Project reports, product manuals, technical documents, and other long-form Word files often contain multiple chapters and sections. As the content changes, section titles, chapter order, and page numbers may also change.
Maintaining the table of contents manually is repetitive and can easily result in missing headings or incorrect page numbers.
A Word table of contents is a field generated from the heading styles used in the document. As long as the document uses Heading 1, Heading 2, Heading 3, and other built-in heading styles correctly, the table of contents can be inserted programmatically and updated after the document changes.
This article demonstrates how to use Java to:
- Create a Word document with multilevel headings
- Generate a table of contents from Heading 1 through Heading 3
- Insert a table of contents into an existing Word document
- Update heading text and page numbers in an existing table of contents
- Control which heading levels appear in the table of contents
How Word Identifies Headings for a Table of Contents
A Word table of contents normally uses paragraph styles to determine the heading hierarchy.
For example:
| Document Content | Word Style | TOC Level |
|---|---|---|
| 1. Project Overview | Heading 1 | Level 1 |
| 1.1 Project Background | Heading 2 | Level 2 |
| 1.1.1 Project Goals | Heading 3 | Level 3 |
Making text bold or increasing its font size does not automatically make it a heading. The paragraph must use an actual Word heading style.
In Java, the following built-in styles can be applied:
BuiltinStyle.Heading_1
BuiltinStyle.Heading_2
BuiltinStyle.Heading_3
The appendTOC() method specifies the heading levels included in the table of contents, while updateTableOfContents() recalculates the entries and page numbers based on the current document structure.
Install the Word Library
The examples below use Spire.Doc for Java to create and edit Word documents.
Add the following repository and dependency to the pom.xml file of a Maven project:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>
https://repo.e-iceblue.com/nexus/content/groups/public/
</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>14.6.0</version>
</dependency>
</dependencies>
The version number can be changed to the version currently used in your project.
Import the required classes:
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.documents.BreakType;
import com.spire.doc.documents.BuiltinStyle;
import com.spire.doc.documents.HorizontalAlignment;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.TextRange;
Create a Word Document with a Table of Contents in Java
The following example creates a Word document from scratch and inserts a table of contents containing Heading 1 through Heading 3.
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.documents.BreakType;
import com.spire.doc.documents.BuiltinStyle;
import com.spire.doc.documents.HorizontalAlignment;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.TextRange;
public class CreateWordWithToc {
public static void main(String[] args) {
// Create a Word document
Document document = new Document();
try {
// Add a section
Section section = document.addSection();
// Add the table of contents title
Paragraph tocTitle = section.addParagraph();
TextRange titleText = tocTitle.appendText(
"Table of Contents"
);
titleText.getCharacterFormat().setBold(true);
titleText.getCharacterFormat().setFontSize(18);
tocTitle.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center
);
// Insert a table of contents containing
// Heading 1 through Heading 3
Paragraph tocParagraph = section.addParagraph();
tocParagraph.appendTOC(1, 3);
// Insert a page break after the table of contents
tocParagraph.appendBreak(BreakType.Page_Break);
// Add a level-one heading
addHeading(
section,
"1. Project Overview",
BuiltinStyle.Heading_1
);
addBodyText(
section,
"This chapter introduces the project background, "
+ "main objectives, and implementation scope."
);
// Add level-two headings
addHeading(
section,
"1.1 Project Background",
BuiltinStyle.Heading_2
);
addBodyText(
section,
"As the scale of the business grows, the existing "
+ "management approach is no longer sufficient "
+ "for centralized operations."
);
addHeading(
section,
"1.2 Project Objectives",
BuiltinStyle.Heading_2
);
addBodyText(
section,
"The project will establish a unified platform for "
+ "data management and business collaboration."
);
// Add level-three headings
addHeading(
section,
"1.2.1 Business Objectives",
BuiltinStyle.Heading_3
);
addBodyText(
section,
"Standardize business processes and improve "
+ "cross-department collaboration."
);
addHeading(
section,
"1.2.2 Technical Objectives",
BuiltinStyle.Heading_3
);
addBodyText(
section,
"Create a scalable and maintainable system architecture."
);
// Add another level-one heading
addHeading(
section,
"2. Implementation Plan",
BuiltinStyle.Heading_1
);
addBodyText(
section,
"This chapter describes the implementation stages "
+ "and major project tasks."
);
addHeading(
section,
"2.1 Implementation Stages",
BuiltinStyle.Heading_2
);
addBodyText(
section,
"The project includes requirements analysis, "
+ "system design, development, testing, "
+ "and deployment."
);
// Update the table of contents based on
// the current headings and pagination
document.updateTableOfContents();
// Save the document
document.saveToFile(
"WordDocumentWithTOC.docx",
FileFormat.Docx_2019
);
} finally {
document.dispose();
}
}
/**
* Add a heading paragraph.
*/
private static void addHeading(
Section section,
String text,
BuiltinStyle style
) {
Paragraph paragraph = section.addParagraph();
paragraph.appendText(text);
paragraph.applyStyle(style);
}
/**
* Add a body paragraph.
*/
private static void addBodyText(
Section section,
String text
) {
Paragraph paragraph = section.addParagraph();
paragraph.appendText(text);
paragraph.getFormat().setAfterSpacing(10);
}
}
After the code runs, it creates:
WordDocumentWithTOC.docx
The first page contains the table of contents, while the main document starts on the next page. The table of contents includes level-one, level-two, and level-three headings together with their page numbers.
Understanding the appendTOC() Parameters
The following code creates a table of contents containing Heading 1 through Heading 3:
tocParagraph.appendTOC(1, 3);
The two parameters represent:
Starting heading level
Ending heading level
For example, to include only Heading 1 and Heading 2:
tocParagraph.appendTOC(1, 2);
To include only Heading 1:
tocParagraph.appendTOC(1, 1);
For most project reports and technical documents, three heading levels are usually sufficient. Including too many levels may make the table of contents difficult to scan and unnecessarily long.
Insert a Table of Contents into an Existing Word Document
In many cases, the Word document already contains the main content and only needs a table of contents added at the beginning.
The following example loads an existing Word file and inserts the table of contents at the beginning of the first section.
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.documents.BreakType;
import com.spire.doc.documents.HorizontalAlignment;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.TextRange;
public class AddTocToExistingDocument {
public static void main(String[] args) {
Document document = new Document();
try {
// Load an existing Word document
document.loadFromFile("ProjectReport.docx");
// Get the first section
Section firstSection =
document.getSections().get(0);
// Create the table of contents title
Paragraph tocTitle = new Paragraph(document);
TextRange titleText = tocTitle.appendText(
"Table of Contents"
);
titleText.getCharacterFormat().setBold(true);
titleText.getCharacterFormat().setFontSize(18);
tocTitle.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center
);
// Create the table of contents paragraph
Paragraph tocParagraph = new Paragraph(document);
tocParagraph.appendTOC(1, 3);
// Insert a page break after the table of contents
tocParagraph.appendBreak(BreakType.Page_Break);
// Insert the title and table of contents
// at the beginning of the first section
firstSection.getParagraphs().insert(
0,
tocTitle
);
firstSection.getParagraphs().insert(
1,
tocParagraph
);
// Update the table of contents
document.updateTableOfContents();
// Save the result as a new file
document.saveToFile(
"ProjectReportWithTOC.docx",
FileFormat.Docx_2019
);
} finally {
document.dispose();
}
}
}
The result is saved as a new file instead of overwriting the source document:
ProjectReport.docx
ProjectReportWithTOC.docx
The headings in the original document must already use styles such as Heading 1, Heading 2, and Heading 3. Otherwise, the table of contents field may be inserted successfully but contain few or no entries.
Apply Heading Styles to Ordinary Paragraphs
If the section titles in an existing document are ordinary paragraphs, heading styles can be applied before generating the table of contents.
For example, suppose the third paragraph in the first section is a level-one heading and the fifth paragraph is a level-two heading:
Section section = document.getSections().get(0);
section.getParagraphs()
.get(2)
.applyStyle(BuiltinStyle.Heading_1);
section.getParagraphs()
.get(4)
.applyStyle(BuiltinStyle.Heading_2);
After applying the styles, insert and update the table of contents:
Paragraph tocParagraph = new Paragraph(document);
tocParagraph.appendTOC(1, 3);
section.getParagraphs().insert(
0,
tocParagraph
);
document.updateTableOfContents();
This approach works well with documents that follow a fixed template.
For documents with an unpredictable structure, relying entirely on paragraph indexes is risky. Adding or removing a paragraph changes the indexes of all subsequent paragraphs.
A more reliable approach is to identify headings by their text, existing styles, bookmarks, or other document markers.
Update an Existing Word Table of Contents
When section titles, chapter order, or document length changes, the table of contents should be updated.
The following example changes a heading and then refreshes the table of contents:
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
public class UpdateWordToc {
public static void main(String[] args) {
Document document = new Document();
try {
// Load a Word document containing a table of contents
document.loadFromFile(
"WordDocumentWithTOC.docx"
);
// Change a heading
document.replace(
"2. Implementation Plan",
"2. Project Implementation Plan",
false,
true
);
// Update the TOC entries and page numbers
document.updateTableOfContents();
// Save the updated document
document.saveToFile(
"UpdatedWordTOC.docx",
FileFormat.Docx_2019
);
} finally {
document.dispose();
}
}
}
After the update, the table of contents entry:
2. Implementation Plan
becomes:
2. Project Implementation Plan
If the document changes cause a heading to move to another page, the corresponding page number is recalculated as well.
Prevent the TOC Title from Appearing in the Table of Contents
The table of contents page often includes a title such as “Table of Contents.”
That title should not use the Heading 1 style unless it is intended to appear as an entry inside the table of contents.
Instead, format it manually:
Paragraph tocTitle = section.addParagraph();
TextRange textRange =
tocTitle.appendText("Table of Contents");
textRange.getCharacterFormat().setBold(true);
textRange.getCharacterFormat().setFontSize(18);
tocTitle.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center
);
Avoid applying a heading style like this:
tocTitle.applyStyle(BuiltinStyle.Heading_1);
Otherwise, “Table of Contents” may appear as a level-one entry inside the table itself.
Common Problems When Updating a Table of Contents
The Table of Contents Is Empty
This usually means the section headings do not use formal Word heading styles.
Bold text, larger font sizes, or different colors do not make a paragraph part of the heading hierarchy.
Apply an actual heading style:
paragraph.applyStyle(BuiltinStyle.Heading_1);
The same applies to Heading 2, Heading 3, and other levels.
Level-Three Headings Are Missing
Check the ending level passed to appendTOC().
The following code includes only Heading 1 and Heading 2:
tocParagraph.appendTOC(1, 2);
To include Heading 3 as well, use:
tocParagraph.appendTOC(1, 3);
Page Numbers Have Not Changed
After modifying the document content, call:
document.updateTableOfContents();
If the document is saved without updating the table of contents, it may continue to display outdated entries or page numbers.
The Table of Contents Appears Before the Cover Page
If the document contains a cover page, place the table of contents in a separate section after the cover instead of inserting it at the first paragraph of the document.
A suitable document structure is:
Section 1: Cover page
Section 2: Table of contents
Section 3: Main content
This approach is more appropriate for formal reports, proposals, and product manuals.
Heading Numbers Are Duplicated
Heading styles define the hierarchy but do not automatically guarantee that manually entered chapter numbers are correct.
For example:
1. Project Overview
1.1 Project Background
If the numbers are written directly in the heading text, the program must ensure that they match the actual heading hierarchy.
When Word multilevel lists are used for automatic numbering, both the list formatting and heading styles need to be maintained.
Practical Considerations
Use a Consistent Heading Structure
A reliable table of contents depends on a consistent document hierarchy.
For example:
Heading 1: Main chapters
Heading 2: Sections
Heading 3: Subsections
Avoid using the same heading level for unrelated structural purposes.
Save the Output as a New File
When adding or updating a table of contents in an existing document, save the result as a new file:
ProjectReport.docx
ProjectReportWithTOC.docx
This keeps the source document available in case the heading styles, pagination, or table of contents layout need to be adjusted.
Keep the Number of TOC Levels Reasonable
Although Word supports several heading levels, including too many levels may reduce readability.
For most business and technical documents, one to three levels are enough.
Check the Result in Word
Automatic generation can handle the heading entries and page numbers, but the result should still be reviewed in Word.
Pay particular attention to:
- Long heading text
- Page breaks
- Section breaks
- Headers and footers
- Landscape pages
- Tables that affect pagination
Conclusion
Java can be used to automate common Word table of contents operations, including:
- Creating Heading 1 through Heading 3 paragraphs
- Generating a table of contents from heading styles
- Inserting a table of contents into an existing Word document
- Updating heading text and page numbers
- Controlling which heading levels appear
- Placing the table of contents between the cover page and main content
The most important part of the process is not the table of contents field itself, but the document’s heading structure.
When headings use the correct Word styles, updateTableOfContents() can regenerate the entries and page numbers after the document changes, reducing the need for manual maintenance.