DEV Community

Cover image for Create and Update Table of Contents in Word Documents in .NET Core [C#]
Suresh Mohan for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

Create and Update Table of Contents in Word Documents in .NET Core [C#]

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!

Create and insert the table of contents with heading styles

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.

A Table of Contents Created with Built-in Heading Styles
A Table of Contents Created with Built-in Heading Styles

Update an existing table of contents when contents change

You can rebuild or update the table of contents in a Word document to reflect the following changes:

  • Heading text alteration.
  • Heading inserted or removed from the document.
  • Content changes that result in a page break.

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.

Updating Table of Contents in a Word Document
Updating Table of Contents in a Word Document

Edit an existing table of contents

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:

  • Modify the number of heading levels to be shown in the table of contents.
  • Exclude the page numbers.
  • Include topics marked with the TC (table of contents entry) field (not applied with a heading style).

You can access and edit an existing table of contents in a Word document programmatically by using the following properties in the TableOfContent class

TOC properties and description

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();
            }
        }
    }
}

Removing Page Number from the Table of Contents
Removing Page Number from the Table of Contents

Insert table of contents with custom styles

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:

  • UseHeadingStyles : Enable or disable inclusion of paragraphs with built-in heading styles in the TOC.
  • SetTOCLevelStyle : Sets the custom (user-defined) styles with their respective heading levels to be included in the TOC.

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.

A Table of Contents Created with Custom (User-Defined) Styles
A Table of Contents Created with Custom (User-Defined) Styles

Customize the format of table of contents entries

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:

  • 1st level of the table of contents entries have the paragraph style TOC 1 applied to them.
  • 2nd level of TOC entries have the paragraph style TOC 2 applied to them.
  • 3rd level of TOC entries have the paragraph style TOC 3 applied to them.
  • Following this pattern, up to 9 levels of TOC entries are set up.

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.

Table of Contents Entries with Custom Formatting
Table of Contents Entries with Custom Formatting

Remove a table of contents

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();
            }

Summary

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!

Oldest comments (0)