Word Office.js:使用getOoxml()和insertOoxml()

时间:2017-05-23 16:12:36

标签: ms-word office-js

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

我能够成功获得Ooxml,并使用C#OpenXMLPowerTools以编程方式成功修改表Ooxml。但是,我无法成功地将Ooxml插回到CC中。

如果在选定的表周围添加了CC,那么当代码运行时,它始终会失败,并带有" InvalidArgument"。请注意,当以这种方式完成时,CC中的表上方或下方没有换行符(CC适合表格)。这就是我的大多数客户的表格。

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

我尝试过contentControls.items [0] .clear()。 - 这会删除文本,但不会删除表格或CC,因此无效。

以下是脚本实验室中的简化代码:

$("#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(Build 8067.2115)

这里有一条帖子表示下个月会修复添加的段落问题:`context.document.body.insertOoxml` breaks documents, crashes word 它还表明在"替换"选项实际上没有替代(但我认为不是这样)

3 个答案:

答案 0 :(得分:1)

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

也就是说,我强烈建议您使用表格OM,OOXML应该用于与尚未在API中公开的对象进行交互。正如您在Word Online中提到的那样,强大的OOXML问题非常缓慢。我真的怀疑你会比使用Table OM获得更好的性能。

看到你看到性能下降的文件以及用来更改表格单元格的代码真是太棒了,这应该非常快。 谢谢!

答案 1 :(得分:1)

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

当你将它们与文本获取/设置功能进行比较时,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));
    }
});

答案 2 :(得分:0)

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

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

  1. 使用table.deleteRows(1,rowCount)删除第一行以外的所有行。
  2. 使用table.addRows(“end”,rowCount,values)添加这些行,其中values是一个二维字符串数组。
  3. 尝试一下,看看它是否比逐个细胞操作更快。谢谢!