【问题标题】:Word Office.js: issues with updating tables in ContentControls using getOoxml() and insertOoxml()Word Office.js:使用 getOoxml() 和 insertOoxml() 更新 ContentControls 中的表的问题
【发布时间】:2017-05-23 16:12:35
【问题描述】:

我正在尝试更新 Word 表格单元格中的文本(位于内容控件 [CC] 中)。我已经使用表格对象成功地做到了这一点;但是对于拥有大量表格的大型文档的客户来说,它太慢了。所以,我希望能够使用 getOoxml 和 insertOoxml 来更新表格单元格的值(希望更快,尽管我看到它在 Word Online 中可能非常慢)。 所以我会使用 getOoxml 在 CC 中获取表 Ooxml,然后以编程方式修改 xml,然后将 Ooxml 插入到 CC 中。

我能够成功获取 Ooxml,并使用 C# OpenXMLPowerTools 以编程方式成功修改表 Ooxml。但是,我无法成功将 Ooxml 重新插入 CC。

如果 CC 是围绕选定的表添加的,那么当代码运行时,它总是会失败并显示“InvalidArgument”。请注意,这样做时,CC 中的表格上方或下方没有换行符(CC 适合表格)。这就是我客户的大多数桌子的样子。

如果表格是在 CC 中添加的(导致表格上方/下方出现不需要的换行符),则代码会运行,但会导致添加额外的 CC 和换行符。因此,每次代码运行时,CC 计数都会增加 1。CC 似乎是相互嵌套的。额外的 CC 是不可接受的,因为它们会弄乱后续代码。它还会在每次运行代码时添加一个额外的换行符。

我已经尝试过 contentControls.items[0].clear()。 - 这会删除文本,但不会删除表格或 CC,因此没有帮助。

这是 Script Lab 中的简化代码:

$("#getooxml").click(getooxml);
function getooxml() {
Word.run(function (context) {
    var contentControls = context.document.contentControls;
    context.load(contentControls);
    return context.sync().then(function () {
        var ooxml = contentControls.items[0].getOoxml(); //contains a table
        return context.sync().then(function () {
            contentControls.items[0].insertOoxml(ooxml.value, Word.InsertLocation.replace);
            return context.sync().then(function () {
                console.log('inserted OOXM.  CC count:' + contentControls.items.length);
            });
        });
    });
})
    .catch(function (error) {
        console.log('Error: ' + JSON.stringify(error));
        if (error instanceof OfficeExtension.Error) {
            console.log('Debug info: ' + JSON.stringify(error.debugInfo));
        }
    });
}

是否有任何可能的方法让它发挥作用? 例如,有没有办法可以修改 Ooxml 以使其工作?我怀疑它添加 CC 的原因是因为 getOoxml() 包含父 CC 本身,并且当插入父 CC 中时,它会添加 CC(以及任何嵌套的 CC)。如果是这样,如何从 Ooxml 中删除父 CC?

我有版本 1704(内部版本 8067.2115)

这里有一个帖子表明添加的段落问题将在下个月修复:`context.document.body.insertOoxml` breaks documents, crashes word 它还表明“替换”选项实际上没有替换的错误(但我不认为是这种情况)

