DEV Community

Leon Davis
Leon Davis

Posted on

How to Add, Edit, and Remove PDF Bookmarks in Java

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>
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

The process consists of three main parts.

First, create a bookmark in the document bookmark collection:

pdf.getBookmarks().add("Project Overview");
Enter fullscreen mode Exit fullscreen mode

Next, create a PdfDestination that identifies the target page and position:

PdfDestination destination =
        new PdfDestination(
                page,
                new Point2D.Float(0, 0)
        );
Enter fullscreen mode Exit fullscreen mode

Finally, connect the bookmark to that destination:

bookmark.setAction(
        new PdfGoToAction(destination)
);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

The important difference is that child bookmarks are added to the parent bookmark:

parentBookmark.add("Project Schedule");
Enter fullscreen mode Exit fullscreen mode

rather than directly to:

pdf.getBookmarks()
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

may later be renamed to:

Project Implementation Plan
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

If only the title needs to change, the essential code is simply:

bookmark.setTitle("New Section Title");
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

This changes a structure such as:

Implementation Plan
├── Project Schedule   ← removed
├── Team Assignment
└── Risk Management
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

If page numbers are stored externally as normal one-based numbers, convert them before accessing the PDF page collection:

int pageIndex = pageNumber - 1;
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

but the bookmark is simply:

Plan
Enter fullscreen mode Exit fullscreen mode

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"
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

or:

Chapter
└── Section
    └── Subsection
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)