PDFtoolkit VCL
Edit, enhance, secure, merge, split, view, print PDF and AcroForms documents
Delphi C++Builder

How To Split A PDF Document By Its Bookmarks

If a PDF documents has several chapters and each chapter has a bookmark, then how would you split the document by chapter?
Girish Patil & Suraj C. B.

In this article, we will see part of the code that was used in the CodeRageĀ II Gnostice session titled Top 5 PDF User Needs Solved using Gnostice PDF Tools. One of the top PDF-related needs that we addressed in the demo was about splitting PDF documents based on a given criteria.

In the session, we demonstrated how to split a PDF documents by its bookmarks. Imagine that you have a PDF document where the content is divided into several chapters. If each of these chapters have a corresponding bookmark, then we could split the document in such a manner that each chapter would be available in a separate PDF document.

The main procedure in the code was SplitByBookmark. It uses a function GetFirstBookmarkWithSiblings recursively to parse the bookmark tree of the PDF document and return bookmark nodes that have child bookmarks.

// Object used to load
// the input PDF document
PDFDoc: TgtPDFDocument;

edOutputFile: TEdit;


procedure TSplitByBkmark.SplitByBookmark;
  function GetFirstBookmarkWithSiblings: TgtPDFOutline;
    // Get hold of root bookmark object and then the
    // first node, which is always the first 
    // child of the root
    with PDFDoc do
      Result := GetBookmarkRoot;
      if Result = nil then
      Result := Result.GetFirstChild;
      // Traverse down the bookmark tree until multiple
      // siblings are found at the same level
      while (Result.GetNextNode = nil) and (Result <> nil) do
        Result := Result.GetFirstChild;

  LBookmark1: TgtPDFOutline;
  with PDFDoc do
    LBookmark1 := GetFirstBookmarkWithSiblings;
    if LBookmark1 = nil then
        'The specified document does not contain ' +
	'bookmarks.'#13#10 +
        'Aborting splitting operation.');
      LSplitDone := False;

    // Loop through all bookmarks in the same level
    while LBookmark1.GetNextNode <> nil do
      // Use bookmark title text for the name of
      // the output document and copy pages until
      // page linked by the next bookmark is reached
        MakeOutputFilename(edOutputFile.Text, LBookmark1.Title),
               LBookmark1.GetNextNode.Destination.PageNo - 1]));
      LBookmark1 := LBookmark1.GetNextNode;

    // Copy last chapter into new document
      MakeOutputFilename(edOutputFile.Text, LBookmark1.Title),
             [LBookmark1.Destination.PageNo, PageCount]));
    LSplitDone := True;


The procedure also uses a function MakeOutputFilename that creates valid output filenames by appending the text used to display the bookmark to the original filename. Invalid filename characters are automatically stripped out of the resulting filename.




Our .NET Developer Tools
Gnostice Document Studio .NET

Multi-format document-processing component suite for .NET developers.


A .NET PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, and bookmark PDF documents in .NET applications.

Our Delphi/C++Builder developer tools
Gnostice Document Studio Delphi

Multi-format document-processing component suite for Delphi/C++Builder developers, covering both VCL and FireMonkey platforms.

eDocEngine VCL

A Delphi/C++Builder component suite for creating documents in over 20 formats and also export reports from popular Delphi reporting tools.

PDFtoolkit VCL

A Delphi/C++Builder component suite to edit, enhance, view, print, merge, split, encrypt, annotate, and bookmark PDF documents.

Our Java developer tools
Gnostice Document Studio Java

Multi-format document-processing component suite for Java developers.

PDFOne (for Java)

A Java PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, bookmark PDF documents in Java applications.

Our Platform-Agnostic Cloud and On-Premises APIs

Cloud-hosted and On-Premises REST-based document-processing and document-viewing APIs

Privacy | Legal | Feedback | Newsletter | Blog | Resellers © 2002-2024 Gnostice Information Technologies Private Limited. All rights reserved.