【问题讨论】:

    标签: ms-word office-js


    【解决方案1】:

    带有表格内容控件的替换选项(cc 仅包装表格)可能在此处存在错误,感谢您报告此问题。将调查并报告。

    也就是说,我强烈建议您为此使用 Table OM,OOXML 确实应该用于与尚未在 API 中公开的对象进行交互。正如您所提到的,在 Word Online 中,OOXML 的问题虽然功能强大,但确实很慢。我真的怀疑你会比使用 Table OM 获得更好的性能。

    看到性能下降的文档以及用于更改表格单元格的代码会很棒,这应该很快。 谢谢!

    【讨论】:

    • 也许比包装更重要的是每次运行代码时添加嵌套的 CC。关于我的简单性能测试(insertOoxml 快得多),请参阅我的 cmets。
    • 如果我可以让 insertOoxml 工作,并且在 PC/Mac 上确实更快,但在 Word Online 上速度较慢,我可以让用户对 Word Online 使用 Table OM 方法,否则使用 insertOoxml 方法。跨度>
    • 我将通过电子邮件向您发送有关示例文档和代码的更多信息(我有您的电子邮件)。
    • 我还没有找到使用 Table OM 的高效方法,并计划为更大的表采用 Ooxml 方法。您能否提供一个 JavaScript sn-p 来减少从 getOoxml 获得的不需要的内容,正如您在“编辑 Office Open XML 以在您的任务窗格加载项中使用”下的 dev.office.com/docs/add-ins/word/… 中所建议的那样。就我而言,我只需要在 CC 中编辑表格。
    【解决方案2】:

    这是设计使然,因为对于表格上的内容控件,内容控件的开始标记在第一个单元格内,结束标记在最后一个单元格内。因此,从开始标签到结束标签的范围并不是整个表格。

    当您将 Ooxml 的获取和设置函数与文本获取/设置函数进行比较时,它们也更慢。因此,我建议你这样做:

    因为你可能有很多表,你可以在你正在处理的表上添加一个内容控件,并给这个内容控件一个标签。此内容控件可以位于整个表格中,也可以仅位于单元格中。

    然后就可以使用内容控件直接抓取表格了。之后,您可以操作表格的文本。

    代码可能是这样的:

    Word.run(function (context) {
        var contentControl = context.document.contentControls.getByTag("forMyTable").getFirst();
        var table = contentControl.tables.getFirst();
        context.load(table);
        return context.sync().then(function () {
            var values = table.values;
            // add some text to the second cell in the second row.
            table.getCell(1, 1).value = values[1][1] + " extra";
            return context.sync().then(function () {
                console.log("inserted values.");
            });
        });
    }).catch(function (error) {
        console.log('Error: ' + JSON.stringify(error));
        if (error instanceof OfficeExtension.Error) {
            console.log('Debug info: ' + JSON.stringify(error.debugInfo));
        }
    });
    

    【讨论】:

    • 很好地解释了为什么当 CC 直接在桌子周围(CC 部分在桌子上)时我得到“InvalidArgument”错误。但我希望有一个解决方法,因为这是我们文档中大多数表格的方式。
    • 我在一个 21 行 x 10 列的表格 (Windows) 上进行了比较测试,更改了所有单元格值:使用 Table OM,需要 15.2 秒(CPU 利用率高和一些令人分心的屏幕闪烁);使用getOoxml/insertOoxml方法,一共需要0.8秒。这包括通过 Ooxml 的 152,000 个字符进行 0.2 秒的查找/替换。因此,至少在这 1 次测试中,insertOoxml 的速度大大提高了 30 倍(尽管实际上会有一次服务器往返来使用 OpenXMLPowerTools 修改 Ooxml - 整个文档需要 1 次)。
    • 您在上面提供的 Table OM 代码是我的加载项当前的工作方式。虽然我用二维数组更新了整个表:table.value = 2dArray。它位于 Office 商店中,称为“Excel 到 Word 文档自动化”。它包括可供尝试的示例文档。
    【解决方案3】:

    InsertOoxml 可能更快,但在 Word Online 中速度较慢。

    由于您已经有一个表格,并且您的方案是为每个单元格添加值,我建议您使用 table.addRows 方法。那就是:

    1. 使用 table.deleteRows(1, rowCount) 删除除第一行以外的所有行。
    2. 使用 table.addRows("end", rowCount, values) 添加回这些行,其中 values 是一个二维字符串数组。

    试试看它是否比逐个单元格操作更快。谢谢!

    【讨论】:

    • 这是一个很好的建议,我很想看看它带来的性能提升......
    • 如果表格中没有内容,则同"myTable.values = arrNewValues"。如果有内容,速度会快 2 倍。因此,由于 screenUpdating,对于大型表来说仍然太慢。见stackoverflow.com/questions/44910445/…。此外,就我而言,这不是一个好的解决方案,因为它会删除应用于表格的任何格式(合并单元格、边框、粗体等)。我需要一个只替换表格单元格值/文本的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2022-08-02
    • 2016-11-04
    • 1970-01-01
    • 2021-01-02
    • 2022-08-04
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多