Merging Bookmarks of Two or More PDF Files by ITextSharp

Recently, I was working on a project. In the project I would like to merge bookmarks of two or more PDF Files by iTextSharp. So I tried looking at tutorials around the web. But I can't find a good solution to this. This article will explain how to merge bookmarks of two or more PDF Files by iTextSharp. To do that here we use the ITextSharp library to create PDF documents. It provides all of the primitive functions necessary to create a PDF document.

This article is for merging of bookmarks of two or more PDF files where each file contains bookmarks.

For example PDF file A that contains some bookmark and file B that contains other bookmarks.

I will merge two PDF files using iTextSharp. After merging the two files A & B then the new File C will be created where all bookmarks will be in File C.

File A bookmark:

File A bookmark

File B bookmark:

File B bookmark

After merging File A and File B then File C contains the bookmark.

bookmark

With this code section you can get a PDF file's bookmarks:

  1. iTextSharp.text.Document document = new iTextSharp.text.Document();   
  2. MemoryStream output = new MemoryStream();        
  3. PdfWriter writer = PdfWriter.GetInstance(document, output);   
  4. writer.PageEvent = new FilePageEvent();   
  5. // Open document to write   
  6. document.Open();   
  7. PdfContentByte content = writer.DirectContent;   
  8. int counter = 0;   
  9. int fileCount = 0;   
  10. int pageno = 0;                    
  11.   
  12. foreach (FileInformation file in sourceFiles)   
  13. {   
  14.     filesByte.Add(File.ReadAllBytes(file.FilePath));   
  15. }   
  16. PdfOutline objRootOutLine;   
  17. List<PDFFIleManager> FileBookmarkInfo;   
  18. objRootOutLine = content.RootOutline;   
  19. PdfOutline objfolderoutline = content.RootOutline;   
  20. string folderName = string.Empty;   
  21. for (int fileCounter = 0; fileCounter < filesByte.Count; fileCounter++)   
  22. {        
  23.     // Create pdf reader   
  24.     PdfReader reader = new PdfReader(filesByte[fileCounter]);   
  25.     int numberOfPages = reader.NumberOfPages;   
  26.     IList<Dictionary<stringobject>> book_mark = SimpleBookmark.GetBookmark(reader);   
  27. }   
  28. By this code section you can merge PDF file bookmarks   
  29. //******************Start merging bookmark of pdf generation      
  30.   
  31. if (!object.Equals(book_mark, null))   
  32. {   
  33.     int index = 0;   
  34.     int j = 0;   
  35.     foreach (Dictionary<stringobject> bk in book_mark)   
  36.     {   
  37.         int i = 0;   
  38.         IList<Dictionary<stringobject>> kids = null;   
  39.         IList<Dictionary<stringobject>> list = null;   
  40.         string Title = string.Empty;   
  41.         int page = 0;   
  42.         foreach (string key in bk.Keys)   
  43.         {   
  44.             if (key.Equals("Title"))   
  45.             {   
  46.                 Title = Convert.ToString(bk[key]);   
  47.                 i = i + 1;   
  48.                 CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  49.                 TextInfo textInfo = cultureInfo.TextInfo;   
  50.                 Title = textInfo.ToTitleCase(Title);   
  51.                 // counter = i;   
  52.             }   
  53.             if (key.Equals("Kids"))   
  54.             {   
  55.                 kids = (IList<Dictionary<stringobject>>)bk[key];   
  56.             }   
  57.             if (key.Equals("Page"))   
  58.             {   
  59.             //page = Convert.ToString(bk[key]).Split('');   
  60.             string[] words = Convert.ToString(bk[key]).Split(' ');   
  61.             if (!object.Equals(words, null))   
  62.             {   
  63.                 page = Convert.ToInt32(words[0]);   
  64.             }   
  65.         }   
  66.     }   
  67.     if (!string.IsNullOrEmpty(Title))   
  68.     {   
  69.         // counter = counter + 1;   
  70.         PdfAction obja3lvl = PdfAction.GotoLocalPage(counter + page -1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  71.         PdfOutline objoutline3lvl = new PdfOutline(objoutline, obja3lvl, Title.ToString(), true);  
  72.   
  73.         if (!object.Equals(kids, null))   
  74.         {   
  75.             // int j = i;   
  76.             foreach (Dictionary<stringobject> innerkids in kids)   
  77.             {   
  78.                 IList<Dictionary<stringobject>> kids2nd = null;   
  79.                 string Title2nd = string.Empty;   
  80.                 int page2 = 0;   
  81.                 foreach (string key in innerkids.Keys)   
  82.                 {   
  83.                     if (key.Equals("Title"))   
  84.                     {   
  85.                         Title2nd = Convert.ToString(innerkids[key]);   
  86.                         i = i + 1;   
  87.                         CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  88.                         TextInfo textInfo = cultureInfo.TextInfo;   
  89.                         Title2nd = textInfo.ToTitleCase(Title2nd);   
  90.                     }  
  91.   
  92.                     if (key.Equals("Kids"))   
  93.                     {   
  94.                         kids2nd = (IList<Dictionary<stringobject>>)innerkids[key];   
  95.                     }   
  96.                     if (key.Equals("Page"))   
  97.                     {   
  98.                         string[] words = Convert.ToString(innerkids[key]).Split(' ');  
  99.   
  100.                         if (!object.Equals(words, null))   
  101.                         {   
  102.                             page2 = Convert.ToInt32(words[0]);   
  103.                         }   
  104.                     }   
  105.                 }  
  106.   
  107.                 if (!string.IsNullOrEmpty(Title2nd))   
  108.                 {   
  109.                     PdfAction obja4lvl = PdfAction.GotoLocalPage(counter + page2 - 1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  110.                     PdfOutline objoutline4lvl = new PdfOutline(objoutline3lvl, obja4lvl, Title2nd.ToString(), true);  
  111.   
  112.                     if (!object.Equals(kids2nd, null))   
  113.                     {   
  114.                         // int k = j;   
  115.                         foreach (Dictionary<stringobject> innerkids3rd in kids2nd)   
  116.                         {   
  117.                             IList<Dictionary<stringobject>> kids3rd = null;   
  118.                             string Title3rd = string.Empty;   
  119.                             int page3 = 0;   
  120.                             foreach (string key in innerkids3rd.Keys)   
  121.                             {   
  122.                                 if (key.Equals("Title"))   
  123.                                 {   
  124.                                     Title3rd = Convert.ToString(innerkids3rd[key]);   
  125.                                     i = i + 1;   
  126.                                     CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  127.                                     TextInfo textInfo = cultureInfo.TextInfo;   
  128.                                     Title3rd = textInfo.ToTitleCase(Title3rd);   
  129.                                 }   
  130.                                 if (key.Equals("Kids"))   
  131.                                 {   
  132.                                    kids3rd = (IList<Dictionary<stringobject>>)innerkids3rd[key];   
  133.                                 }   
  134.                                 if (key.Equals("Page"))   
  135.                                 {   
  136.                                     // page3 = Convert.ToInt32(innerkids3rd[key]);   
  137.                                     string[] words = Convert.ToString(innerkids3rd[key]).Split(' ');   
  138.                                     if (!object.Equals(words, null))   
  139.                                     {   
  140.                                        page3 = Convert.ToInt32(words[0]);   
  141.                                     }   
  142.                                 }   
  143.                             }   
  144.                             if (!string.IsNullOrEmpty(Title2nd))   
  145.                             {   
  146.                                 PdfAction obja5lvl = PdfAction.GotoLocalPage(counter + page3 - 1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  147.                                 PdfOutline objoutline5lvl = new PdfOutline(objoutline4lvl, obja5lvl, Title3rd.ToString(), true);   
  148.                             }   
  149.                         }   
  150.                     }   
  151.                 }   
  152.             }   
  153.         }   
  154.     }   
  155. }      
  156.   
  157. //*************End bookmark of pdf generation 

The MergePDF Method that accepts a collection of PDF files that have Bookmarks where you can merge 3 levels of bookmarks.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace Common.Interface  
  7. {  
  8.     /// <summary>  
  9.     /// Interface for manage the file information  
  10.     /// </summary>  
  11.     public interface IFileInformation  
  12.     {  
  13.         #region Properties  
  14.         /// <summary>  
  15.         /// Gets and set the fileid  
  16.         /// </summary>  
  17.         string FileID  
  18.         {  
  19.             get;  
  20.             set;  
  21.         }  
  22.         /// <summary>  
  23.         /// Gets and sets the pdf file name  
  24.         /// </summary>  
  25.         string FileName  
  26.         {  
  27.             get;  
  28.             set;  
  29.         }  
  30.         /// <summary>  
  31.         /// Gets and sets the pdf file path  
  32.         /// </summary>  
  33.         string FilePath  
  34.         {  
  35.             get;  
  36.             set;  
  37.         }  
  38.         /// <summary>  
  39.         /// Gets and set the folder name  
  40.         /// </summary>  
  41.         string FolderName  
  42.         {  
  43.             get;  
  44.             set;  
  45.         }  
  46.         /// <summary>  
  47.         /// Gets and set the is deleted  
  48.         /// </summary>  
  49.         bool IsDeleted  
  50.         {  
  51.             get;  
  52.             set;  
  53.         }  
  54.         /// <summary>  
  55.         /// Gets and set the is bookmarkName  
  56.         /// </summary>  
  57.         string FileBookMark  
  58.         {  
  59.             get;  
  60.             set;  
  61.         }  
  62.         #endregion  
  63.     }  
  64. }  
  65.              
  66.   /// <summary>  
  67.         /// Method for merge pdf files  
  68.         /// </summary>  
  69.         /// <param name="listFileInformation">List of pdf files</param>  
  70.         /// <returns></returns>  
  71.         public byte[] MergePDF(List<IFileInformation> sourceFiles)  
  72.         {       
  73.             if (sourceFiles.Count == 0)  
  74.             {  
  75.                 throw new ArgumentNullException("File list");  
  76.             }   
  77.           iTextSharp.text.Document document = new iTextSharp.text.Document();  
  78.           MemoryStream output = new MemoryStream();  
  79.             List<byte[]> filesByte = new List<byte[]>();  
  80.             bool checkCoverBookmark = true;  
  81.             try  
  82.             {  
  83.                 // Initialize pdf writer  
  84.                 PdfWriter writer = PdfWriter.GetInstance(document, output);  
  85.                 writer.PageEvent = new FilePageEvent();  
  86.                 // Open document to write  
  87.                 document.Open();  
  88.                 PdfContentByte content = writer.DirectContent;  
  89.                 int counter = 0;  
  90.                 int fileCount = 0;  
  91.                 int pageno = 0;  
  92.                   
  93.                 foreach (FileInformation file in sourceFiles)  
  94.                 {  
  95.                     filesByte.Add(File.ReadAllBytes(file.FilePath));  
  96.                 }  
  97.                 PdfOutline objRootOutLine;  
  98.                 List<PDFFIleManager> FileBookmarkInfo;  
  99.                 objRootOutLine = content.RootOutline;  
  100.                 PdfOutline objfolderoutline = content.RootOutline;  
  101.                 string folderName = string.Empty;  
  102.                 for (int fileCounter = 0; fileCounter < filesByte.Count; fileCounter++)  
  103.                 {   
  104.                     // Create pdf reader  
  105.                     PdfReader reader = new PdfReader(filesByte[fileCounter]);  
  106.                     int numberOfPages = reader.NumberOfPages;            
  107.                     IList<Dictionary<stringobject>> book_mark = SimpleBookmark.GetBookmark(reader);  
  108.    
  109.                     if (!object.Equals(book_mark, null))  
  110.                     {  
  111.                         IList<Dictionary<stringobject>> list = IterateBookmark(book_mark);  
  112.                     }                
  113.                     #region  bookmarking of member and decision vote  
  114.                     // Iterate through all pages  
  115.                     for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)  
  116.                     {  
  117.                         counter = counter + 1;  
  118.                         pageno = pageno + 1;  
  119.                         // Determine page size for the current page  
  120.                         document.SetPageSize(reader.GetPageSizeWithRotation(currentPageIndex));  
  121.                         // Create page  
  122.                         document.NewPage();       
  123.                         if (currentPageIndex == 1)  
  124.                         {  
  125.                             fileCount = fileCount + 1;  
  126.                             string fileName = (from l in sourceFiles where l.FileID == fileCount.ToString() select l.FileName).FirstOrDefault();  
  127.                             string folderName1 = (from l in sourceFiles where l.FileID == fileCount.ToString() select l.FolderName).FirstOrDefault();  
  128.                             string bookmarkIndividualName = (from l in sourceFiles where l.FileID == fileCount.ToString() select l.FileBookMark).FirstOrDefault();  
  129.                             if (folderName != folderName1)  
  130.                             {  
  131.                                 PdfAction objFolderAction = PdfAction.GotoLocalPage(counter, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);  
  132.                                 objfolderoutline = new PdfOutline(objRootOutLine, objFolderAction, folderName1.ToUpper(), true);  
  133.                                 folderName = folderName1;
  134.                             }  
  135.   
  136.                             PdfAction objaction = PdfAction.GotoLocalPage(counter, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);  
  137.                                  
  138.                             if (string.IsNullOrEmpty(bookmarkIndividualName))  
  139.                                 bookmarkIndividualName = fileName;   
  140.                             PdfOutline objoutline = new PdfOutline(objfolderoutline, objaction, bookmarkIndividualName.ToUpper(), true);   
  141.       //******************Start merging bookmark of pdf generation   
  142.                             if (!object.Equals(book_mark, null))  
  143.                             {  
  144.                                 int index = 0;            
  145.                                 int j = 0;                                   
  146.                                 foreach (Dictionary<stringobject> bk in book_mark)  
  147.                                 {   
  148.                                     int i = 0;  
  149.                                     IList<Dictionary<stringobject>> kids = null;  
  150.                                     IList<Dictionary<stringobject>> list = null;  
  151.                                     string Title = string.Empty;  
  152.                                     int page = 0;                                         
  153.                                     foreach (string key in bk.Keys)  
  154.                                     {  
  155.                                         if (key.Equals("Title"))  
  156.                                         {  
  157.                                             Title = Convert.ToString(bk[key]);  
  158.                                             i = i + 1;       
  159.                                             CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  160.                                             TextInfo textInfo = cultureInfo.TextInfo;   
  161.                                             Title = textInfo.ToTitleCase(Title);   
  162.                                            // counter = i;  
  163.                                         }  
  164.   
  165.                                         if (key.Equals("Kids"))  
  166.                                         {  
  167.                                             kids = (IList<Dictionary<stringobject>>)bk[key];  
  168.                                         }  
  169.                                         if (key.Equals("Page"))  
  170.                                         {  
  171.                                             //page = Convert.ToString(bk[key]).Split('');  
  172.   
  173.                                             string[] words = Convert.ToString(bk[key]).Split(' ');  
  174.                                             if (!object.Equals(words, null))  
  175.                                             {  
  176.                                                 page = Convert.ToInt32(words[0]);  
  177.                                             }                                             
  178.                                         }  
  179.                                     }   
  180.                                     if (!string.IsNullOrEmpty(Title))  
  181.                                     {                                       
  182.                                        // counter = counter + 1;   
  183.                                         PdfAction obja3lvl = PdfAction.GotoLocalPage(counter + page -1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  184.                                     PdfOutline objoutline3lvl = new PdfOutline(objoutline, obja3lvl, Title.ToString(), true);       
  185.                                     if (!object.Equals(kids, null))  
  186.                                     {  
  187.                                        // int j = i;  
  188.                                             foreach (Dictionary<stringobject> innerkids in kids)  
  189.                                             {   
  190.                                                 IList<Dictionary<stringobject>> kids2nd = null;  
  191.                                                 string Title2nd = string.Empty;  
  192.                                                 int page2 = 0;   
  193.                                                 foreach (string key in innerkids.Keys)  
  194.                                                 {  
  195.                                                     if (key.Equals("Title"))  
  196.                                                     {  
  197.                                                         Title2nd = Convert.ToString(innerkids[key]);  
  198.                                                         i = i + 1;     
  199.                                                         CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  200.                                                         TextInfo textInfo = cultureInfo.TextInfo;   
  201.                                                         Title2nd = textInfo.ToTitleCase(Title2nd);                                                          
  202.                                                     }   
  203.                                                     if (key.Equals("Kids"))  
  204.                                                     {  
  205.                                                         kids2nd = (IList<Dictionary<stringobject>>)innerkids[key];  
  206.                                                     }   
  207.                                                     if (key.Equals("Page"))  
  208.                                                     {                                                          
  209.                                                         string[] words = Convert.ToString(innerkids[key]).Split(' ');  
  210.                                                         if (!object.Equals(words, null))  
  211.                                                         {  
  212.                                                             page2 = Convert.ToInt32(words[0]);  
  213.                                                         }  
  214.                                                     }  
  215.                                                 }   
  216.   
  217.                                                 if (!string.IsNullOrEmpty(Title2nd))  
  218.                                                 {   
  219.                                                     PdfAction obja4lvl = PdfAction.GotoLocalPage(counter + page2 - 1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  220.                                                     PdfOutline objoutline4lvl = new PdfOutline(objoutline3lvl, obja4lvl, Title2nd.ToString(), true);       
  221.                                                     if (!object.Equals(kids2nd, null))  
  222.                                                     {  
  223.                                                       // int k = j;  
  224.                                                         foreach (Dictionary<stringobject> innerkids3rd in kids2nd)  
  225.                                                         {  
  226.   
  227.                                                             IList<Dictionary<stringobject>> kids3rd = null;  
  228.                                                             string Title3rd = string.Empty;  
  229.                                                             int page3 = 0;  
  230.                                                             foreach (string key in innerkids3rd.Keys)  
  231.                                                             {  
  232.                                                                 if (key.Equals("Title"))  
  233.                                                                 {  
  234.                                                                     Title3rd = Convert.ToString(innerkids3rd[key]);  
  235.                                                                     i = i + 1;     
  236.                                                                     CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;   
  237.                                                                     TextInfo textInfo = cultureInfo.TextInfo;   
  238.                                                                     Title3rd = textInfo.ToTitleCase(Title3rd);                                                                      
  239.                                                                 }  
  240.   
  241.                                                                 if (key.Equals("Kids"))  
  242.                                                                 {  
  243.                                                                     kids3rd = (IList<Dictionary<stringobject>>)innerkids3rd[key];  
  244.                                                                 }  
  245.                                                                 if (key.Equals("Page"))  
  246.                                                                 {  
  247.                                                                   //  page3 = Convert.ToInt32(innerkids3rd[key]);  
  248.   
  249.                                                                     string[] words = Convert.ToString(innerkids3rd[key]).Split(' ');  
  250.                                                                     if (!object.Equals(words, null))  
  251.                                                                     {  
  252.                                                                         page3 = Convert.ToInt32(words[0]);  
  253.                                                                     }  
  254.                                                                 }  
  255.                                                             }   
  256.   
  257.                                                             if (!string.IsNullOrEmpty(Title2nd))  
  258.                                                             {     
  259.                                                                 PdfAction obja5lvl = PdfAction.GotoLocalPage(counter + page3 - 1, new iTextSharp.text.pdf.PdfDestination(iTextSharp.text.pdf.PdfDestination.FITH), writer);   
  260.                                                                 PdfOutline objoutline5lvl = new PdfOutline(objoutline4lvl, obja5lvl, Title3rd.ToString(), true);  
  261.                                                             }       
  262.                                                         }  
  263.                                                     }         
  264.                                                 }       
  265.                                             }  
  266.                                         }                                       
  267.                                   }     
  268.                             }  
  269.   
  270.                             //*************End bookmark of pdf generation  
  271.                         }   
  272.   
  273.                         PdfImportedPage importedPage = writer.GetImportedPage(reader, currentPageIndex);   
  274.                         // Determine page orientation  
  275.                         int pageOrientation = reader.GetPageRotation(currentPageIndex);  
  276.                         if ((pageOrientation == 90) || (pageOrientation == 270))  
  277.                         {  
  278.                             content.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(currentPageIndex).Height);  
  279.                         }  
  280.                         else  
  281.                         {  
  282.                             content.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);  
  283.                         }   
  284.                     }  
  285.                     #endregion   
  286.                     //}   
  287.                 }     
  288.             }  
  289.             catch (IOException ex)  
  290.             {  
  291.                 throw new IOException(ex.Message);  
  292.             }  
  293.             catch (OutOfMemoryException ex)  
  294.             {  
  295.                 throw new OutOfMemoryException(ex.Message);  
  296.             }  
  297.             catch (Exception ex)  
  298.             {  
  299.                 throw new Exception(ex.Message);  
  300.             }  
  301.             finally  
  302.             {  
  303.                 document.Close();  
  304.             }   
  305.             return output.GetBuffer();  
  306.         }