Aspose.Words Table of contents settings

I want to create a table of contents in Word document such that based on the heading level it will automatically add the numbering at the beginning of the title such as 1, 1.1, 1.2, based on which level the heading was adding.

What is the right custom setting to get this behavior?

@slahabar Please see our documentation to learn how to work with Table of Contents:
https://docs.aspose.com/words/net/working-with-table-of-contents/

Table of Contents in MS Word document is represented using TOC field. You can configure it using the appropriate field switches.

Hi Alexey, I have tried a few options from the documentation but was unable to get the functionality I expect.
Do you have guidance on how to configure it to achieve the desired behavior?

@slahabar Could you please create the expected output using MS Word and attach it here for our reference? This will hep us to better understand your requirements.

sample.docx (42.8 KB)

Hi Alexey,
Attached the expected word document.
My question is how can I get the title numbers to show up for each title based on the heading level without have to explicitly mention it.

For e.g, if I write this, it should automatically display as “1 Introduction” and “1.1 Purpose” in the TOC

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
builder.Writeln("Introduction");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
builder.Writeln("Purpose");

@slahabar You can configure list and apply it to the heading styles. For example see the following code:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Configure heading styles to use numbering.
List lst = doc.Lists.Add(ListTemplate.NumberDefault);
lst.ListLevels[0].NumberFormat = "\x0000.";
lst.ListLevels[1].NumberFormat = "\x0000.\x0001";
lst.ListLevels[1].NumberStyle = NumberStyle.Arabic;

doc.Styles[StyleIdentifier.Heading1].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading1].ListFormat.ListLevelNumber = 0;

doc.Styles[StyleIdentifier.Heading2].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading2].ListFormat.ListLevelNumber = 1;

// Insert TOC
builder.InsertTableOfContents("\\o \"1-5\" \\h \\z \\u");
builder.InsertBreak(BreakType.PageBreak);
builder.Writeln();

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
builder.Writeln("Introduction");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
builder.Write("Purpose");

doc.UpdateFields();

doc.Save(@"C:\Temp\out.docx");

Please see our documentation to learn more about working with lists:
https://docs.aspose.com/words/net/working-with-lists/

Thank you @alexey.noskov.
The configuration you suggested works well for my use case and the numbers are showing up correctly.

I have two other issues that I am trying to figure out and would appreciate your help on that.
Attached the document with the issues.

Issue 1.
In the table of contents, the dots between the title e.g., “Introduction” and its corresponding page number, 5 are not running till the end of the line till the right most margin but only about 3/4 of the page length.

Issue 2:
There is a big tab gap between the title number e.g, 1. and title value “Introduction” where the actual content occurs. You can refer page 2 of the document, the blue titles and its numbers are far apart than one tab gap.
sample2.docx (17.6 KB)

@slahabar

  1. Position of page number is configured by tab position:

    In your case tab position is less then page width.

For some reason these tab stops are specified in TOC paragraph explicitly in your document instated of TOC styles. You can use the following code to correct this:

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

// Calculate the right margin position.
double rightMarginPosition = doc.FirstSection.PageSetup.PageWidth - doc.FirstSection.PageSetup.LeftMargin - doc.FirstSection.PageSetup.RightMargin;

StyleIdentifier[] tocStyles = new StyleIdentifier[]
{
    StyleIdentifier.Toc1,
    StyleIdentifier.Toc2,
    StyleIdentifier.Toc3,
    StyleIdentifier.Toc4,
    StyleIdentifier.Toc5,
    StyleIdentifier.Toc6,
    StyleIdentifier.Toc7,
    StyleIdentifier.Toc8,
    StyleIdentifier.Toc9
};

// Setup tab stops in the TOC styles.
foreach (StyleIdentifier identifier in tocStyles)
{
    Style toc = doc.Styles[identifier];
    toc.ParagraphFormat.TabStops.Add(doc.DefaultTabStop, TabAlignment.Left, TabLeader.None);
    toc.ParagraphFormat.TabStops.Add(rightMarginPosition, TabAlignment.Right, TabLeader.Dots);
}

// Reset tab stops set in the TOC paragraphs. 
doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().Where(p => tocStyles.Any(s => s == p.ParagraphFormat.StyleIdentifier))
    .ToList().ForEach(p => p.ParagraphFormat.TabStops.Clear());

doc.Save(@"C:\Temp\out.docx");
  1. You can configure the list items label tab and text position using the appropriate properties.
// Get Heading paragrphs.
List<Paragraph> headings = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().Where(p => p.ParagraphFormat.IsHeading).ToList();
foreach (Paragraph  p in headings)
{
    if (p.IsListItem)
    {
        // Configure list levels
        p.ListFormat.ListLevel.NumberPosition = 20;
        p.ListFormat.ListLevel.TabPosition = 20;
        p.ListFormat.ListLevel.TextPosition = 20;
    }
}
1 Like

Thank you Alexey.
So I got the numbers of the toc to show up in the right of the page as expected.

One more issue I want to fix is that in the toc list, the tab spacing between the numbers and the title is varying based on the level.

See Page 1.
In here the first tab stop length is more for Introduction and shorter for Purpose, Mission.
It is trying to align the text for all the contents in the list. Instead I want the gap between the number and the title to be constant
samaple3.docx (17.9 KB)

.
Similarly on page 2. I want the tab length between the number and the title to be constant on every level.

@slahabar In this case you can use space instead of tab as a trailing character in the list:

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

// Get Heading paragrphs.
List<Paragraph> headings = doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().Where(p => p.ParagraphFormat.IsHeading).ToList();
foreach (Paragraph p in headings)
{
    if (p.IsListItem)
        p.ListFormat.ListLevel.TrailingCharacter = ListTrailingCharacter.Space;
}

doc.UpdateFields();

doc.Save(@"C:\Temp\out.docx");

Please see page 1 of the attached document.

How do I fix the spacing between the number and the title in the Table of contents?
Currently it is aligning all the titles text vertically. Instead I would like to have a constant tab space between the title number and the title value.

I am using below code.

foreach (StyleIdentifier identifier in tocStyles)
{
    Style toc = doc.Styles[identifier];
    toc.ParagraphFormat.TabStops.Add(doc.DefaultTabStop, TabAlignment.Left, TabLeader.Dots);
    toc.ParagraphFormat.TabStops.Add(rightMarginPosition, TabAlignment.Right, TabLeader.Dots);
}

// Reset tab stops set in the TOC paragraphs. 
doc.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().Where(p => tocStyles.Any(s => s == p.ParagraphFormat.StyleIdentifier))
    .ToList().ForEach(p => p.ParagraphFormat.TabStops.Clear());

samaple3.docx (17.9 KB)

@slahabar As I have mentioned, in this case you can use space instead of tab as a trailing character in the list. Please see the output produced by the above mentioned code: out.docx (13.5 KB)