document.contentControls 未返回文档中的所有 ContentControl
document.contentControls not returning all ContentControls in the document
我有一个包含三个 ContentControl
对象的文档,如下所示:
这里是完整的 .docx file - 但基本上文档正文的标记如下所示:
<w:body>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D">
<w:r>
<w:t xml:space="preserve">Video provides a powerful way to help you </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc1"/>
<w:tag w:val="prove"/>
<w:id w:val="806369342"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF9900"/>
<w15:appearance w15:val="tags"/>
<w:text/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>prove</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t xml:space="preserve"> your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc2"/>
<w:tag w:val="number 2"/>
<w:id w:val="1463999480"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF0000"/>
<w15:appearance w15:val="tags"/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>type</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t xml:space="preserve"> a keyword to search online for the video that best fits your document.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D">
<w:r>
<w:t xml:space="preserve">To make your document look professionally produced, Word provides </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc3"/>
<w:tag w:val="xxx"/>
<w:id w:val="1703202634"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF99CC"/>
<w15:appearance w15:val="tags"/>
<w:text/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>header</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t>, footer, cover page, and text box designs that complement each other. For example, you can add a matching cover page, header, and sidebar. Click Insert and then choose the elements you want from the different galleries.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D"/>
<w:p w:rsidR="00000000" w:rsidRDefault="0075044D"/>
<w:sectPr w:rsidR="00000000">
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
</w:body>
当我运行下面的代码时,只有中间的控件被document.contentControls
返回,因此被我的代码更改了。为什么不返回其他两个控件的任何想法?还有其他人遇到过这个问题吗?有办法解决吗?
Word.run(function (context) {
var myContentControls = context.document.contentControls;
myContentControls.load("tag");
return context.sync()
.then(function () {
for (var i = 0; i < myContentControls.items.length; i++)
{
myContentControls.items[i].color = "blue";
myContentControls.items[i].title = "myCC";
myContentControls.items[i].appearance = "tags";
}
return context.sync();
});
}).catch(OfficeHelpers.Utilities.log);
为了方便起见,这里有一个ScriptLab gist。
有趣的是,这个 VBA 代码 returns 正确的结果 (3
):
Sub Main()
MsgBox ActiveDocument.ContentControls.Count
End Sub
我只在 Windows 10 / Office 365 桌面客户端上尝试过。
如 Word JS API 的内容控件文档中所述,仅支持/识别富文本内容控件。所以代码不会"see"纯文本内容控件。
内容控件是纯文本还是富文本在视觉上无法识别(除非它包含格式或文本以外的内容)。 Word Open XML 中也没有任何内容来区分内容控件的类型,除非它包含格式或非文本对象。
正如 Cindy Meister 所说,Word OfficeJS API 仅 returns RichText 内容控件 - 请参阅 Word.ContentControl。
如果你深入研究 OOXML,你会发现纯文本上下文控件(不返回的那些)与富文本控件的主要区别在于它们标有 <w:text/>
。这实质上意味着如果删除该标记,则纯文本内容控件将变为富文本内容控件。所以这是我解决这个问题的方法:
var ooxml = context.document.body.getOoxml();
await context.sync();
var newxml = ooxml.value.replace(/<w:text\/>/g, '');
context.document.body.insertOoxml(newxml, Word.InsertLocation.replace);
var myContentControls = context.document.contentControls;
myContentControls.load();
await context.sync();
console.log(myContentControls.items.length); // now returns 3. Yay!!!
return context.sync();
Nota Bene:getOoxml()
和 insertOoxml()
是缓慢的方法,此变通方法需要很长时间才能执行,因此请仅在绝对必要时使用。
我有一个包含三个 ContentControl
对象的文档,如下所示:
这里是完整的 .docx file - 但基本上文档正文的标记如下所示:
<w:body>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D">
<w:r>
<w:t xml:space="preserve">Video provides a powerful way to help you </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc1"/>
<w:tag w:val="prove"/>
<w:id w:val="806369342"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF9900"/>
<w15:appearance w15:val="tags"/>
<w:text/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>prove</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t xml:space="preserve"> your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc2"/>
<w:tag w:val="number 2"/>
<w:id w:val="1463999480"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF0000"/>
<w15:appearance w15:val="tags"/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>type</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t xml:space="preserve"> a keyword to search online for the video that best fits your document.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D">
<w:r>
<w:t xml:space="preserve">To make your document look professionally produced, Word provides </w:t>
</w:r>
<w:sdt>
<w:sdtPr>
<w:alias w:val="cc3"/>
<w:tag w:val="xxx"/>
<w:id w:val="1703202634"/>
<w:placeholder>
<w:docPart w:val="1F3FDE3D075A4E8AADE251C4E318E379"/>
</w:placeholder>
<w15:color w:val="FF99CC"/>
<w15:appearance w15:val="tags"/>
<w:text/>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:t>header</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r>
<w:t>, footer, cover page, and text box designs that complement each other. For example, you can add a matching cover page, header, and sidebar. Click Insert and then choose the elements you want from the different galleries.</w:t>
</w:r>
</w:p>
<w:p w:rsidR="0075044D" w:rsidRDefault="0075044D"/>
<w:p w:rsidR="00000000" w:rsidRDefault="0075044D"/>
<w:sectPr w:rsidR="00000000">
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
</w:body>
当我运行下面的代码时,只有中间的控件被document.contentControls
返回,因此被我的代码更改了。为什么不返回其他两个控件的任何想法?还有其他人遇到过这个问题吗?有办法解决吗?
Word.run(function (context) {
var myContentControls = context.document.contentControls;
myContentControls.load("tag");
return context.sync()
.then(function () {
for (var i = 0; i < myContentControls.items.length; i++)
{
myContentControls.items[i].color = "blue";
myContentControls.items[i].title = "myCC";
myContentControls.items[i].appearance = "tags";
}
return context.sync();
});
}).catch(OfficeHelpers.Utilities.log);
为了方便起见,这里有一个ScriptLab gist。
有趣的是,这个 VBA 代码 returns 正确的结果 (3
):
Sub Main()
MsgBox ActiveDocument.ContentControls.Count
End Sub
我只在 Windows 10 / Office 365 桌面客户端上尝试过。
如 Word JS API 的内容控件文档中所述,仅支持/识别富文本内容控件。所以代码不会"see"纯文本内容控件。
内容控件是纯文本还是富文本在视觉上无法识别(除非它包含格式或文本以外的内容)。 Word Open XML 中也没有任何内容来区分内容控件的类型,除非它包含格式或非文本对象。
正如 Cindy Meister 所说,Word OfficeJS API 仅 returns RichText 内容控件 - 请参阅 Word.ContentControl。
如果你深入研究 OOXML,你会发现纯文本上下文控件(不返回的那些)与富文本控件的主要区别在于它们标有 <w:text/>
。这实质上意味着如果删除该标记,则纯文本内容控件将变为富文本内容控件。所以这是我解决这个问题的方法:
var ooxml = context.document.body.getOoxml();
await context.sync();
var newxml = ooxml.value.replace(/<w:text\/>/g, '');
context.document.body.insertOoxml(newxml, Word.InsertLocation.replace);
var myContentControls = context.document.contentControls;
myContentControls.load();
await context.sync();
console.log(myContentControls.items.length); // now returns 3. Yay!!!
return context.sync();
Nota Bene:getOoxml()
和 insertOoxml()
是缓慢的方法,此变通方法需要很长时间才能执行,因此请仅在绝对必要时使用。