OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
687 stars 95 forks source link

How to create the Table of Content (TOC) using office.js Word API #5097

Open harsh-borad opened 2 hours ago

harsh-borad commented 2 hours ago

How to create the Table of Content (TOC) using office.js Word API

Platform : PC desktop Host: Word Office version number: Microsoft® Word for Microsoft 365 MSO (Version 2404 Build 16.0.17531.20140) 64-bit Operating System: Microsoft Windows 11 pro

Hello Team , I want to create the TOC using office.js API but found nothing to create it directly,so I tried this below code snippet in ScriptLab with default configuration of ScriptLab HTML,CSS,Libraries. That give me some result but i want to use Word's Built-in Table of Contents Table styles (eg. Automatic Table 1 , etc).

$("#run").on("click", () => tryCatch(run));

async function run() {
  await Word.run(async (context) => {
    const body = context.document.body;

    // Sample TOC data (replace this with your actual data source)
    const tocData = [
      { TOCid: "toc1", title: "Introduction", customPageNumber: 1 },
      { TOCid: "toc2", title: "Methodology", customPageNumber: 2 },
      { TOCid: "toc3", title: "Results", customPageNumber: 5 },
      { TOCid: "toc4", title: "Conclusion", customPageNumber: 8 }
    ];

    // Clear any existing TOC entries
    const tocContentRange = body.search("Custom TOC Start:", { matchCase: true });
    tocContentRange.load("items");
    await context.sync();

    if (tocContentRange.items.length > 0) {
      tocContentRange.items[0]
        .getRange()
        .expandTo(body.getRange("End"))
        .clear();
    }

    // Insert a header for the TOC
    body.insertParagraph("Custom TOC Start:", Word.InsertLocation.end);

    // Loop through TOC data and insert each entry as a new paragraph
    tocData.forEach((entry) => {
      // Insert title with custom page number
      const tocEntryParagraph = body.insertParagraph(
        `${entry.title} ........................... ${entry.customPageNumber}`,
        Word.InsertLocation.end
      );

      // Load the range for hyperlink creation
      const range = tocEntryParagraph.getRange("Whole");
      range.hyperlink = `#${entry.TOCid}`; // This sets the range as a hyperlink to the bookmark
      range.font.color = "Blue"; // Optionally, set font color to indicate hyperlink style

      tocEntryParagraph.style = "TOC 1"; // Apply TOC style or custom formatting as needed
    });
    body.insertParagraph("Custom TOC End", Word.InsertLocation.end);
    await context.sync();
  });
}
// Default helper for invoking an action and handling errors.
async function tryCatch(callback) {
  try {
    await callback();
  } catch (error) {
    console.error(error);
  }
}

This is result below: image

RuizhiSunMS commented 12 minutes ago

Hi @harsh-borad, thx for reporting here. May I confirm that the below is what you want? If yes, range.insertField() may could help you with word.fieldtype.toc image