Search code examples
office365office-jsword-addins

Word Addin: How to find a heading and insert text there?


How to list headings (Heading 1, Heading 2, etc.), find a particular (by name) one and insert a paragraph there? Is it doable in new Word JS API?

Update. Thank you Rick! Pasting here code which does the trick:

    await Word.run(async (context) => {
        try {
            let paragraphs = context.document.body.paragraphs;
            context.load(paragraphs, ['items']);

            // Synchronize the document state by executing the queued commands
            await context.sync();

            let listItems: HeroListItem[] = [];
            for (let i = 0; i < paragraphs.items.length; ++i) {
                let item = paragraphs.items[i];

                context.load(item, ['text', 'style', 'styleBuiltIn']);

                // Synchronize the document state by executing the queued commands
                await context.sync();

                if (item.style === 'Heading 1' || item.style === 'Heading 2') {
                    listItems.push({
                        primaryText: item.text + ' (' + item.style + ')'
                    });

                    if (item.text === 'Late days') {
                        let newLineItem = item.getNextOrNullObject();
                        context.load(item, ['text', 'style', 'styleBuiltIn']);
                        newLineItem.insertParagraph('<<<<<<<<<<<<<<My inserted text>>>>>>>>>>>>>>', 'After');
                    }
                }
            }

            this.setState({listItems: listItems});
        } catch (error) {
            this.setState({listItems: [{primaryText: 'error:' + error}]});
        }
    });

Solution

  • I assume that when you say "name" you mean the text of the heading. This can be done. Your code should load all the paragraphs. Iterate through them and use the style or styleBuiltIn property to find the ones with style names beginning with "Heading". Then iterate through those looking at the text property to find the one you want. Then use the insertParagraph method to insert the new paragraph.

    UPDATE: (Responding to the OP's question below): You should always minimize calls of context.sync, so you should try to avoid calling it in a loop. Try using the for loop to add each paragraph to an array and then context.load the array and do context.sync. Then loop through the array and do your style and text check. BTW, in the code you added to your question, your 3rd call of context.load is unnecessary. You can also delete your second call of context.load, provided that you rewrite the first call of context.load as:

    context.load(paragraphs, ['text', 'style']);
    

    Also, your code doesn't use styleBuiltIn, so you can remove all references to it.