Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read PDF bookmarks programmatically

I'm using a PDF converter to access the graphical data within a PDF. Everything works fine, except that I don't get a list of the bookmarks. Is there a command-line app or a C# component that can read a PDF's bookmarks? I found the iText and SharpPDF libraries and I'm currently looking through them. Have you ever done such a thing?

like image 527
Robin Rodricks Avatar asked Mar 27 '12 06:03

Robin Rodricks


2 Answers

As the bookmarks are in a tree structure (https://en.wikipedia.org/wiki/Tree_(data_structure)), I've used some recursion here to collect all bookmarks and it's children.

iTextSharp solved it for me.

dotnet add package iTextSharp

Collected all bookmarks with the following code:

using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using iTextSharp.text.pdf;

namespace PdfManipulation
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder bookmarks = ExtractAllBookmarks("myPdfFile.pdf");
        }

        private static StringBuilder ExtractAllBookmarks(string pdf)
        {
            StringBuilder sb = new StringBuilder();
            PdfReader reader = new PdfReader(pdf);
            IList<Dictionary<string, object>> bookmarksTree = SimpleBookmark.GetBookmark(reader);
            foreach (var node in bookmarksTree)
            {
                sb.AppendLine(PercorreBookmarks(node).ToString());
            }
            return RemoveAllBlankLines(sb);
        }

        private static StringBuilder RemoveAllBlankLines(StringBuilder sb)
        {
            return new StringBuilder().Append(Regex.Replace(sb.ToString(), @"^\s+$[\r\n]*", string.Empty, RegexOptions.Multiline));
        }

        private static StringBuilder PercorreBookmarks(Dictionary<string, object> bookmark)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(bookmark["Title"].ToString());
            if (bookmark != null && bookmark.ContainsKey("Kids"))
            {
                IList<Dictionary<string, object>> children = (IList<Dictionary<string, object>>) bookmark["Kids"];
                foreach (var bm in children)
                {
                    sb.AppendLine(PercorreBookmarks(bm).ToString());
                }
            }
            return sb;
        }
    }
}
like image 86
Felipe de Macêdo Avatar answered Oct 13 '22 12:10

Felipe de Macêdo


Try the following code

PdfReader pdfReader = new PdfReader(filename);

IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(pdfReader);

for(int i=0;i<bookmarks.Count;i++)
{
    MessageBox.Show(bookmarks[i].Values.ToArray().GetValue(0).ToString());

    if (bookmarks[i].Count > 3)
    {
        MessageBox.Show(bookmarks[i].ToList().Count.ToString());
    }
}

Note: Don't forget to add iTextSharp DLL to your project.

like image 25
chidambaram Avatar answered Oct 13 '22 10:10

chidambaram