Add items to a Word document using C#

I thought I had found the promised land. Then I tried adding more than one item to a blank Word document using C# and I realised it had been a mirage all along. I simply wanted to create a blank document, add a line of text, followed by another, followed by my table. I was flummoxed by the Word.Range object – and I’ll go into detail in a bit – but here’s the solution:

object oEndOfDoc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */
 
Word.Application app = new Word.Application();
 
Word.Document doc = app.Documents.Add(
    ref oMissing, ref oMissing, ref oMissing, ref oMissing
);
 
Word.Range line1 = doc.Bookmarks.Item(ref oEndOfDoc).Range;
line1.Text = "First line!";
line1.InsertParagraphAfter();
 
Word.Range line2 = doc.Bookmarks.Item(ref oEndOfDoc).Range;
line2.Text = "Second line!";
line2.InsertParagraphAfter();
 
Word.Range r = doc.Bookmarks.Item(ref oEndOfDoc).Range;
r.Text = "Name\tAge\tLocation\nNigel\t44\tUK\nBill\t33\tUSA\nRuben\t86\tNicaragua\n";
 
object tab = Word.WdTableFieldSeparator.wdSeparateByTabs;
Word.Table t  = r.ConvertToTable(
    ref tab,
    ref oMissing, ref oMissing, ref oMissing, ref oMissing,
    ref oMissing, ref oMissing, ref oMissing, ref oMissing,
    ref oMissing, ref oMissing, ref oMissing, ref oMissing,
    ref oMissing, ref oMissing, ref oMissing
);

Looks pretty obvious, doesn’t it? But it took me a while to get there. The important difference is that instead of…

Word.Range r = doc.Range(ref oMissing, ref oMissing);

…I used:

Word.Range r = doc.Bookmarks.Item(ref oEndOfDoc).Range;

What I had been experiencing with the former was a document with only the final item (the table) being added. In fact, all items had been added, but at the same location in the document – so each item was being overwritten by each subsequent item. This seems obvious too, in retrospect, because I was supplying the missing value to the Range constructor’s start and end parameters, so the target range became “everything”.

I couldn’t see – and still can’t – how you’re supposed to identify a range in an empty document, but I was fortunate enough to discover endofdoc, a built-in bookmark signifying the, er, end of a document.

object oEndOfDoc = "\\endofdoc"; /* \endofdoc is a predefined bookmark */

My requirement was simply to add items to the document sequentially, so using this bookmark for the range of each item did the trick. I think that’s me done with Word Automation…

 

 

P.S. In trying to find a solution I toyed with a Word document template with predefined mail merge fields acting as placeholders for the items I wanted to add. It almost worked until I tried to replace a field with my table. Any ideas why this doesn’t work?

foreach (Word.Field myMergeField in doc.Fields)
{
    // ...
    myMergeField.Select();
    app.Selection.Range.Text = "Name\tAge\tLocation\nNigel\t44\tUK\nBill\t33\tUSA\nRuben\t86\tNicaragua\n";
    app.Selection.Range.ConvertToTable(
        ref tab,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing
    );
}

2 thoughts on “Add items to a Word document using C#

  1. Wow!, that’s amazing!! thanks for the hint, I really spend to much hours finding this piece of code, the only missing thing is how to fill the table from a database table?, I think I can figure out using your code. Thanks

  2. Glad you found it useful! I guess you’ve got two options regarding the database table. One is to retrieve your data and then iterate around it, building tabbed strings to pass to ConvertToTable(). The other is to make the mail merging work. Good luck!

Leave a Reply