document.contentControls не возвращает все ContentControls в документе - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть документ с тремя ContentControl объектами, который выглядит следующим образом:

screenshot of document

Вот файл .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 gist .

Интересно, что этот код VBA возвращает правильный результат (3 ):

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

Я пробовал это только на Windows 10 / клиент Office 365 для настольных компьютеров.

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

Как указано в документации API Word JS для элементов управления содержимым, поддерживаются / распознаются только элементы управления содержимым Rich Text. Поэтому код не будет «видеть» элементы управления содержимым в виде простого текста.

Независимо от того, является ли элемент управления содержимым простым текстом или форматированный текст не распознается визуально (если он не содержит форматирование или содержимое, отличное от текста). В Word Open XML также нет ничего, что могло бы дифференцировать тип управления содержимым, если только оно не содержит форматирование или нетекстовый объект.

0 голосов
/ 07 февраля 2020

Как уже говорила Синди Мейстер, API-интерфейс Word Office JS возвращает только элементы управления содержимым RichText - см. Word.ContentControl .

Если вы погрузитесь в OO XML, вы обнаружите, что основные элементы управления контекстом в виде простого текста (те, которые не возвращены) отличаются от основных элементов форматированного текста тем, что они отмечены <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() - медленные методы, и этот обходной путь займет много времени, поэтому только используйте, когда это строго необходимо.

...