In long PDF documents such as project reports, product manuals, technical specifications, or contract collections, navigating page by page can quickly become inconvenient.
Bookmarks provide a simple way to organize the document structure and let readers jump directly to important sections from the navigation panel. Existing PDFs may also need bookmark maintenance when chapter names change, sections are removed, or the original bookmark structure is no longer accurate.
This article shows how to manage PDF bookmarks in Java, including how to:
Add bookmarks to a PDF
Create multi-level bookmarks
Edit existing bookmarks
Remove individual or all bookmarks
Install the Required PDF Library
This article uses Spire.PDF for Java to read and modify PDF files. It provides APIs for creating top-level and child bookmarks, changing bookmark properties, and removing existing bookmarks.
If you are using Maven, add the repository and dependency to your pom.xml:
<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.pdf</artifactId>
<version>12.6.1</version>
</dependency>
</dependencies>
You can replace the version number with the current version used in your project.
After installing the library, load an existing PDF with PdfDocument and work with its bookmark collection.
Add Bookmarks to a PDF
Suppose a project report contains the following major sections:
Project Overview
Implementation Plan
Data Analysis
Recommendations
You can create one top-level bookmark for each section and link it to the corresponding page.
The following example adds bookmarks for the first four pages of a PDF.
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.actions.PdfGoToAction;
import com.spire.pdf.bookmarks.PdfBookmark;
import com.spire.pdf.bookmarks.PdfTextStyle;
import com.spire.pdf.general.PdfDestination;
import com.spire.pdf.graphics.PdfRGBColor;
import java.awt.Color;
import java.awt.geom.Point2D;
public class AddPdfBookmarks {
public static void main(String[] args) {
// Create a PdfDocument object
PdfDocument pdf = new PdfDocument();
// Load the source PDF
pdf.loadFromFile("ProjectReport.pdf");
// Define bookmark titles
String[] bookmarkTitles = {
"Project Overview",
"Implementation Plan",
"Data Analysis",
"Recommendations"
};
// Add bookmarks for the first four pages
for (int i = 0; i < bookmarkTitles.length; i++) {
PdfPageBase page = pdf.getPages().get(i);
// Add a bookmark
PdfBookmark bookmark =
pdf.getBookmarks().add(bookmarkTitles[i]);
// Set the bookmark destination
PdfDestination destination =
new PdfDestination(
page,
new Point2D.Float(0, 0)
);
bookmark.setAction(
new PdfGoToAction(destination)
);
// Set the bookmark color
bookmark.setColor(
new PdfRGBColor(
new Color(47, 84, 150)
)
);
// Display the bookmark in bold
bookmark.setDisplayStyle(
PdfTextStyle.Bold
);
}
// Save the result
pdf.saveToFile("ProjectReportWithBookmarks.pdf");
pdf.close();
}
}
The process consists of three main parts.
First, create a bookmark in the document bookmark collection:
pdf.getBookmarks().add("Project Overview");
Next, create a PdfDestination that identifies the target page and position:
PdfDestination destination =
new PdfDestination(
page,
new Point2D.Float(0, 0)
);
Finally, connect the bookmark to that destination:
bookmark.setAction(
new PdfGoToAction(destination)
);
One detail worth noting is that PDF page indexes start from 0.
For example:
get(0) → Page 1
get(1) → Page 2
get(2) → Page 3
If the actual chapter starts on another page, adjust the page index accordingly.
Create Multi-Level PDF Bookmarks
A single level of bookmarks may not be enough for a document with multiple sections and subsections.
For example:
Implementation Plan
├── Project Schedule
├── Team Assignment
└── Risk Management
In this case, child bookmarks can be added under a parent bookmark.
The following example creates one top-level bookmark and three child bookmarks.
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.actions.PdfGoToAction;
import com.spire.pdf.bookmarks.PdfBookmark;
import com.spire.pdf.general.PdfDestination;
import java.awt.geom.Point2D;
public class AddChildBookmarks {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ProjectReport.pdf");
// Create the parent bookmark
PdfBookmark parentBookmark =
pdf.getBookmarks().add("Implementation Plan");
// Link the parent bookmark to page 2
PdfPageBase parentPage =
pdf.getPages().get(1);
PdfDestination parentDestination =
new PdfDestination(
parentPage,
new Point2D.Float(0, 0)
);
parentBookmark.setAction(
new PdfGoToAction(parentDestination)
);
// Add child bookmark: Project Schedule
PdfBookmark scheduleBookmark =
parentBookmark.add("Project Schedule");
PdfDestination scheduleDestination =
new PdfDestination(
pdf.getPages().get(1),
new Point2D.Float(0, 120)
);
scheduleBookmark.setAction(
new PdfGoToAction(scheduleDestination)
);
// Add child bookmark: Team Assignment
PdfBookmark teamBookmark =
parentBookmark.add("Team Assignment");
PdfDestination teamDestination =
new PdfDestination(
pdf.getPages().get(2),
new Point2D.Float(0, 0)
);
teamBookmark.setAction(
new PdfGoToAction(teamDestination)
);
// Add child bookmark: Risk Management
PdfBookmark riskBookmark =
parentBookmark.add("Risk Management");
PdfDestination riskDestination =
new PdfDestination(
pdf.getPages().get(3),
new Point2D.Float(0, 0)
);
riskBookmark.setAction(
new PdfGoToAction(riskDestination)
);
pdf.saveToFile("ProjectReportWithNestedBookmarks.pdf");
pdf.close();
}
}
The important difference is that child bookmarks are added to the parent bookmark:
parentBookmark.add("Project Schedule");
rather than directly to:
pdf.getBookmarks()
This creates a real hierarchical bookmark structure.
For reports and manuals that already follow a chapter-and-section structure, multi-level bookmarks are usually easier to navigate than a long flat list.
Edit Existing PDF Bookmarks
PDF content often changes over time.
For example, a section originally named:
Project Plan
may later be renamed to:
Project Implementation Plan
If the PDF pages have already been updated, the bookmark can be edited directly instead of rebuilding the entire file.
The following example changes the title, color, and display style of the first bookmark.
import com.spire.pdf.PdfDocument;
import com.spire.pdf.bookmarks.PdfBookmark;
import com.spire.pdf.bookmarks.PdfTextStyle;
import com.spire.pdf.graphics.PdfRGBColor;
import java.awt.Color;
public class EditPdfBookmark {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
// Load a PDF that already contains bookmarks
pdf.loadFromFile("ProjectReport.pdf");
// Get the first bookmark
PdfBookmark bookmark =
pdf.getBookmarks().get(0);
// Change the bookmark title
bookmark.setTitle("Project Implementation Plan");
// Change the bookmark color
bookmark.setColor(
new PdfRGBColor(
new Color(31, 78, 121)
)
);
// Display it in bold
bookmark.setDisplayStyle(
PdfTextStyle.Bold
);
// Save the result
pdf.saveToFile("ProjectReportWithUpdatedBookmark.pdf");
pdf.close();
}
}
If only the title needs to change, the essential code is simply:
bookmark.setTitle("New Section Title");
Changing the color or text style is optional and depends on how the bookmark panel should be presented.
Remove a Specific PDF Bookmark
If a section has been removed from the document, its bookmark should usually be removed as well.
Otherwise, the bookmark may still point to a page that no longer represents the expected content.
A top-level bookmark can be removed with:
pdf.getBookmarks().removeAt(0);
For example:
import com.spire.pdf.PdfDocument;
public class DeletePdfBookmark {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ProjectReport.pdf");
// Remove the first top-level bookmark
pdf.getBookmarks().removeAt(0);
pdf.saveToFile("ProjectReportAfterBookmarkRemoval.pdf");
pdf.close();
}
}
The index also starts from 0, so removeAt(0) removes the first top-level bookmark.
If that bookmark contains child bookmarks, removing the parent also removes the bookmarks under it.
Remove a Child Bookmark
Sometimes only one subsection needs to be removed while the parent bookmark should remain.
In that case, get the parent bookmark first and remove the required child bookmark from it.
PdfBookmark parentBookmark =
pdf.getBookmarks().get(0);
// Remove the first child bookmark
parentBookmark.removeAt(0);
This changes a structure such as:
Implementation Plan
├── Project Schedule ← removed
├── Team Assignment
└── Risk Management
without deleting the entire Implementation Plan bookmark.
This is useful when only part of the document structure changes.
Remove All Bookmarks from a PDF
If the existing bookmark structure is completely outdated, it may be simpler to remove all bookmarks and rebuild them from scratch.
Use:
pdf.getBookmarks().clear();
A complete example looks like this:
import com.spire.pdf.PdfDocument;
public class DeleteAllPdfBookmarks {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ProjectReport.pdf");
// Remove all bookmarks
pdf.getBookmarks().clear();
pdf.saveToFile("ProjectReportWithoutBookmarks.pdf");
pdf.close();
}
}
This approach is useful when:
The existing bookmark structure is no longer valid
The document has been reorganized significantly
Bookmarks need to be regenerated from a new table of contents
PDFs from different sources contain inconsistent bookmark structures
Practical Considerations
1. Remember That Page Indexes Start from 0
This is one of the easiest mistakes to make when assigning bookmark destinations.
If a business rule says that a bookmark should point to page 5, the corresponding code is:
pdf.getPages().get(4);
If page numbers are stored externally as normal one-based numbers, convert them before accessing the PDF page collection:
int pageIndex = pageNumber - 1;
This is particularly important when generating many bookmarks automatically.
2. Validate the Target Page Before Creating a Bookmark
If bookmark definitions come from a database, configuration file, or another external source, do not assume that every page number is valid.
For example:
int pageIndex = 10;
if (pageIndex >= 0 &&
pageIndex < pdf.getPages().getCount()) {
PdfPageBase page =
pdf.getPages().get(pageIndex);
// Create the bookmark here
}
This avoids failures caused by invalid page references.
3. Keep Bookmark Titles Consistent with the Document Structure
If a visible section heading is:
3. Project Implementation Plan
but the bookmark is simply:
Plan
the bookmark technically works, but the navigation structure becomes less clear.
For automatically generated reports, it is usually better to reuse the same chapter titles for both the document body and the bookmarks.
For example:
String[] chapterNames = {
"1. Project Overview",
"2. Implementation Plan",
"3. Data Analysis",
"4. Recommendations"
};
This makes the document body, table of contents, and bookmark panel easier to keep consistent.
4. Avoid Excessively Deep Bookmark Hierarchies
PDF bookmarks support nested levels, but a very deep structure can become difficult to use.
For many reports and manuals, a structure such as:
Chapter
└── Section
or:
Chapter
└── Section
└── Subsection
is usually enough.
If the source data contains six or seven hierarchical levels, consider exposing only the most useful levels as PDF bookmarks rather than reproducing the full internal structure.
Conclusion
Bookmarks provide a practical navigation layer for long PDF documents such as reports, manuals, specifications, and contract collections.
This article covered how to use Java to:
Add top-level bookmarks to a PDF
Create parent-child bookmark structures
Edit bookmark titles and styles
Remove individual top-level or child bookmarks
Remove all bookmarks from a PDF
For automatically generated PDFs, bookmarks can be created from the same chapter names and page information used to build the document. For existing PDFs, outdated bookmark structures can be edited or rebuilt without recreating the entire file.
Keeping the bookmark structure aligned with the actual document makes long PDFs easier to navigate and easier to maintain.
Comments
Post a Comment