简体   繁体   中英

Merging pdf files with bookmarks

I'm trying to merge a lot of pdf's and for each pdf I want to add a bookmark(the name of the pdf), I found difrent techniques of merging pdf's but none of them can add only the bookmark fore eg. itextsharp add's a chapter, then the bookmark for the chapter, i don't want to alter the pdf's.

Using itextsharp you can do it. I do it by the following method:

MergePdfFiles(string outputPdf, string[] sourcePdfs) {
    PdfReader reader = null;
    Document document = new Document();
    PdfImportedPage page = null;
    PdfCopy pdfCpy = null;
    int n = 0;
    int totalPages = 0;
    int page_offset = 0;
    List < Dictionary < string, object >> bookmarks = new List < Dictionary < string, object >> ();
    IList < Dictionary < string, object >> tempBookmarks;
    for (int i = 0; i <= sourcePdfs.GetUpperBound(0); i++) {
        reader = new PdfReader(sourcePdfs[i]);
        reader.ConsolidateNamedDestinations();
        n = reader.NumberOfPages;
        tempBookmarks = SimpleBookmark.GetBookmark(reader);
        if (i == 0) {
            document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
            pdfCpy = new PdfCopy(document, new FileStream(outputPdf, FileMode.Create));
            document.Open();
            SimpleBookmark.ShiftPageNumbers(tempBookmarks, page_offset, null);
            page_offset += n;
            if (tempBookmarks != null)
                bookmarks.AddRange(tempBookmarks);
            //  MessageBox.Show(n.ToString());
            totalPages = n;
        } else {
            SimpleBookmark.ShiftPageNumbers(tempBookmarks, page_offset, null);
            if (tempBookmarks != null)
                bookmarks.AddRange(tempBookmarks);
            page_offset += n;
            totalPages += n;
        }
        for (int j = 1; j <= n; j++) {
            page = pdfCpy.GetImportedPage(reader, j);
            pdfCpy.AddPage(page);
        }
        reader.Close();
    }
    pdfCpy.Outlines = bookmarks;
    document.Close();
}

Try Docotic.Pdf library for the task.

Here is a sample code that does what you described:

public static void combineDocumentsWithBookmarks()
{
    string[] names = new string[] { "first.pdf", "second.pdf", "third.pdf" };

    using (PdfDocument pdf = new PdfDocument())
    {
        int targetPageIndex = 0;
        for (int i = 0; i < names.Length; i++)
        {
            string currentName = names[i];
            
            if (i == 0)
                pdf.Open(currentName);
            else
                pdf.Append(currentName);

            pdf.OutlineRoot.AddChild(currentName, targetPageIndex);
            targetPageIndex = pdf.PageCount;
        }

        // setting PageMode will cause PDF viewer to display
        // bookmarks pane when document is open
        pdf.PageMode = PdfPageMode.UseOutlines;
        pdf.Save("output.pdf");
    }
}

The sample combines different documents into one PDF and creates bookmarks. Each bookmark points to the first page of original document.

Disclaimer: I work for the company that develops Docotic.Pdf library.

public string MergeFiles(string outputPath)
{
    if (string.IsNullOrEmpty(outputPath))
        throw new NullReferenceException("Path for output document is null or empty.");

    using (Document outputDocument = new Document())
    {
        using (PdfCopy pdf = new PdfCopy(outputDocument, new FileStream(outputPath, FileMode.Create)))
        {
            outputDocument.Open();
            // All bookmarks for output document
            List<Dictionary<string, object>> bookmarks = new List<Dictionary<string, object>>();
            // Bookmarks of the current document
            IList<Dictionary<string, object>> tempBookmarks;
            int pageOffset = 0;

            // Merge documents and add bookmarks
            foreach (string file in Files)
            {
                using (PdfReader reader = new PdfReader(file))
                {
                    reader.ConsolidateNamedDestinations();
                    // Get bookmarks of current document
                    tempBookmarks = SimpleBookmark.GetBookmark(reader);

                    SimpleBookmark.ShiftPageNumbers(tempBookmarks, pageOffset, null);

                    pageOffset += reader.NumberOfPages;

                    if(tempBookmarks != null)
                        // Add bookmarks of current document to all bookmarks 
                        bookmarks.AddRange(tempBookmarks);

                    // Add every page of document to output document
                    for (int i = 1; i <= reader.NumberOfPages; i++)
                        pdf.AddPage(pdf.GetImportedPage(reader, i));
                 }
             }

             // Add all bookmarks to output document
             pdf.Outlines = bookmarks;
         }
    }

    return outputPath;
}

I optimised Md Kamruzzaman Sarker's answer by using a foreach loop to go over the pdfs and using statements. Like this it looks cleaner to me but all credits goes to him.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM