What is the fastest way of replacing the text of many content controls via office-js?

怎甘沉沦 提交于 2020-01-23 16:49:26

问题


I wrote the following function to replace a huge amount of CCs with specified values:

/** replaceManyCCs()
 *
 * Replaces the content of many content controls, based on the replacementObject.
 *
 * @arg replacementObject   A dictionary. The keys are the titles of the CCs which should be replaced. The values are the replacement values.
 */
function replaceManyCCs (replacementObject) {
    Word.run(function (context) {
        var time1 = Date.now();

        // load the title of all content controls
        var CCc = context.document.contentControls.load('title');

        return context.sync().then(function () { // synchronous
            // extract CC titles
            var documentCCtitleList = [];
            for(var i = 0; i < CCc.items.length; i++) { documentCCtitleList.push(CCc.items[i].title); }

            // check for missing titles and replace
            var replaceCounter = 0;
            for(var key in replacementObject) {
                var index = documentCCtitleList.indexOf(key);
                if(index == -1) { // title is missing
                    throw 'Could not find CC with title "'+key+'"';
                }
                else { // replace
                    CCc.items[index].insertText(' '+replacementObject[key], 'Replace');
                    replaceCounter++;
                }
            }

            $('#status').html('...replacing...');

            return context.sync().then(function () {
                var time2 = Date.now();
                var tdiff = time2-time1;
                $('#status').html('Replaced '+replaceCounter+' CCs in '+(tdiff/1000)+' seconds');
            });
        });
    }).catch(function (error) {
        $('#status').html('<pre>Error: ' + JSON.stringify(error, null, 4) + '</pre>');
        console.log('Error: ' + JSON.stringify(error, null, 4));
        if (error instanceof OfficeExtension.Error) {
            console.log('Debug info: ' + JSON.stringify(error.debugInfo, null, 4));
        }
    });
}

Replacing 816 CCs requires 50-60 seconds with this code. Are there any better/faster ways of accomplishing this?


回答1:


good follow up question. I would need to know more details about how big the replacementObject array is I am assuming at least the same size as the # of content controls in the document, that definitely has direct impact on the overall perf of your method. As you can see from my previous answer, updating 700 CCs with a fixed value takes no more than 5 seconds, so I think the satellite operations you are doing to find the new values are affecting negatively the performance.

Specifically, I see a couple of things you are doing that impact negatively the perf, and you could potentially fix.

  1. You are traversing at least 2 times the content control collection. One for getting the titles (and push them into a temp array), and another one to replace the content (if the replacement object matched the CCs in the doc). I would really try to do this in a single pass.
  2. On top of the above, In the inner loop where you are finding the titles, you are practically traversing the replacementObject for each CC (this means at least you are traversing this array 700 times) and to make things worse you are using the array.indexOf method to find the index by key (just FYI in the browser we use for Add-ins, latest IE, this is the most expensive way of traversing an array, in fact is 90% slower than if you do a for loop trying to find the indesx given the key, this simple change theoretically will be 90% faster in latest IE, if you want to keep this logic). Check out this page demonstrating this (use latest IE browser for test).

I think you should tag (or title) each content control with the index that directly maps it to the relacementObject array position (title=index in the replacement object and just directly use the index of the replacementObject array to change the values in a single pass. If there is a way of doing that you will get the fastest outcome!



来源:https://stackoverflow.com/questions/45321706/what-is-the-fastest-way-of-replacing-the-text-of-many-content-controls-via-offic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!