1

我有一个包含三个ContentControl对象的文档,如下所示:

文件截图

这是整个.docx 文件- 但基本上文档正文的标记如下所示:

<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 要点

有趣的是,这个 VBA 代码返回了正确的结果 ( 3):

Sub Main()
 MsgBox ActiveDocument.ContentControls.Count
End Sub

我只在 Windows 10 / Office 365 桌面客户端上试过这个。

4

2 回答 2

3

如 Word JS API 的内容控件文档中所述,仅支持/识别富文本内容控件。所以代码不会“看到”纯文本内容控件。

内容控件是纯文本还是富文本在视觉上是无法识别的(除非它包含文本以外的格式或内容)。Word Open XML 中也没有任何内容来区分内容控件的类型,除非它包含格式或非文本对象。

于 2020-02-06T22:18:03.073 回答
0

正如 Cindy Meister 已经说过的,Word OfficeJS API 只返回 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()andinsertOoxml()是缓慢的方法,这种解决方法需要很长时间才能执行,所以只在绝对必要时使用。

于 2020-02-07T10:58:35.423 回答