0

我正在尝试使用 Word 加载项 Javascript API 来打印文档中所有表格的上边框的颜色和宽度。

我正在使用以下代码:

    Word.run(function (context) {
        var range = context.document.getSelection();
        var tables = context.document.body.tables;
        context.load(range);
        context.load(tables);
        return context.sync().then(function () {
            for (var i = 0; i < tables.items.length; i++) {
                var topBorder = tables.items[i].getBorder("Top");
                context.load(topBorder, ['color', 'width']);
                var color = "1", width = "1";
                context.sync().then(function () {
                    color = topBorder.color.toString();
                    width = topBorder.width.toString();
                });
                range.insertText(color, "End");
                range.insertText(width, "End");
            }
            return context.sync();
        });
    });

但是当我运行它时,它会打印 11 而不是打印正确的值。

我曾尝试在线搜索一些示例代码,但只能找到设置值的代码。我错过了什么?

谢谢!

4

1 回答 1

1

您的代码中存在一些问题:

  1. 次要:您不需要加载范围对象,因为您正在写入而不是读取它。
  2. 你有一个context.sync内部循环。这很少是一个好主意。它会损害性能并使您的代码难以推理。通常的解决方法是循环两次,context.sync循环之间有一个。第一个循环填充一个数组(将在第二个循环中循环)并加载将在第二个循环中读取的每个 Office 对象属性。请参阅下面的代码。
  3. 你有一个context.sync().then(),里面有另一个context.sync().then()。如果你把 aconsole.log("outer then")作为 outer 的最后一行thenconsole.log("inner then")inner 的第一行then,你会看到你的 outerthen在 inner 之前完成then。这就是你得到“11”的原因。写入文档的行在这些变量从其初始值更改之前运行。
  4. 我在Script Lab工具中运行您的代码时发现,该行color = topBorder.color.toString();抛出了一个错误,指出该color属性未加载。这可能是分支 Promise 链的另一个副作用。

以下代码有效,更简单,性能更高,因为无论文档中有多少表,它都只同步 3 次。

Word.run(function (context) {
    var range = context.document.getSelection();
    var tables = context.document.body.tables.load("items");
    var topBorders = [];
    return context.sync()
      .then(function () {
        for (var i = 0; i < tables.items.length; i++) {
          topBorders.push(tables.items[i].getBorder("Top").load(['color', 'width']));
        }
      })
      .then(context.sync)
      .then(function () {
        for (var i = 0; i < topBorders.length; i++) {
          range.insertText(topBorders[i].color.toString(), "End");
          range.insertText(topBorders[i].width.toString(), "End");
        }
      })
      .then(context.sync)
});
于 2019-12-08T01:07:03.467 回答