Search code examples
c#ms-wordoffice-interopword-automationword-table

Fill existing table in Microsoft Word dynamically via C#


I have created a Word template with a table that I would like to fill dynamically. The number of rows is always dynamic and always different.

How can I fill and extend an existing table? I have already started to implement code. I can create new tables and fill them, but not existing ones.

object oMissing = Missing.Value;

Word._Application word = new Word.Application();
word.Visible = true;

// Template
object oTemplate = "C:\\Temp\\Template.dotx";
Word._Document document = word.Documents.Add(ref oTemplate, ref oMissing, ref oMissing, ref oMissing);

// Insert table and fill with data
Word.Table oTable;

int columnCount = 4;
int rowCount = someVariableCount;

// Table Bookmark
object oBookMark = "Table";

Word.Range wrdRng = document.Bookmarks.get_Item(oBookMark).Range;
oTable = document.Tables.Add(wrdRng, someVariableCount, columnCount, ref oMissing, true);

Solution

  • The most efficient way to create and extend tables in Word is to "dump" the content in delimited text format, then convert it to a table. Doing anything else - such as creating a table, then writing cell-by-cell or appending row-by-row - is comparatively slow. And the longer the table, the slower it gets! This is due to Word's dynamically laying out the pages with each change.

    If you want to start with a header row already in the document, or need to extend an existing table, then insert the delimited content directly below the existing table and convert to a table. In tests, the table columns do not always align exactly using this method. As a work-around, the table can be inserted elsewhere, then moved to the existing table, where it should adapt the correct column widths.

    Sample data with a semi-colon field delimiter and char(13) record delimiter. Note that any character can be used as field delimiter, but ANSI 13 is required as record delimiter:

    Test;One;3;End

    New line;Two;4;End

    Insert and create a new table at a bookmark named Tbl. Assumes doc as Word.Document and missing as object have already been defined and instantiated:

            string tableData = "Test;One;3;End\nNew line;Two;4;End";
            string bkmName = "TableTarget";
            if (doc.Bookmarks.Exists(bkmName))
            {
                Word.Range rngTable = doc.Bookmarks[bkmName].Range;
                rngTable.Text = tableData;
                Word.Table tbl = rngTable.ConvertToTable(";", missing, missing, missing, missing,
                    missing, missing, missing, missing, missing, missing, missing, missing, missing,
                    missing, Word.WdDefaultTableBehavior.wdWord8TableBehavior);
            }
    

    Append to an existing table (the first in the document):

            string tableData = "Test;One;3;End\nNew line;Two;4;End";
            //Target table, to be extended
            Word.Table tbl = doc.Tables[1];
            Word.Range rngTbl = tbl.Range;
            rngTbl.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
            //Target for inserting the data (end of the document)
            Word.Range rng = doc.Content;
            rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
            rng.Text = tableData;
            Word.Table tblExtend = rng.ConvertToTable(";", missing, missing, missing, missing,
                    missing, missing, missing, missing, missing, missing, missing, missing, missing,
                    missing, Word.WdDefaultTableBehavior.wdWord8TableBehavior);
            //Move the new table content to the end of the target table
            tblExtend.Range.Cut();
            rngTbl.PasteAppendTable();