Office.js Word Add-In: Performance Issue with Upda

2019-02-20 15:21发布

Summary:

  • Updating values in large Word tables (larger than 10 by 10) is very slow. Performance gets exponentially worse with table size.
  • I'm using myTable.values = arrNewValues. I've also tried myTable.addRows("end", rows, arrNewValues). Where arrNewValues is a 2D array.
  • I've also tried using updating via getOoxml() and insertOoxml(), but ran into other issues I haven't been able to resolve, but has good performance.
  • Slow performance seems to be caused by "ScreenUpdating" (same issue exists in VBA and is solved via ScreenUpdating=false). I believe it is critically important to add the ability to temporarily turn off ScreenUpdating.
  • Is there another way to improve table updating performance?

Background:

My add-in (https://analysisplace.com/Solutions/Document-Automation) performs document automation (updates content in a variety of Word docs). Many customers want to be able to update text in largish tables. Some documents have dozens of tables (appendices). I have run into the issue where updating these documents is unacceptably slow (well over a minute) due to the table updates.

Update time by table size:

  • 2 rows by 10 columns: .33 seconds
  • 4 rows by 10 columns: .52 seconds
  • 8 rows by 10 columns: 1.5 seconds
  • 16 rows by 10 columns: 5.5 seconds
  • 32 rows by 10 columns: 20.8 seconds
  • 64 rows by 10 columns: 88 seconds

Sample Office.js Code (Script Lab):

function updateTableCells() {
    Word.run(function (context) {   
        var arrValues = context.document.body.tables.getFirst().load("values");
        return context.sync().then(
            function () {
                var rows = arrValues.values.length;
                var cols = arrValues.values[0].length;
                console.log(getTimeElapsed() + "rows " + rows + "cols " + cols);
                var arrNewValues = [];
                for (var row = 0; row < rows; row++) {
                    arrNewValues[row] = [];
                    for (var col = 0; col < cols; col++) {
                        arrNewValues[row][col] = 'r' + row + ':c' + col;
                    }
                }
                console.log(getTimeElapsed() + 'Before setValues ') ;
                context.document.body.tables.getFirst().values = arrNewValues;
                return context.sync().then(
                    function () {
                        console.log(getTimeElapsed() + "Done");
                });
            });
    })
        .catch(OfficeHelpers.Utilities.log);
}

Sample Word VBA Code:

VBA performance is similar to the Office.js performance without ScreenUpdating = False. With ScreenUpdating = False, performance is instant.

Sub PopulateTable()
   Application.ScreenUpdating = False
    Dim nrRow As Long, nrCol As Long
    Dim tbl As Word.Table
    Set tbl = ThisDocument.Tables(1)
    For nrRow = 1 To 32
        For nrCol = 1 To 10
            tbl.Cell(nrRow, nrCol).Range.Text = "c" & nrRow & ":" & nrCol
        Next nrCol
    Next nrRow
End Sub

Article explaining slow performance: see "Improving Performance When Automating Tables": https://msdn.microsoft.com/en-us/library/aa537149(v=office.11).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-3

Posts indicating there is no "ScreenUpdating = False" in Office.js: ScreenUpdating Office-js taskpane and Equivalent to Application.ScreenUpdating Property in office-js Excel add-in Sounds like we won't see it any time soon.

Post related to the updating tables via getOoxml() and insertOoxml(): Word Office.js: issues with updating tables in ContentControls using getOoxml() and insertOoxml()

1条回答
We Are One
2楼-- · 2019-02-20 16:00

This is probably not the answer you're looking for, but I have been working with a word add in for validation of software, and we are talking about updating 500-1000 rows with lots of little formatting changes.

Anyway one thing I found that helped is to scroll somewhere else in the document before you make the changes to the table. Just the act of looking at it will slow it down 10-20x. It's not always instant but near.

查看更多
登录 后发表回答