TOC update issue in DOCX file

Hello Team,

We are currently updating the Table of Contents (TOC), but the page numbers are not being updated in the DOCX document. It is working correctly for the PDF version.

We are using the following code:

var wordDocument = (WordDocument)doc;

// ✅ Step 1: Build layout to ensure correct page numbers
wordDocument.Content.UpdatePageLayout();

// ✅ Step 2: Update TOC fields explicitly
foreach (var field in wordDocument.Content.Range.Fields)
{
    if (field.Type == FieldType.FieldTOC)
    {
        field.Update();
    }
}

// ✅ Step 3: Update all other fields (excluding ignored types and TOC)
var fields = wordDocument.Content.Range.Fields
    .Where(x => x.Type != FieldType.FieldTOC && !ignoreFieldTypes.Contains(x.Type))
    .ToList();

fields.ForEach(field => field.Update());

// ✅ Step 4: Clean up placeholders and known errors
foreach (var field in fields)
{
    if (errorMessages.Any(errorMessage => field.Result.Contains(errorMessage)))
    {
        field.Result = string.Empty;
        field.IsLocked = true;
    }

    ClearPlaceholderMergeFields(field);
}

return new MergeCallbackResult
{
    Document = wordDocument
};

Based on our research and information found via Google, it appears this is expected behavior when using Aspose with DOCX files. Aspose does not automatically update TOC page numbers in DOCX documents because Word requires a manual update of the fields (such as TOC) when the document is opened. This is a limitation due to how Microsoft Word handles field updates, and Aspose respects this behavior to maintain document fidelity.

Please let us know if there’s a recommended workaround or if further action is needed.

@pthube

It seems that you are experiencing an issue with updating the Table of Contents (TOC) page numbers in a DOCX document using Aspose. As you noted, the page numbers are not being updated automatically, which is a known behavior when working with DOCX files in Aspose. This is due to how Microsoft Word handles field updates, requiring a manual refresh of fields like the TOC when the document is opened.

To ensure that the TOC is updated correctly, you can follow these steps in your code:

  1. Update the Page Layout: This step ensures that the layout is built correctly, which is essential for accurate page numbering.

    wordDocument.Content.UpdatePageLayout();
    
  2. Update TOC Fields: Iterate through the fields in the document and explicitly update those that are of type TOC.

    foreach (var field in wordDocument.Content.Range.Fields)
    {
        if (field.Type == FieldType.FieldTOC)
        {
            field.Update();
        }
    }
    
  3. Update Other Fields: If you have other fields that need updating (excluding the TOC), you can do so in a similar manner.

    var fields = wordDocument.Content.Range.Fields
        .Where(x => x.Type != FieldType.FieldTOC && !ignoreFieldTypes.Contains(x.Type))
        .ToList();
    
    fields.ForEach(field => field.Update());
    
  4. Handle Errors and Placeholders: If there are known errors or placeholders, you can clean them up as needed.

    foreach (var field in fields)
    {
        if (errorMessages.Any(errorMessage => field.Result.Contains(errorMessage)))
        {
            field.Result = string.Empty;
            field.IsLocked = true;
        }
    
        ClearPlaceholderMergeFields(field);
    }
    

Unfortunately, due to the limitations of how Aspose interacts with DOCX files, there is no automatic way to refresh the TOC page numbers upon document opening. Users typically need to manually refresh the TOC in Microsoft Word after the document is generated.

If you are looking for a workaround, consider providing instructions to users to manually update the TOC after opening the document, or explore if there are any specific settings in your environment that might help with this issue.

If you have further questions or need additional assistance, feel free to ask!

@pthube Could you please attach your problematic input and output documents here for our reference? We will check the issue and provide you more information.

If we compare both images, the Table of Contents shows the page number as 21, but the actual content appears on page 20.

Is what the bot said above correct?

@pthube Thank you for additional information, but, unfortunately, screenshots do not give enough information for analysis. So, could you please attach your actual input and output documents.

No, bot’s answer is not quite correct. Aspose.Words supports updating TOC in both DOCX and PDF documents.

OutPutTOC.docx (275.6 KB)

PFA in this, you can see TOC is not refreshed

Input.docx (306.8 KB)

@pthube Unfortunately, I cannot reproduce the problem on my side using the following simple code:

Document doc = new Document(@"C:\Temp\in.docx");
doc.UpdateFields();
doc.Save(@"C:\Temp\out.docx");

out.docx (299.9 KB)

The problem on your side might occur because the fonts used in your input document are not available on the machine where document is processed. To update page numbers in the TOC Aspose.Words need to built document layout. The fonts are required for this. If Aspose.Words cannot find the font used in the document, the font is substituted. This might lead into fonts mismatch and document layout differences due to the different fonts metrics and as a result incorrect page numbers in the TOC. You can implement IWarningCallback to get notifications when font substitution is performed.
Please see our documentation to learn where Aspose.Words looks for fonts:
https://docs.aspose.com/words/net/specifying-truetype-fonts-location/

InputDoc.docx (269.4 KB)

Can you try for this , we have arial font in this document and i also tried with the code given by you

@pthube ABBvoiceOffice font is used in your document. This font is not available on my side. Could you please provide this font here for testing?

I checked the fonts using a macro in the file InputDoc.docx. It contains two fonts: Aptos and Arial.
And you mentioned font ABBvoiceOffice is also not available in my system

Micro

Sub ListFontsUsed()
    Dim doc As Document
    Dim r As Range
    Dim fList As Object
    Dim fName As Variant
    Dim p As Paragraph

    Set doc = ActiveDocument
    Set fList = CreateObject("Scripting.Dictionary")

    For Each p In doc.Paragraphs
        Set r = p.Range
        If Not fList.Exists(r.Font.Name) Then
            fList.Add r.Font.Name, 1
        End If
    Next p

    ' Output fonts in a new document
    Documents.Add
    For Each fName In fList.Keys
        Selection.TypeText fName & vbCrLf
    Next fName
End Sub

@pthube To get the output closer to MS Word it is required to enable open type features. Aspose.Words.Shaping.Harfbuzz package provides support for OpenType features in Aspose.Words using the HarfBuzz text shaping engine. You should enabling open type features to get the expected result. To achieve this you should add reference to Aspose.Words Shaping Harfbuzz plugin and use the following code to convert your document:

Document doc = new Document(@"C:\Temp\in.docx");
doc.LayoutOptions.TextShaperFactory = Aspose.Words.Shaping.HarfBuzz.HarfBuzzTextShaperFactory.Instance;
doc.Save(@"C:\Temp\out.pdf");