0

我正在尝试使用 javascript API 将复杂的列表结构插入到 MS Word 中的 contentControl 中。该结构是根据包含嵌套数组的对象构建的:不同的项目包含包含不同属性的子项目。这些项目数组的大小可以改变,因此它需要是通用的。也许 Office.js API 并不是真正为我想要实现的目标而构建的,我应该使用 insertHTML(在 HTML 中构建结构)或 OOXML。

这是我已经建立的结构

产生这个的函数:

import ContentControl = Word.ContentControl;
import {formatDate} from '../formatters';
let firstItem = true;
let listId;

export async function resolveItems(contentControl: ContentControl, data: Array<any>, t) {
Word.run(  contentControl, async (context) => {
    contentControl.load('paragraphs');
    await context.sync();
    for (const item of data) {
        if (firstItem) {
            const firstPara = contentControl.paragraphs.getFirst();
            firstPara.insertText('ITEM (' + formatDate(item.date) + ')', 'Replace');
            firstItem = false;
            const contactList = firstPara.startNewList();
            contactList.load('id');
            await context.sync().catch((error) => {
                console.log('Error: ' + error);
                if (error instanceof OfficeExtension.Error) {
                    console.log('Debug info: ' + JSON.stringify(error.debugInfo));
                }
            });
            listId = contactList.id;
        } else {
            const otherItem = contentControl.insertParagraph('ITEM (' + formatDate(item.date) + ')', 'End');
            otherItem.load(['isListItem']);
            await context.sync();
            otherItem.attachToList(listId, 0);
        }
        for (const subItem of item.subItems) {
            let descriptionParaList = new Array();
            let subItemPara = contentControl.insertParagraph(subItem.title + ' (' + formatDate(subItem.date) + ')', 'End');
            subItemPara.load(['isListItem']);
            await context.sync();
            if (subItemPara.isListItem) {
                subItemPara.listItem.level = 1;
            } else {
                subItemPara.attachToList(listId, 1);
            }
            let descriptions = subItem.descriptions;
            for (const description of descriptions) {
                let descriptionPara = contentControl.insertParagraph('', 'End');
                descriptionPara.insertText(t(description.descriptionType) + ': ', 'Start').font.set({
                    italic: true
                });
                descriptionPara.insertText(description.description, 'End').font.set({
                    italic: false
                });
                descriptionPara.load(['isListItem', 'leftIndent']);
                descriptionParaList.push(descriptionPara);
            }
            await context.sync();
            for (const subItemPara of descriptionParaList) {
                if (subItemPara.isListItem) {
                    subItemPara.detachFromList();
                }
                subItemPara.leftIndent = 72;
            }

        }
    }
    return context.sync().catch((error) => {
        console.log('Error: ' + error);
        if (error instanceof OfficeExtension.Error) {
            console.log('Debug info: ' + JSON.stringify(error.debugInfo));
        }
    });
});}

数据结构如下所示:

'LAST_5_Items': [
    {
        'date': '2019-03-14T14:51:29.506+01:00',
        'type': 'ITEM',
        'subItems': [
            {
                'date': '2019-03-14T14:51:29.506+01:00',
                'title': 'SUBITEM 1',
                'descriptions': [
                    {
                        'descriptionType': 'REASON',
                        'description': 'Reason 1',
                        'additionalInformation': ''
                    }
                ]
            },
            {
                'date': '2019-03-14T14:51:29.506+01:00',
                'title': 'SUBITEM 2',
                'descriptions': [
                    {
                        'descriptionType': 'REASON',
                        'description': 'Reason 1',
                        'additionalInformation': ''
                    }
                ]
            }
        ]
    },
    {
        'date': '2019-03-14T14:16:26.220+01:00',
        'type': 'ITEM',
        'subItems': [
            {
                'date': '2019-03-14T14:16:26.220+01:00',
                'title': 'SUBITEM 1',
                'descriptions': [
                    {
                        'descriptionType': 'REASON',
                        'description': 'Reason 1',
                        'additionalInformation': ''
                    }
                ]
            },
            {
                'date': '2019-03-14T14:16:26.220+01:00',
                'title': 'SUBITEM 2',
                'descriptions': [
                    {
                        'descriptionType': 'REASON',
                        'description': 'Reason 1',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'SUBJECTIVE',
                        'description': 'Subjective 1',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'SUBJECTIVE',
                        'description': 'Subjective 2',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'OBJECTIVE',
                        'description': 'Objective 1',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'OBJECTIVE',
                        'description': 'Objective 2',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'EVALUATION',
                        'description': 'Evaluation',
                        'additionalInformation': ''
                    },
                    {
                        'descriptionType': 'REASON',
                        'description': 'Reason 1',
                        'additionalInformation': ''
                    }
                ]
            }
        ]
    }
]

我想要实现的是模板解析器。该插件将允许用户在文档中放置占位符(ContentControls)、名字、姓氏等标签以及最后的 5 个联系人(我现在描述的那个),当他解析文件时,它将获取所有所需的数据并开始使用此结构化布局替换 ContentControls。

是的,代码可以工作,但我非常怀疑代码结构是否良好,有这么多的 context.sync() 调用。它太慢了,无法使用。我需要这么多 context.sync() 因为我需要列表 ID 的属性以及段落是否属于列表。有没有更好的方法来实现我想要使用 office.js API 实现的目标?

理想情况下,队列应该同步一次,这样用户就不会看到正在以非常奇怪的方式添加和更改的内容,就像它现在的行为一样。

谢谢

4

1 回答 1

0

有一种技术可以避免context.sync进入循环。基本思想是你有两个循环,context.sync它们之间有一个循环。在第一个循环中,您创建一个对象数组。每个对象都包含对您要处理的 Office 对象之一的引用(例如,更改、删除等)。在您的情况下,它看起来像段落。但是该对象具有其他属性。它们中的每一个都包含处理对象所需的一些数据项。这些其他项目可能是其他 Office 对象的属性,也可能是其他数据。此外,无论是在循环中还是在循环之后,您load都需要数组中对象中所有 Office 对象的所有属性。(这通常在循环内更容易做到。)

那么你有context.sync.

同步之后,您将遍历在context.sync. 第二个循环中的代码使用您创建的对象的其他属性处理每个对象(即您要处理的 Office 对象)中的第一项。

以下是该技术的几个示例:

我对这个 StackOverflow 问题的回答:Document not in sync after replace text

此代码示例: https ://github.com/OfficeDev/Word-Add-in-Angular2-StyleChecker/blob/master/app/services/word-document/word.document.service.js 。

于 2019-03-15T23:02:06.373 回答