Search code examples
c#gembox-document

Gembox document removes table of contents


I'm using Gembox document to replace some text in a docx document and it works great. However, I have a table of contents field that disappears after saving the document. I tried doing the following but the field still disappears leaving only the placeholder text:

var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
toc.Update();
document.GetPaginator(new PaginatorOptions() { UpdateFields = true });

Solution

  • UPDATE (2021-01-15):

    Please try again with the latest version from the BugFixes page or from NuGet.

    The latest version will work on the machine that uses culture with ';' character as a list separator.
    Or you can specify that culture like this:

    var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();
    
    CultureInfo.CurrentCulture = new CultureInfo("fr");
    toc.Update();
    
    document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
    

    Also, the issue with the missing tab stop should be resolved now as well.

    ORIGINAL:

    When I tried to update your TOC from MS Word, I got the following:

    No table of contents entries found.

    After investigating the field's code of your TOC element, I figured out what the problem is.
    This is the instruction text that you have:

    { TOC \h \z \t "TitreChapitre;1;SousTitreChapitre;2" }
    

    These semicolon character separators (;) are culture-dependent. In other words, updating this TOC element will work on a machine that has a French region and settings, but it won't work when you have an English region and settings.

    I'm currently on vacation, so I can't do anything about this. When I come back I will fix this problem for you.

    For now, can you use the following as a workaround (I also noticed an issue with missing TabStop, this workaround will cover that as well):

    var toc = (TableOfEntries)document.GetChildElements(true, ElementType.TableOfEntries).First();            
    var section = toc.Parent as Section;
    
    var tocWidth = section.PageSetup.PageWidth - section.PageSetup.PageMargins.Left - section.PageSetup.PageMargins.Right;
    
    var toc1Style = document.Styles["toc 1"] as ParagraphStyle;
    var toc1TabStop = new TabStop(tocWidth - toc1Style.ParagraphFormat.RightIndentation, TabStopAlignment.Right, TabStopLeader.Dot);
    toc1Style.ParagraphFormat.Tabs.Add(toc1TabStop);
    
    var toc2Style = document.Styles["toc 2"] as ParagraphStyle;
    var toc2TabStop = new TabStop(tocWidth - toc2Style.ParagraphFormat.RightIndentation, TabStopAlignment.Right, TabStopLeader.Dot);
    toc2Style.ParagraphFormat.Tabs.Add(toc2TabStop);
    
    toc.InstructionText = toc.InstructionText.Replace(';', ',');
    toc.Update();
    
    document.GetPaginator(new PaginatorOptions() { UpdateFields = true });
    

    I hope this works for you.