How can I create a Toc(Table of Content) for a document in Word using office.js?

635 views Asked by At

How can I create a Toc(Table of Content) for a document in Word using office.js? I have look through the help doc on github, but find nothing about this. Please help me. Thank you very much.

2

There are 2 answers

2
Juan Balmori On

Table of Contents is currently not a supported object of the Word JS API.

Make sure to add this idea to our user voice channel

https://officespdev.uservoice.com/forums/224641-feature-requests-and-feedback/category/163566-add-in-word

0
Sagar Mistry On

I am experiment TOC in Word JS API[preview]

till now i had created some sort of TOC look in Word JS API with help of XML[insertOoxml]

Word.run(async function (context) {
        const currentDoc = context.document;
        const body = currentDoc.body;
        const paragraphs = currentDoc.body.paragraphs.load('items');
        const headers = [];
        const uniqueStr = new Date().getTime();
        let insertion = '';
        await context.sync();
        for (let i = 0; i < paragraphs.items.length; i++) {
            // we can use outlineLevel 1,2,3
            if (
                paragraphs.items[i].styleBuiltIn === 'Heading1' ||
                paragraphs.items[i].styleBuiltIn === 'Heading2' ||
                paragraphs.items[i].styleBuiltIn === 'Heading3'
            ) {
                headers.push(paragraphs.items[i]);
            }
        }

        const xValues = headers.map(function (o) {
            return o.outlineLevel;
        });
        const xMax = Math.max.apply(null, xValues);
        const xMin = Math.min.apply(null, xValues);
        console.log(headers);
        headers.map(function (item, i) {
            console.log(item.outlineLevel);
            const bookmarkName = `_Toc${item.outlineLevel + item._Id + uniqueStr}`;
            insertion += `<w:p w:rsidR='00000000' w:rsidRDefault='0043114D'>
                                <w:pPr>
                                    <w:pStyle w:val='TOC${item.outlineLevel}'/>
                                    <w:tabs>
                                        <w:tab w:val='right' w:leader='dot' w:pos='9016'/>
                                        <w:tab w:val="left" w:pos="9016"  w:leader='dot'/>  
                                    </w:tabs>
                                    <w:rPr>
                                        <w:rFonts w:eastAsiaTheme='minorEastAsia' w:cs='Latha'/>
                                        <w:noProof/>
                                        
                                    </w:rPr>
                                </w:pPr>
                                ${
                                    i === 0
                                        ? `<w:r>
                                        <w:fldChar w:fldCharType='begin'/>
                                        </w:r>
                                        <w:r>
                                        <w:rPr>
                                            <w:noProof />
                                            <w:webHidden />
                                            
                                        </w:rPr>
                                        <w:instrText xml:space='preserve'> TOC \\o "${xMin}-${xMax}" \\h \\z \\u </w:instrText>
                                    </w:r>
                                        <w:r>
                                        <w:fldChar w:fldCharType='separate'/>
                                        </w:r>`
                                        : `<w:r><w:rPr>
                                        <w:noProof />
                                        <w:webHidden />
                                    </w:rPr></w:r>`
                                }
                                <w:p w:rsidR='00000000' w:rsidRDefault='0043114D'>
                                    <w:r>
                                        <w:fldChar w:fldCharType="begin"/>
                                    </w:r>
                                    <w:r>
                                        <w:instrText xml:space="preserve"> PAGEREF ${bookmarkName} \\h </w:instrText>
                                    </w:r>
                                    <w:r>
                                        <w:fldChar w:fldCharType="separate"/>
                                    </w:r>
                                    <w:r>
                                    <w:rPr>
                                        <w:rStyle w:val="Hyperlink"/>
                                        <w:noProof/>
                                    </w:rPr>
                                        <w:t>${item.text.toString()}</w:t>
                                    </w:r>
                                    <w:r>
                                        <w:tab />
                                    </w:r>
                                    <w:r>
                                        <w:rPr>
                                            <w:noProof />
                                            <w:webHidden />
                                            <w:spacing w:line='50' w:lineRule='auto'/>
                                        </w:rPr>
                                        <w:fldChar w:fldCharType='separate' />
                                    </w:r>
                                        <w:r>
                                            <w:rPr>
                                                <w:noProof />
                                                <w:webHidden />
                                                
                                            </w:rPr>
                                            <w:t xml:space="preserve"> 1 </w:t>
                                        </w:r>
                                    <w:r>
                                        <w:fldChar w:fldCharType="end"/>
                                    </w:r>
                                </w:p>
                            </w:p>`;
            const insertRange: Word.Range = item.getRange();
            insertRange.insertBookmark(bookmarkName);
        });
        body.insertOoxml(
            `<pkg:package xmlns:pkg='http://schemas.microsoft.com/office/2006/xmlPackage'>
            <pkg:part pkg:name='/_rels/.rels' pkg:contentType='application/vnd.openxmlformats-package.relationships+xml' pkg:padding='512'>
                <pkg:xmlData>
                    <Relationships xmlns='http://schemas.openxmlformats.org/package/2006/relationships'>
                    <Relationship Id='rId1' Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument' Target='word/document.xml'/></Relationships>
                </pkg:xmlData>
            </pkg:part>
            <pkg:part pkg:name='/word/document.xml' pkg:contentType='application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml'>
                <pkg:xmlData>
                    <w:document xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' >
                        <w:body>
                            <w:sdt>
                                <w:sdtPr>
                                    <w:id w:val='${uniqueStr}' />
                                    <w:docPartObj>
                                        <w:docPartGallery w:val='Table of Contents' />
                                        <w:docPartUnique />
                                    </w:docPartObj>
                                </w:sdtPr>
                                <w:sdtEndPr>
                                    <w:rPr>
                                        <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi" />
                                        <w:b />
                                        <w:bCs />
                                        <w:noProof />
                                        <w:color w:val="auto" />
                                        <w:sz w:val="22" />
                                        <w:szCs w:val="22" />
                                    </w:rPr>
                                </w:sdtEndPr>
                                <w:sdtContent>
                                    <w:p w:rsidR="00095C65" w:rsidRDefault="00095C65">
                                        <w:pPr>
                                            <w:pStyle w:val='TOCHeading'/>
                                            <w:b /> 
                                            <w:color w:val="2E74B5" w:themeColor="accent1" w:themeShade="BF" /> 
                                            <w:sz w:val="30" /> 
                                            <w:szCs w:val="30" /> 
                                        </w:pPr>
                                        <w:r>
                                            <w:t>Contents</w:t>
                                        </w:r>
                                    </w:p>
                                    ${insertion}
                                </w:sdtContent>
                            </w:sdt>
                        </w:body>
                    </w:document>
                </pkg:xmlData>
            </pkg:part>
            </pkg:package>`,
            Word.InsertLocation.start
        );

        await context.sync();
        console.log('xml added at the start of the document body.');
    }).catch(OfficeAddinFacade.errorHandler);

now i want page number in dynamic way where Header[1,2,3] is present someone can help me this