When you create a long document with multiple headings or sections, such as project requirements, design guidelines, or user manuals, it can be difficult to understand the contents and navigate to a particular part. To solve this difficulty, Microsoft Word provides support to insert a table of contents (TOC) in Word documents.
A table of contents is a heading-oriented list or outline of the Word document contents. It indicates which page number each heading is located on and links each entry in the table of contents to the corresponding heading in the document.
Being a developer, you might need to work with the table of contents programmatically. In this blog, you will learn how to create, edit, and update the table of contents in Word documents programmatically in C# using Syncfusion’s .NET Core Word (DocIO) Library.
Syncfusion’s .NET Core Word (DocIO) Library is a feature-rich and high-performance .NET library that allows you to add advanced Word document processing functionalities to any .NET application. It also enables you to create, read, and edit Word documents programmatically without Microsoft Office or interop dependencies.
Let’s get started!
Microsoft Word creates the table of contents based on the document headings up to three levels (Heading 1, Heading 2, and Heading 3) by default.
Likewise, our Syncfusion .NET Core Word (DocIO) Library also creates a table of contents by identifying the contents that have heading styles applied, and inserts the TOC entries as links along with their page numbers.
For more information about applying paragraph styles, please refer to this documentation: Applying paragraph formatting.
You can programmatically create and insert a table of contents based on the built-in heading styles in a Word document by using the AppendTOC method in the WordDocument class.
The following code example illustrates how to create and insert a table of contents for heading levels 1 through 3 in a Word document using the Syncfusion Word Library.
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer; using System.IO; namespace Create_TOC { class Program { static void Main(string[] args) { using (WordDocument document = new WordDocument()) { document.EnsureMinimal(); document.LastSection.PageSetup.Margins.All = 72; WParagraph para = document.LastParagraph; para.AppendText("Essential DocIO - Table of Contents"); para.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center; para.ApplyStyle(BuiltinStyle.Heading4); para = document.LastSection.AddParagraph() as WParagraph; para = document.LastSection.AddParagraph() as WParagraph; //Insert TOC field in the Word document. TableOfContent toc = para.AppendTOC(1, 3); //Sets the heading levels 1 through 3 to include in the TOC. toc.LowerHeadingLevel = 1; toc.UpperHeadingLevel = 3; //Adds content to the Word document with built-in heading styles. WSection section = document.LastSection; WParagraph newPara = section.AddParagraph() as WParagraph; newPara.AppendBreak(BreakType.PageBreak); AddHeading(section, BuiltinStyle.Heading1, "Document with built-in heading styles", "This is the built-in heading 1 style. This sample demonstrates the TOC insertion in a word document. Note that DocIO can insert TOC field in a word document. It can refresh or update TOC field by using UpdateTableOfContents method. MS Word refreshes the TOC field after insertion. Please update the field or press F9 key to refresh the TOC."); AddHeading(section, BuiltinStyle.Heading2, "Section 1", "This is the built-in heading 2 style. A document can contain any number of sections. Sections are used to apply same formatting for a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 1", "This is the built-in heading 3 style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives a meaning for the text."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 2", "This is the built-in heading 3 style. This demonstrates the paragraphs at the same level and style as that of the previous one. A paragraph can have any number formatting. This can be attained by formatting each text range in the paragraph."); //Adds a new section to the Word document. section = document.AddSection() as WSection; section.PageSetup.Margins.All = 72; section.BreakCode = SectionBreakCode.NewPage; AddHeading(section, BuiltinStyle.Heading2, "Section 2", "This is the built-in heading 2 style. A document can contain any number of sections. Sections are used to apply same formatting for a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 1", "This is the built-in heading 3 style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives a meaning for the text."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 2", "This is the built-in heading 3 style. This demonstrates the paragraphs at the same level and style as that of the previous one. A paragraph can have any number formatting. This can be attained by formatting each text range in the paragraph."); //Updates the table of contents. document.UpdateTableOfContents(); //Saves the file in the given path Stream docStream = File.Create(Path.GetFullPath(@"../../../TOC-creation.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); } } private static void AddHeading(WSection section, BuiltinStyle builtinStyle, string headingText, string paragraghText) { WParagraph newPara = section.AddParagraph() as WParagraph; WTextRange text = newPara.AppendText(headingText) as WTextRange; newPara.ApplyStyle(builtinStyle); newPara = section.AddParagraph() as WParagraph; newPara.AppendText(paragraghText); section.AddParagraph(); } } }
You can download the complete working example from this GitHub location.
You can rebuild or update the table of contents in a Word document to reflect the following changes:
You can automatically update the table of contents on demand by invoking the UpdateTableOfContents method in the WordDocument class. This method updates any changes in the heading text, as well as any page changes.
The following code example illustrates how to rebuild or update an existing table of contents in a Word document using the Syncfusion Word Library.
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer; using System.IO; namespace Update_TOC { class Program { static void Main(string[] args) { using (WordDocument document = new WordDocument()) { //Opens the Word template document Stream docStream = File.OpenRead(Path.GetFullPath(@"../../../TOC.docx")); document.Open(docStream, FormatType.Docx); docStream.Dispose(); //Modifies the heading text and inserts a page break document.Replace("Section 1", "First section", true, true); document.Replace("Paragraph 1", "First paragraph", true, true); document.Replace("Paragraph 2", "Second paragraph", true, true); document.Replace("Section 2", "Second section", true, true); var selection = document.Find("heading 3 style", true, true); var paragraph = selection.GetAsOneRange().OwnerParagraph.NextSibling as WParagraph; paragraph.AppendBreak(BreakType.PageBreak); //Updates the table of contents document.UpdateTableOfContents(); //Saves the file in the given path docStream = File.Create(Path.GetFullPath(@"../../../TOC-update.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); } } } }
Note: To perform the update table of contents operation, you have to include the Syncfusion.DocIORenderer.Net.Core NuGet package in your application.
You can download the complete working example from this GitHub location.
In the previous section, we learned about updating a TOC when changes occur in heading text and page numbers. Now, we are going to look at the following editing functionalities:
You can access and edit an existing table of contents in a Word document programmatically by using the following properties in the TableOfContent class
Property Name | Description |
LowerHeadingLevel | Represents the starting heading level to be displayed in the table of contents. The default value is 1. |
UpperHeadingLevel | Represents the ending heading level to be displayed in the table of contents. The default value is 3. |
UseTableEntryFields | Represents a Boolean value which indicates whether to include the TC fields in the Word document as the table of content entries while constructing the TOC. |
IncludePageNumbers | Represents a Boolean value indicating whether to show the page numbers in the table of contents. The default value is true. |
The following code example illustrates how to hide a page number, change the number of heading levels, and include normal text in the TOC by inserting the TC field.
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer; using System.IO; namespace Update_TOC { class Program { static void Main(string[] args) { using (WordDocument document = new WordDocument()) { //Opens the Word template document Stream docStream = File.OpenRead(Path.GetFullPath(@"../../../TOC.docx")); document.Open(docStream, FormatType.Docx); docStream.Dispose(); //Modifies the heading text and inserts a page break document.Replace("Section 1", "First section", true, true); document.Replace("Paragraph 1", "First paragraph", true, true); document.Replace("Paragraph 2", "Second paragraph", true, true); document.Replace("Section 2", "Second section", true, true); var selection = document.Find("heading 3 style", true, true); var paragraph = selection.GetAsOneRange().OwnerParagraph.NextSibling as WParagraph; paragraph.AppendBreak(BreakType.PageBreak); //Updates the table of contents document.UpdateTableOfContents(); //Saves the file in the given path docStream = File.Create(Path.GetFullPath(@"../../../TOC-update.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); } } } }
At times, you might need to create a table of contents based on custom (user-defined) styles. The following APIs allow you to do this:
The following code example illustrates the procedure to add paragraphs with custom styles as headings in an existing table of contents using the Syncfusion Word Library.
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer; using System.IO; namespace TOC_for_custom_styles { class Program { static void Main(string[] args) { using (WordDocument document = new WordDocument()) { document.EnsureMinimal(); document.LastSection.PageSetup.Margins.All = 72; WParagraph para = document.LastParagraph; para.AppendText("Essential DocIO - Table of Contents"); para.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center; para.ApplyStyle(BuiltinStyle.Heading4); para = document.LastSection.AddParagraph() as WParagraph; //Creates the new custom styles. WParagraphStyle pStyle1 = (WParagraphStyle)document.AddParagraphStyle("MyStyle1"); pStyle1.CharacterFormat.FontSize = 18f; WParagraphStyle pStyle2 = (WParagraphStyle)document.AddParagraphStyle("MyStyle2"); pStyle2.CharacterFormat.FontSize = 16f; WParagraphStyle pStyle3 = (WParagraphStyle)document.AddParagraphStyle("MyStyle3"); pStyle3.CharacterFormat.FontSize = 14f; para = document.LastSection.AddParagraph() as WParagraph; //Insert TOC field in the Word document. TableOfContent toc = para.AppendTOC(1, 3); //Sets the Heading Styles to false to define custom levels for TOC. toc.UseHeadingStyles = false; //Sets the TOC level style based on which the TOC should be created. toc.SetTOCLevelStyle(1, "MyStyle1"); toc.SetTOCLevelStyle(2, "MyStyle2"); toc.SetTOCLevelStyle(3, "MyStyle3"); //Adds content to the Word document with custom styles. WSection section = document.LastSection; WParagraph newPara = section.AddParagraph() as WParagraph; newPara.AppendBreak(BreakType.PageBreak); AddHeading(section, "MyStyle1", "Document with custom styles", "This is the 1st custom style. This sample demonstrates the TOC insertion in a Word document. Note that DocIO can insert TOC fields in a Word document. It can refresh or update the TOC field by using the UpdateTableOfContents method. MS Word refreshes the TOC field after insertion. Please update the field or press F9 to refresh the TOC."); AddHeading(section, "MyStyle2", "Section 1", "This is the 2nd custom style. A document can contain any number of sections. Sections are used to apply the same formatting to a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, "MyStyle3", "Paragraph 1", "This is the 3rd custom style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives meaning to the text."); AddHeading(section, "MyStyle3", "Paragraph 2", "This is the 3rd custom style. This demonstrates the paragraphs at the same level and with the same style as the previous one. A paragraph can have any kind of formatting. This can be attained by formatting each text range in the paragraph."); AddHeading(section, "Normal", "Paragraph with normal", "This is the paragraph with the Normal style. This demonstrates the paragraph with outline level 4 and the Normal style. This can be attained by formatting the outline level of the paragraph."); //Adds a new section to the Word document. section = document.AddSection() as WSection; section.PageSetup.Margins.All = 72; section.BreakCode = SectionBreakCode.NewPage; AddHeading(section, "MyStyle2", "Section 2", "This is the 2nd custom style. A document can contain any number of sections. Sections are used to apply the same formatting to a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, "MyStyle3", "Paragraph 1", "This is the 3rd custom style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives meaning to the text."); AddHeading(section, "MyStyle3", "Paragraph 2", "This is the 3rd custom style. This demonstrates the paragraphs at the same level and with the same style as the previous one. A paragraph can have any kind of formatting. This can be attained by formatting each text range in the paragraph."); //Updates the table of contents. document.UpdateTableOfContents(); //Saves the file in the given path Stream docStream = File.Create(Path.GetFullPath(@"../../../TOC-custom-style.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); } } private static void AddHeading(WSection section, string styleName, string headingText, string paragraghText) { WParagraph newPara = section.AddParagraph() as WParagraph; WTextRange text = newPara.AppendText(headingText) as WTextRange; newPara.ApplyStyle(styleName); newPara = section.AddParagraph() as WParagraph; newPara.AppendText(paragraghText); section.AddParagraph(); } } }
You can download the complete working example from this GitHub location.
In this section, you will learn about how to customize the appearance of the table of contents entries. The following TOC heading styles will be applied in our example:
The following code example creates a TOC and customizes the styles of the table of contents entries.
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer; using System.IO; namespace customize_toc_entries_style { class Program { static void Main(string[] args) { using (WordDocument document = new WordDocument()) { document.EnsureMinimal(); document.LastSection.PageSetup.Margins.All = 72; WParagraph para = document.LastParagraph; para.AppendText("Essential DocIO - Table of Contents"); para.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center; para.ApplyStyle(BuiltinStyle.Heading4); para = document.LastSection.AddParagraph() as WParagraph; para = document.LastSection.AddParagraph() as WParagraph; //Insert TOC field in the Word document. TableOfContent toc = para.AppendTOC(1, 3); //Sets the heading levels 1 through 3 to include in the TOC. toc.LowerHeadingLevel = 1; toc.UpperHeadingLevel = 3; //Adds content to the Word document with built-in heading styles. WSection section = document.LastSection; WParagraph newPara = section.AddParagraph() as WParagraph; newPara.AppendBreak(BreakType.PageBreak); AddHeading(section, BuiltinStyle.Heading1, "Document with built-in heading styles", "This is the built-in heading 1 style. This sample demonstrates TOC insertion in a Word document. Note that DocIO can insert TOC fields in a Word document. It can refresh or update TOC fields with the UpdateTableOfContents method. MS Word refreshes the TOC field after insertion. Please update the field or press F9 to refresh the TOC."); AddHeading(section, BuiltinStyle.Heading2, "Section 1", "This is the built-in heading 2 style. A document can contain any number of sections. Sections are used to apply the same formatting to a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 1", "This is the built-in heading 3 style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives meaning to the text."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 2", "This is the built-in heading 3 style. This demonstrates paragraphs at the same level and with the same style as that of the previous one. A paragraph can have any formatting. This can be attained by formatting each text range in the paragraph."); //Adds a new section to the Word document. section = document.AddSection() as WSection; section.PageSetup.Margins.All = 72; section.BreakCode = SectionBreakCode.NewPage; AddHeading(section, BuiltinStyle.Heading2, "Section 2", "This is the built-in heading 2 style. A document can contain any number of sections. Sections are used to apply the same formatting to a group of paragraphs. You can insert sections by inserting section breaks."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 1", "This is the built-in heading 3 style. Each section contains any number of paragraphs. A paragraph is a set of statements that gives meaning to the text."); AddHeading(section, BuiltinStyle.Heading3, "Paragraph 2", "This is the built-in heading 3 style. This demonstrates paragraphs at the same level and with the same style as that of the previous one. A paragraph can have any formatting. This can be attained by formatting each text range in the paragraph."); //Access the TOC 1 style and update its formatting. IWParagraphStyle toc1style = document.AddParagraphStyle("TOC 1"); toc1style.CharacterFormat.FontName = "Calibri"; toc1style.CharacterFormat.FontSize = 14; toc1style.CharacterFormat.Bold = true; toc1style.CharacterFormat.Italic = true; toc1style.ParagraphFormat.AfterSpacing = 8; //Access the TOC 2 style and update its formatting. IWParagraphStyle toc2style = document.AddParagraphStyle("TOC 2"); toc2style.CharacterFormat.FontName = "Calibri"; toc2style.CharacterFormat.FontSize = 12; toc2style.ParagraphFormat.AfterSpacing = 5; toc2style.CharacterFormat.Bold = true; toc2style.ParagraphFormat.LeftIndent = 11; //Access the TOC 3 style and update its formatting. IWParagraphStyle toc3style = document.AddParagraphStyle("TOC 3"); ; toc3style.CharacterFormat.FontName = "Calibri"; toc3style.CharacterFormat.FontSize = 12; toc3style.ParagraphFormat.AfterSpacing = 3; toc3style.CharacterFormat.Italic = true; toc3style.ParagraphFormat.LeftIndent = 22; //Updates the table of contents. document.UpdateTableOfContents(); //Saves the file in the given path Stream docStream = File.Create(Path.GetFullPath(@"../../../TOC-entry-style.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); } } private static void AddHeading(WSection section, BuiltinStyle builtinStyle, string headingText, string paragraghText) { WParagraph newPara = section.AddParagraph() as WParagraph; WTextRange text = newPara.AppendText(headingText) as WTextRange; newPara.ApplyStyle(builtinStyle); newPara = section.AddParagraph() as WParagraph; newPara.AppendText(paragraghText); section.AddParagraph(); } } }
You can download the complete working example from this GitHub location.
You can also remove an existing table of contents from a Word document by using the following code snippet.
The following code snippet identifies where the TOC field starts and ends, and then dynamically inserts a bookmark around the TOC and removes all the content enclosed by the bookmark. Please refer to the example from this GitHub location for the complete code with all the helper methods.
using (WordDocument document = new WordDocument()) { //Opens the Word template document. Stream docStream = File.OpenRead(Path.GetFullPath(@"../../../TOC.docx")); document.Open(docStream, FormatType.Docx); docStream.Dispose(); //Removes the TOC field. TableOfContent toc = document.Sections[0].Body.Paragraphs[2].Items[0] as TableOfContent; RemoveTableOfContents(toc); //Saves the file in the given path docStream = File.Create(Path.GetFullPath(@"../../../Sample.docx")); document.Save(docStream, FormatType.Docx); docStream.Dispose(); }
Thank you for taking the time to read this blog. I hope it clarified you about creating, editing, and updating the table of contents in Word documents using the Syncfusion Word Library. This feature will help you easily navigate to specific headings and get a clear idea of the structure of a lengthy document without the need to read all of it.
Take a moment to peruse the documentation, where you’ll find other options and features, all with accompanying code examples. Using the Word Library, you can create, edit, and merge Word documents, as well as convert them to PDF, image, HTML, RTF, and other formats.
If you are new to our Word Library (Essential DocIO), it is highly recommended that you follow our Getting Started guide.
Are you already a Syncfusion user? You can download the product setup here. If you’re not yet a Syncfusion user, you can download a free, 30-day trial here.
If you have any questions about these features, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!