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 BenegetOoxml()insertOoxml() 是缓慢的方法,此变通方法需要很长时间才能执行,因此请仅在绝对必要时使用。