Search

Atalasoft Knowledge Base

HOWTO: Adjust PDF Bookmarks Page Indicies

Tananda
DotImage

There are times when it is necessary to adjust the page indices of bookmarks in PDFs that link to other pages.. for instance, when combining two PDFs using PdfDocument.Combine .. the resulting output PDF will only contain the bookmark tree of the original first document.

To address this you need to walk the PdfBookmarkTree.Bookmarks and adjust the indices of any PdfIndexedPageReference objects

These are actually kind of deep down in the structure and it may not be entirely obvious where to look, so we've created this convenience method code for you

Convenience Method Code:

// <summary>
/// Iterates bookmark list and adjusts any PdfIndexedPageRference by a given offset 
/// </summary>
/// <param name="bkMks" />The PdfBookmarkList to operate upon
/// <param name="pageOffset" />The number of pages to shift the index by
private static void ShiftPageNumbers(PdfBookmarkList bkMks, int pageOffset)
{
    // Skip if the offset is 0 - its basically a no-op
    if (pageOffset != 0)
    {
        foreach (PdfBookmark bm in bkMks)
        {
            // Each boomark can have multiple click actions so we loop
            foreach (PdfAction rawAction in bm.ClickAction)
            {
                // we only want to operate on a very specific subtype of a specific subtype
                if (rawAction.GetType() == typeof(PdfGoToViewAction))
                {
                    PdfGoToViewAction action = rawAction as PdfGoToViewAction;
                    PdfPageReference rawPgRef = action.Destination.Page;

                    if (rawPgRef.GetType() == typeof(PdfIndexedPageReference))
                    {
                        PdfIndexedPageReference indexedRef = rawPgRef as PdfIndexedPageReference;
                        indexedRef.PageIndex = indexedRef.PageIndex + pageOffset;
                    }
                }
            }
        }
    }  
}

Usage:

string finalOutFile = @"C:\pathTo\FINAL_combined.pdf";
string inFile1 = @"C:\pathTo\inFile1.pdf";
string inFile2 = @"C:\pathTo\inFile2.pdf";
string tempCombinedFile = @"C:\pathTo\tempFile.pdf":

PdfDocument.Combine(tempCombinedFile, new string[] { inFile1, file2});

PdfDocument destDoc = new PdfDocument(tempCombinedFile);
PdfDocument srcDoc = new PdfDocument(inFile2);

int pageOffset = destDoc.Pages.Count - srcDoc.Pages.Count;

ShiftPageNumbers(srcDoc.BookmarkTree.Bookmarks, pageOffset);

foreach(PdfBookmark bm in srcDoc.BookmarkTree.Bookmarks)
{
    destDoc.BookmarkTree.Bookmarks.Add(bm);
}
destDoc.Save(finalOutFile);
File.Delete(tempCombinedFile);
Details
Last Modified: 2 Months Ago
Last Modified By: Tananda
Type: HOWTO
Article not rated yet.
Article has been viewed 105 times.
Options
Also In This Category