如何在word文档中快速填充有许多条目的表?



我使用Microsoft.Office.Interop.Word,并希望将给定的数据库作为Word文档中的表输出。但是在我第一次尝试之后(下面的例子),我很快注意到遍历每一行的时间随着行数的增加而迅速增加。

using Word = Microsoft.Office.Interop.Word;
private void InsertTableWithRandomValue(Word.Document doc)
{
var par = doc.Paragraphs.Add();
string guid = Guid.NewGuid().ToString();
Word.Table firstTable = doc.Tables.Add(par.Range, 1000, 5);
firstTable.Borders.Enable = 1;
foreach (Word.Row row in firstTable.Rows)
{
foreach (Word.Cell cell in row.Cells)
{
cell.Range.Text = guid;
}
}
}

在一个有200行的表中,写每个条目大约需要100ms。然而,对于2000行,每个条目已经高达400ms,对于我的用例来说,这还不够快。

是否有一种方法来迭代每一行更快?

如果没有,我的下一个方法是暂时将Word文档保存为HTML,编辑文本,然后再次导出为Word文档。

Office Interop真的很慢。您应该考虑使用Open XML来创建文档。

我从你的代码创建了一个例子。首先,将DocumentFormat.OpenXmlNuGet包添加到项目中。

using var document = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document); // or WordprocessingDocument.Open() if you want to open an existing one
// Since we create a new document, we need to add main document part, as well as body etc.
var mainDocumentPart = document.AddMainDocumentPart();
mainDocumentPart.Document = new Document();
var body = mainDocumentPart.Document.AppendChild(new Body());
// Adding borders
var borderType = new EnumValue<BorderValues>(BorderValues.Single);
UInt32Value borderSize = 16;
var table = new Table(new TableProperties(new TableBorders(
new TopBorder
{
Val = borderType,
Size = borderSize
},
new RightBorder
{
Val = borderType,
Size = borderSize
},
new BottomBorder
{
Val = borderType,
Size = borderSize
},
new LeftBorder
{
Val = borderType,
Size = borderSize
},
new InsideVerticalBorder
{
Val = borderType,
Size = borderSize
},
new InsideHorizontalBorder
{
Val = borderType,
Size = borderSize
}
)
));
var guid = Guid.NewGuid().ToString();
const int rowCount = 1000;
const int columnCount = 5;
// Instead of creating a row with same cell every single time, creating a cell and then populating the rows with it would be better
var tableCell = new TableCell();
tableCell.Append(new Paragraph(new Run(new Text(guid))));
var tableRow = new TableRow();
for (var i = 0; i < columnCount; i++)
{
tableRow.Append(new TableCell(tableCell.OuterXml)); // You cannot add same element twice, because you cannot add something that's part of a tree. So we clone it before adding
}
for (var i = 0; i < rowCount; i++)
{
table.Append(new TableRow(tableRow.OuterXml));
}
body.Append(table);

我创建了一个包含要插入到表中的内容的文本,然后将该文本转换为表:

Document document = new Document();
int rows = 1000;
int cols = 5;
//document.Application.Visible = true;
var par = document.Paragraphs.Add();
string guid = Guid.NewGuid().ToString();
var start = DateTime.Now;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sb.Append(guid);
if (j<cols-1) sb.Append('t');
}
sb.AppendLine("");
}
par.Range.Text = sb.ToString();
var r = document.Range(0,par.Range.End);
Table t = r.ConvertToTable(NumRows:rows,NumColumns:cols);
t.Borders.Enable = 1;
document.SaveAs2(@"d:temptest.docx");
document.Application.Quit();
Console.WriteLine($"{(DateTime.Now-start).TotalMilliseconds/1000}");
Console.ReadLine();

这大约需要1.7秒,而你的方法在我的系统上大约需要38秒。

最新更新