【问题标题】:Merging pdf files with bookmarks将 pdf 文件与书签合并
【发布时间】:2012-04-28 13:42:51
【问题描述】:

我正在尝试合并很多 pdf,并且我想为每个 pdf 添加书签(pdf 的名称),我发现了不同的合并 pdf 的技术,但它们都不能只添加书签,例如。 itextsharp 添加一章,然后是该章的书签,我不想更改 pdf 的。

【问题讨论】:

  • 也许您需要提取各个页面并将它们重新组合成一个文件。这样你就可以用书签标记每个 pdf 的第一页
  • 我不知道如何添加一个简单的书签

标签: c# pdf merge itext pdf-generation


【解决方案1】:

使用 itextsharp 你可以做到。我是通过以下方法做到的:

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();
}

【讨论】:

  • 运行此代码并合并 pdf,但它没有添加书签。初始 pdf 文件需要有书签才能在最终 pdf 中显示。
  • 只需要对这段代码说声谢谢!过去几天我一直在网上冲浪,直到我刚刚偶然发现了这一点。再次感谢!
  • 好的,经过一段时间的搜索,我偶然发现了这段代码,完美运行!
【解决方案2】:

尝试Docotic.Pdf library 完成任务。

这是一个执行您所描述的示例代码:

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");
    }
}

该示例将不同的文档组合成一个 PDF 并创建书签。每个书签都指向原始文档的第一页。

免责声明:我为开发 Docotic.Pdf 库的公司工作。

【讨论】:

    【解决方案3】:
    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;
    }
    

    我优化了Md Kamruzzaman Sarker 的答案,方法是使用 foreach 循环遍历 pdf 和 using 语句。像这样在我看来它看起来更干净,但所有功劳都归他所有。

    【讨论】:

      猜你喜欢
      • 2017-03-29
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 2018-06-27
      相关资源
      最近更新 更多