Table of Content Using Document Object Model!

Can I able to create TOC using aspose DOM ?
As I understand I can use “InsertTableOfContents” using document builder. but it will always create TOC at the start of the document. But I need to create it at specific point. Refer below sample code

Sample Code Below

Document wordDoc = new Document();

if (wordDoc != null)
{
    wordDoc.RemoveAllChildren();
}

// Create a Section and add some content to it. 
Section CurrentSection = new Section(wordDoc);
CurrentSection.AppendChild(new Body(wordDoc));
wordDoc.Sections.Add(CurrentSection);

// Cover Page Content
Paragraph cvpara = new Paragraph(wordDoc);
Run cvrun = new Run(wordDoc, "Hi Welcome to Cover Page Text. This shoud be the first paragraph in the document");
cvpara.AppendChild(cvrun);
CurrentSection.Body.AppendChild(cvpara);

// Heading 1
Paragraph paratext = new Paragraph(wordDoc);
paratext.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
Run runtext = new Run(wordDoc, "Heading 1 - Introduction");
paratext.AppendChild(runtext);
CurrentSection.Body.AppendChild(paratext);

// Text Below Heading 1
Paragraph ph1 = new Paragraph(wordDoc);
Run rn1 = new Run(wordDoc, "Content below Heading 1 which should be place before TOC");
ph1.AppendChild(rn1);
CurrentSection.Body.AppendChild(ph1);

// Heading 2
Paragraph paratext1 = new Paragraph(wordDoc);
paratext1.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
Run runtext1 = new Run(wordDoc, "Heading 2 - Sub to Intro");
paratext1.AppendChild(runtext1);
CurrentSection.Body.AppendChild(paratext1);

// Text Below Heading 2
Paragraph ph2 = new Paragraph(wordDoc);
Run rn2 = new Run(wordDoc, "Content below Heading 2 which should be place before TOC");
ph2.AppendChild(rn2);
CurrentSection.Body.AppendChild(ph2);

// Create Toc using string Builder
DocumentBuilder builder = new DocumentBuilder(wordDoc);
builder.InsertTableOfContents("\o "1 - 3" \h \z \u");
builder.InsertBreak(BreakType.PageBreak);

// Heading 3
Paragraph paratext3 = new Paragraph(wordDoc);
paratext3.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;
Run runtext3 = new Run(wordDoc, "Heading 3 - Last Sub to Intro");
paratext3.AppendChild(runtext3);
CurrentSection.Body.AppendChild(paratext3);

// Text Below Heading 2
Paragraph ph3 = new Paragraph(wordDoc);
Run rn3 = new Run(wordDoc, "Content below Heading 3 which should be place before TOC");
ph3.AppendChild(rn3);
CurrentSection.Body.AppendChild(ph3);

// Update Document Fields
wordDoc.UpdateFields();

// Save Document
string outFile = string.Format("{0}.{1}", "Output_TOC", "docx");
wordDoc.Save(outFile, Aspose.Words.SaveFormat.Docx);

Attached Actual output

Hi Manikandan,

Thanks for your inquiry. Please move the cursor to the desired location and insert the TOC field. Please check the highlighted code snippet below. Hope this helps you.

Moving the Cursor

Document wordDoc = new Document();
if (wordDoc != null)
{
    wordDoc.RemoveAllChildren();
}
// Create a Section and add some content to it. 
Section CurrentSection = new Section(wordDoc);
CurrentSection.AppendChild(new Body(wordDoc));
wordDoc.Sections.Add(CurrentSection);
// Cover Page Content
Paragraph cvpara = new Paragraph(wordDoc);
Run cvrun = new Run(wordDoc, "Hi Welcome to Cover Page Text. This shoud be the first paragraph in the document");
cvpara.AppendChild(cvrun);
CurrentSection.Body.AppendChild(cvpara);
// Heading 1
Paragraph paratext = new Paragraph(wordDoc);
paratext.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
Run runtext = new Run(wordDoc, "Heading 1 - Introduction");
paratext.AppendChild(runtext);
CurrentSection.Body.AppendChild(paratext);
// Text Below Heading 1
Paragraph ph1 = new Paragraph(wordDoc);
Run rn1 = new Run(wordDoc, "Content below Heading 1 which should be place before TOC");
ph1.AppendChild(rn1);
CurrentSection.Body.AppendChild(ph1);
// Heading 2
Paragraph paratext1 = new Paragraph(wordDoc);
paratext1.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
Run runtext1 = new Run(wordDoc, "Heading 2 - Sub to Intro");
paratext1.AppendChild(runtext1);
CurrentSection.Body.AppendChild(paratext1);
// Text Below Heading 2
Paragraph ph2 = new Paragraph(wordDoc);
Run rn2 = new Run(wordDoc, "Content below Heading 2 which should be place before TOC");
ph2.AppendChild(rn2);
CurrentSection.Body.AppendChild(ph2);
FieldToc field = (FieldToc)CreateField(FieldType.FieldTOC, wordDoc);
field.HeadingLevelRange = "1-3";
// Heading 3
Paragraph paratext3 = new Paragraph(wordDoc);
paratext3.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;
Run runtext3 = new Run(wordDoc, "Heading 3 - Last Sub to Intro");
paratext3.AppendChild(runtext3);
CurrentSection.Body.AppendChild(paratext3);
// Text Below Heading 2
Paragraph ph3 = new Paragraph(wordDoc);
Run rn3 = new Run(wordDoc, "Content below Heading 3 which should be place before TOC");
ph3.AppendChild(rn3);
CurrentSection.Body.AppendChild(ph3);
// Update Document Fields
wordDoc.UpdateFields();
// Save Document
wordDoc.Save(MyDir + "Out.docx", Aspose.Words.SaveFormat.Docx);
private static Field CreateField(FieldType fieldType, Document doc)
{
    DocumentBuilder builder = new DocumentBuilder(doc);
    return builder.InsertField(fieldType, true);
}

