如何在word文档中快速填入一个table?

How to quickly fill a table in a word document with many entries?

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

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 行的 table 中,写入每个条目大约需要 100 毫秒。但是,对于 2000 行,每个条目已经高达 400 毫秒,这对于我的用例来说还不够快。

有没有办法更快地遍历每一行?

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

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

我已经根据您的代码创建了一个示例。首先,将 DocumentFormat.OpenXml NuGet 包添加到您的项目中。

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);

我创建了一个包含您要插入 table 的内容的文本,然后将此文本转换为 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:\temp\test.docx");
document.Application.Quit();
Console.WriteLine($"{(DateTime.Now-start).TotalMilliseconds/1000}");
Console.ReadLine();

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