Doicare
Doicare

Reputation: 361

Filling table takes a lot of time in MS Word

I made the following code to add external data table to another table in MS word document, its working fine but takes a lot of time in case that the number of rows is more than 100, and in case of adding table with rows count more that 500 it fills the ms word table really slow and can't complete the task.

I tried to hide the document and disable the screen update for the document but still no solution for the slow performance.

//Get the required external data to the DT data table            
DataTable DT = XDt.GetData();
Word.Table TB;
int X = 1;
foreach (DataRow Rw in DT.Rows)
{
    Word.Row Rn = TB.Rows.Add(TB.Rows[X + 1]);

    for(int i=0;i<=DT.Columns.Count-1;i++)
        {
           Rn.Cells[i+1].Range.Text = Rw[i].ToString()); 
        }
    X++;
}

So is there a way to make this process go faster ?

Upvotes: 2

Views: 1866

Answers (3)

jlo-gmail
jlo-gmail

Reputation: 5048

ConvertToTable method is orders of magnitude faster than adding Rows/Cells one at a time.

while (reader.Read())
{
   values = new object[reader.FieldCount];
   var cols = reader.GetValues(values);
   var item = String.Join("\t", values);
   items.Add(item);
};
data = String.Join("\n", items.ToArray());

var tempDocument = application.Documents.Add();
var range = tempDocument.Range();
range.Text = data;
var tempTable = range.ConvertToTable(Separator: Microsoft.Office.Interop.Word.WdTableFieldSeparator.wdSeparateByTabs,
                                    NumColumns: reader.FieldCount,
                                    NumRows: rows, DefaultTableBehavior: WdDefaultTableBehavior.wdWord9TableBehavior,
                                    AutoFitBehavior: WdAutoFitBehavior.wdAutoFitWindow);

Upvotes: 0

Cindy Meister
Cindy Meister

Reputation: 25673

The most efficient way to add a table to Word is to first concatenate the data in a delimited text string, where "/n" must be the symbol for end-of-row (record separator). The end-of-cell (field separator) can be any character you like that's not in the string content that makes up the table.

Assign this string to a Range object, then use the ConvertToTable() method to create the table.

Upvotes: 1

DanL
DanL

Reputation: 999

You're retrieving the last row of the current table for the BeforeRow parameter of TB.Rows.Add. This is significantly slower than simply adding the row. You should replace this:

Word.Row Rn = TB.Rows.Add(TB.Rows[X + 1]);

With this:

Word.Row Rn = TB.Rows.Add();

Utilizing parallelization as suggested in the comments might help slightly, but I'm afraid it's not going to do much good seeing the table add code runs on the main thread as mentioned in this link.

EDIT:

If performance is still an issue, I'd look into creating the Word table independently of the Word object model by using OpenXML. It's orders of magnitude faster.

Upvotes: 0

Related Questions