Thanks Tahir Manzoor. That was really helpful.

Would be happy if you clarify below concern.

I struck here, where my TOC doesn’t update listlabels dynamically. Sample code below with output

Document wordDoc = new Document();

if (wordDoc != null)
{
    wordDoc.RemoveAllChildren();
}

// Create a Section and add some content to it. 
Section CurrentSection = new Section(wordDoc);
CurrentSection.AppendChild(new Body(wordDoc));
wordDoc.Sections.Add(CurrentSection);

// Cover Page Content
Paragraph cvpara = new Paragraph(wordDoc);
Run cvrun = new Run(wordDoc, "Hi Welcome to Cover Page Text. This shoud be the first paragraph in the document");
cvpara.AppendChild(cvrun);
CurrentSection.Body.AppendChild(cvpara);

// Heading 1
Paragraph paratext = new Paragraph(wordDoc);
paratext.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
Run runtext = new Run(wordDoc, "Heading 1 - Introduction");
paratext.AppendChild(runtext);
CurrentSection.Body.AppendChild(paratext);

// Text Below Heading 1
Paragraph ph1 = new Paragraph(wordDoc);
Run rn1 = new Run(wordDoc, "Content below Heading 1 which should be place before TOC");
ph1.AppendChild(rn1);
CurrentSection.Body.AppendChild(ph1);

// Heading 2
Paragraph paratext1 = new Paragraph(wordDoc);
paratext1.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
Run runtext1 = new Run(wordDoc, "Heading 2 - Sub to Intro");
paratext1.AppendChild(runtext1);
CurrentSection.Body.AppendChild(paratext1);

// Text Below Heading 2
Paragraph ph2 = new Paragraph(wordDoc);
Run rn2 = new Run(wordDoc, "Content below Heading 2 which should be place before TOC");
ph2.AppendChild(rn2);
CurrentSection.Body.AppendChild(ph2);

// Create Toc using string Builder
Section CurrentSection1 = new Section(wordDoc);
wordDoc.Sections.Add(CurrentSection1);
DocumentBuilder builder = new DocumentBuilder(wordDoc);
builder.MoveToSection(wordDoc.Count - 1);
builder.InsertTableOfContents("\o "1 - 3" \h \z \u");
builder.InsertBreak(BreakType.PageBreak);
builder.PageSetup.SectionStart = SectionStart.NewPage;

CurrentSection = new Section(wordDoc);
CurrentSection.AppendChild(new Body(wordDoc));
wordDoc.Sections.Add(CurrentSection);
CurrentSection.PageSetup.SectionStart = SectionStart.Continuous;
// Heading 3
Paragraph paratext3 = new Paragraph(wordDoc);
paratext3.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;
Run runtext3 = new Run(wordDoc, "Heading 3 - Last Sub to Intro");
paratext3.AppendChild(runtext3);
CurrentSection.Body.AppendChild(paratext3);

// Text Below Heading 3
Paragraph ph3 = new Paragraph(wordDoc);
Run rn3 = new Run(wordDoc, "Content below Heading 3 which should be place after TOC");
ph3.AppendChild(rn3);
CurrentSection.Body.AppendChild(ph3);

// Heading 4
Paragraph paratext4 = new Paragraph(wordDoc);
paratext4.ParagraphFormat.OutlineLevel = OutlineLevel.Level1;
paratext4.ListFormat.List = wordDoc.Lists.Add(ListTemplate.NumberDefault);
paratext4.ListFormat.ListLevel.NumberFormat = "%1";
paratext4.ListFormat.ListLevel.StartAt = 1;
Run runlabel = new Run(wordDoc);

Run runtext4 = new Run(wordDoc, "This is List Content 1");
paratext4.AppendChild(runtext3);
CurrentSection.Body.AppendChild(paratext4);

// Update Document Fields 
wordDoc.UpdateFields();

// Save Document
string outFile = string.Format("{0}.{1}", "Output_TOC", "docx");
wordDoc.Save(outFile, Aspose.Words.SaveFormat.Docx);

Hi Manikandan,

Thanks for your inquiry.

Please set the value of ListLevel.NumberFormat as shown below to get the correct output. Among normal text characters, the string can contain placeholder characters \x0000 to \x0008 representing the numbers from the corresponding list levels.

For example, the string “\x0000.\x0001)” will generate a list label that looks something like “1.5)”. The number “1” is the current number from the 1st list level, the number “5” is the current number from the 2nd list level.

Paragraph paratext4 = new Paragraph(wordDoc);
paratext4.ParagraphFormat.OutlineLevel = OutlineLevel.Level1;
paratext4.ListFormat.List = wordDoc.Lists.Add(ListTemplate.NumberDefault);
paratext4.ListFormat.ListLevel.NumberFormat = "\x0000";
paratext4.ListFormat.ListLevel.StartAt = 1;