I am trying to modify a word document and inserting data at some specific positions( I have a template document which I must get it ready and fill all the blank spaces ).I am using Microsoft.Office.Interop.Word library and till now I just figure out how to insert text at the end of the document, I will write down the code too so maybe someone can help me out.Thanks!
private void button1_Click(object sender, EventArgs e)
string str = null;
OpenFileDialog dia = new OpenFileDialog();
if (dia.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
str = dia.FileName;
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document doc1 = app.Documents.Open(str);
object missing = System.Reflection.Missing.Value;
doc1.Content.Text += "Merge?";
app.Visible = true;
doc1.Save();
this.Close();
}
}
For sake of simplicity, first add the bookmark in MS Word as follow:
Select the region where you want to add the text, Then go to Insert > Bookmark in Word.
Then give the name to the bookmark as follow:
Then use the follow modified version of Ben:
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Document doc = app.Documents.Open(Path.Combine(Environment.CurrentDirectory, "Report.doc"));
Dictionary<string, string> bookmarks = new Dictionary<string, string> { { "DateOfIssue", "23-06-2018"}, { "TotalNumOfPages", "20" } };
foreach (var bookmark in bookmarks)
{
Bookmark bm = doc.Bookmarks[bookmark.Key];
Range range = bm.Range;
range.Text = bookmark.Value;
doc.Bookmarks.Add(bookmark.Key, range);
}
Finally the output is as follow:
You can use the Range object to insert text at a specific position. msdn
doc1.Range(0, 0).Text = "Hello World";
If you have a template and the position to insert the text is always at the same location, you could also use Bookmark. msdn
[Update]
Here is a complete example to add text to a word document by a bookmark:
Application app = new Microsoft.Office.Interop.Word.Application();
Document doc = app.Documents.Open(#"your file");
string bookmark = "BookmarkName";
Bookmark bm = doc.Bookmarks[bookmark];
Range range = bm.Range;
range.Text = "Hello World";
doc.Bookmarks.Add(bookmark, range);
With this solution, the bookmark will not be deleted and you can add/modify it later again with the same piece of code.
You can use the following to insert a string into another string in a specific position.
doc1.Content.Text = doc1.Content.Text.Insert(10, "Merge?");
Source: https://msdn.microsoft.com/en-us/library/system.string.insert(v=vs.110).aspx
Related
I managed to insert a text in a Bookmark of a Word document using Microsoft.Office.Interop.Word.
using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;
using Range = Microsoft.Office.Interop.Word.Range;
Application app = new Microsoft.Office.Interop.Word.Application();
Document doc = app.Documents.Open(#"C:\wordDocument.docx");
string bookmark = "bookmarkName";
Bookmark bm = doc.Bookmarks[bookmark];
Range range = bm.Range;
range.Text = "Hello World";
doc.Bookmarks.Add(bookmark, range);
/* OR
doc.Bookmarks[bookmark].Select();
app.Selection.TypeText("Hello");
*/
The problem is this also opened the Word document. Can this be done without opening the document itself? Like its all happening in the background?
Try using the Save and Close function after updating the text of the Bookmark of your Word Document.
Add the below code after the doc.Bookmarks.Add(bookmark, range);.
doc.Save();
doc.Close();
EDIT:
If the computer is slow, the Word document might show within a second since you open it up. As hardcoregamer said, you can try to hide the object of Word.Application first before opening it.
using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;
using Range = Microsoft.Office.Interop.Word.Range;
Application app = new Microsoft.Office.Interop.Word.Application();
app.Visible = false; //Hide the Word.Application object.
Document doc = app.Documents.Open(#"C:\wordDocument.docx");
string bookmark = "bookmarkName";
Bookmark bm = doc.Bookmarks[bookmark];
Range range = bm.Range;
range.Text = "Hello World";
doc.Bookmarks.Add(bookmark, range);
doc.Save(); //save the document.
doc.Close(); //close the document.
app.Quit(); //close the Word.Application object. otherwise, you'll get a ReadOnly error later.
I have a MS word file which has some sentences and I need to insert some images in between the lines. When I am using the AddPicture method in Microsoft.Office.Interop.Word I am able to insert the image but not at a particular position.
I did not find any method to insert other than AddPicture to insert an image into existing word file. I am trying to insert an image after a particular line after apple there should an image of apple.
Here I am creating a paragraph and trying to add the image. This is my initial file:
This contains paragraphs containing the words apple, mango, and grape.
This is the output of my code (below)
The image should be inserted after the apple line
Required output:
Required Output
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using Word =Microsoft.Office.Interop.Word;
using System.IO;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Word.Application ap = new Word.Application();
Word.Document document = ap.Documents.Open(#"C:\Users\ermcnnj\Desktop\Doc1.docx");
//document.InlineShapes.AddPicture(#"C:\Users\ermcnnj\Desktop\apple.png");
String read = string.Empty;
List<string> data = new List<string>();
for (int i = 0; i < document.Paragraphs.Count; i++)
{
string temp = document.Paragraphs[i + 1].Range.Text.Trim();
if (temp != string.Empty && temp.Contains("Apple"))
{
var pPicture = document.Paragraphs.Add();
pPicture.Format.SpaceAfter = 10f;
document.InlineShapes.AddPicture(#"C:\Users\ermcnnj\Desktop\apple.png", Range: pPicture.Range);
}
}
}
}
}
The above is the code I am using.
The following code snippet illustrates how this can be done. Note that. for the sake of clarity, it's simplified to set only the text to be found - there are a lot of additional properties that might need to be specified; read up on the Find functionality in Word's Language Reference.
If a search term is found, the Range associated with Find changes to the found term and further action can be taken. In this case, a new (empty) paragraph is inserted after the found term. (The question specifies that the term is the entire content of a paragraph, so that's what this example assumes!) The Range is then moved to this new paragraph and the InlineShape inserted.
Note how the graphic is assigned to an InlineShape object. If anything needs to be done to this object, work with the object variable ils.
Word.Application ap = new Word.Application();
Word.Document document = ap.Documents.Open(#"C:\Users\ermcnnj\Desktop\Doc1.docx");
Word.Range rng = document.Content;
Word.Find wdFind = rng.Find;
wdFind.Text = "apple";
bool found = wdFind.Execute();
if (found)
{
rng.InsertAfter("\n");
rng.MoveStart(Word.WdUnits.wdParagraph, 1);
Word.InlineShape ils = rng.InlineShapes.AddPicture(#"C:\Test\avatar.jpg", false, true, rng);
}
I'm new to VSTO and OpenXML and I would like to develop a Word add-in. This add-in should use OpenXML, The add in should add a MergeField to the document, I can actually add MergeField using ConsoleApp but I want to insert the MergeField from the Word add in to the current opened document.
So I have this code in ButtonClick
// take current file location
var fileFullName = Globals.ThisAddIn.Application.ActiveDocument.FullName;
Globals.ThisAddIn.Application.ActiveDocument.Close(WdSaveOptions.wdSaveChanges, WdOriginalFormat.wdOriginalDocumentFormat, true);
// function to insert new field here
OpenAndAddTextToWordDocument(fileFullName, "username");
Globals.ThisAddIn.Application.Documents.Open(fileFullName);
And I Created the function which should add the new MergeField:
public static DocumentFormat.OpenXml.Wordprocessing.Paragraph OpenAndAddTextToWordDocument(string filepath, string txt)
{
// Open a WordprocessingDocument for editing using the filepath.
WordprocessingDocument wordprocessingDocument =
WordprocessingDocument.Open(filepath, true);
// Assign a reference to the existing document body.
Body body = wordprocessingDocument.MainDocumentPart.Document.Body;
// add text
string instructionText = String.Format(" MERGEFIELD {0} \\* MERGEFORMAT", txt);
SimpleField simpleField1 = new SimpleField() { Instruction = instructionText };
Run run1 = new Run();
RunProperties runProperties1 = new RunProperties();
NoProof noProof1 = new NoProof();
runProperties1.Append(noProof1);
Text text1 = new Text();
text1.Text = String.Format("«{0}»", txt);
run1.Append(runProperties1);
run1.Append(text1);
simpleField1.Append(run1);
DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
paragraph.Append(new OpenXmlElement[] { simpleField1 });
return paragraph;
// Close the handle explicitly.
wordprocessingDocument.Close();
But something is not working here, when I use the add in it doesn't do anything
Thanks for the help.
Add a try/catch and you'll probably find that it can't open the file because it's currently open for editing.
The OpenXML SDK is a library for writing to Office files without going through Office's interfaces. But you're trying to do so while also using Office's interfaces, so you're essentially trying to take two approaches at once. This isn't going to work unless you first close the document.
But what you probably want to do is use VSTO. In VSTO, each document has a Fields collection, that you can use to add fields.
Fields.Add(Range, Type, Text, PreserveFormatting)
i'm new to ASP.NET MVC and tried to generate an export from Formdata to word file. That worked quite well, all the Bookmarks in the Document are filled correctly with following code:
string savePath = (#"U:\Coding ASP.MVC\WebForm Export into WordFile\Gutachten.docx");
string templatePath = (#"U:\Coding ASP.MVC\WebForm Export into WordFile\wordTemplate.docx");
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
doc = app.Documents.Open(templatePath);
doc.Activate();
if (doc.Bookmarks.Exists("FileNoSIS"))
{
doc.Bookmarks["FileNoSIS"].Range.Text = FileNoSIS;
}
if (doc.Bookmarks.Exists("NameOfAction"))
{
doc.Bookmarks["NameOfAction"].Range.Text = NameOfAction;
}
doc.SaveAs2(savePath);
app.Application.Quit();
Response.Write("Success");
But now i want to get the thing done with a stream to edit the document and offer the new filled document as a download. Can anybody here give me some advice or any tip how to get there?
Thx
I'm looking to replace a bookmark in a word document with the entire contents of another word document. I was hoping to do something along the lines of the following, but appending the xml does not seem to be enough as it does not include pictures.
using Word = Microsoft.Office.Interop.Word;
...
Word.Application wordApp = new Word.Application();
Word.Document doc = wordApp.Documents.Add(filename);
var bookmark = doc.Bookmarks.OfType<Bookmark>().First();
var doc2 = wordApp.Documents.Add(filename2);
bookmark.Range.InsertXML(doc2.Contents.XML);
The second document contains a few images and a few tables of text.
Update: Progress made by using XML, but still doesn't satisfy adding pictures as well.
You've jumped in deep.
If you're using the object model (bookmark.Range) and trying to insert a picture you can use the clipboard or bookmark.Range.InlineShapes.AddPicture(...). If you're trying to insert a whole document you can copy/paste the second document:
Object objUnit = Word.WdUnits.wdStory;
wordApp.Selection.EndKey(ref objUnit, ref oMissing);
wordApp.ActiveWindow.Selection.PasteAndFormat(Word.WdRecoveryType.wdPasteDefault);
If you're using XML there may be other problems, such as formatting, images, headers/footers not coming in correctly.
Depending on the task it may be better to use DocumentBuilder and OpenXML SDK. If you're writing a Word addin you can use the object API, it will likely perform the same, if you're processing documents without Word go with OpenXML SDK and DocumentBuilder. The issue with DocumentBuilder is if it doesn't work there aren't many work-arounds to try. It's open source not the cleanest piece of code if you try troubleshooting it.
You can do this with openxml SDK and Document builder. To outline here is what you will need
1> Inject insert key in main doc
public WmlDocument GetProcessedTemplate(string templatePath, string insertKey)
{
WmlDocument templateDoc = new WmlDocument(templatePath);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(templateDoc.DocumentByteArray, 0, templateDoc.DocumentByteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open([source], true))
{
XDocument xDoc = doc.MainDocumentPart.GetXDocument();
XElement bookMarkPara = [get bookmarkPara to replace];
bookMarkPara.ReplaceWith(new XElement(PtOpenXml.Insert, new XAttribute("Id", insertKey)));
doc.MainDocumentPart.PutXDocument();
}
templateDoc.DocumentByteArray = mem.ToArray();
}
return templateDoc;
}
2> Use document builder to merge
List<Source> documentSources = new List<Source>();
var insertKey = "INSERT_HERE_1";
var processedTemplate = GetProcessedTemplate([docPath], insertKey);
documentSources.Add(new Source(processedTemplate, true));
documentSources.Add(new Source(new WmlDocument([docToInsertFilePath]), insertKey));
DocumentBuilder.BuildDocument(documentSources, [outputFilePath]);