【问题标题】:Add items to existing PDF with iTextSharp使用 iTextSharp 将项目添加到现有 PDF
【发布时间】:2013-02-10 23:56:03
【问题描述】:

向现有 PDF 添加项目的正确方法是什么? GetFileBytes 方法 从磁盘读取 PDF 并转换为数组,这工作正常,但是 结果文件 NP.PDF 与原始文件完全相同。我其实想 添加条形码,但想先尝试让它与一个简单的项目一起工作。

Byte[] bytes = GetFileBytes();

Document document = new Document();
MemoryStream ms = new MemoryStream(bytes);

PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();

document.Add(new Paragraph("First Paragraph"));
document.Add(new Paragraph("Second Paragraph"));
//document.Close();
ms.Position = 0;

File.WriteAllBytes(@"e:\NP.pdf", (Byte[])ms.ToArray());

【问题讨论】:

    标签: itextsharp paragraph


    【解决方案1】:

    这就是我过去的做法。您需要为 PDF 编写器使用新的流,并将原始 PDF 内容添加到新文档中。这可能不是执行此操作的最佳或最有效的方法,这正是我发现的方法。

    这适用于我来自Stream 的原始 PDF,并将合并的输出生成为另一个 Stream,但是您应该能够根据您的需要对其进行调整。

    var originalPdfStream = GetOriginalPdfStream();
    var pdfDocument = Document();
    var finalPdfStream = new MemoryStream();
    var pdfWriter = PdfWriter.GetInstance(pdfDocument, finalPdfStream);
    
    pdfDocument.Open();
    
    // Add the originalPdfStream into the pdfDocument
    var originalPdfReader = new PdfReader(originalPdfStream);
    AddPdf(document, writer, reader);
    
    // Code to add other items to the pdfDocument.
    
    
    pdfWriter.CloseStream = false;
    pdfDocument.Close();
    finalPdfStream.Position = 0;
    
    return finalPdfStream;
    

    然后,以下方法将您的文档和编写器以及阅读器带到您要添加的文档。

    /// <summary>
    /// Merge a PDF file into a PDF document.
    /// </summary>
    /// <param name="document">The PDF document.</param>
    /// <param name="writer">The PDF writer.</param>
    /// <param name="reader">A PDF reader.</param>
    private static void AddPdf(Document document, PdfWriter writer, PdfReader reader)
    {
        if (document == null) throw new ArgumentNullException("document");
        if (writer == null) throw new ArgumentNullException("writer");
        if (reader == null) throw new ArgumentNullException("reader");
    
        var numberOfPages = reader.NumberOfPages;
        var originalPageSize = document.PageSize;
    
        // Iterate through all pages
        for (var currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
        {
            // Determine page size for the current page
            document.SetPageSize(reader.GetPageSizeWithRotation(currentPageIndex));
    
            // Create page
            document.NewPage();
            var importedPage = writer.GetImportedPage(reader, currentPageIndex);
    
            // Determine page orientation and add page.
            var pageRotation = reader.GetPageRotation(currentPageIndex);
            var pageWidth = reader.GetPageSizeWithRotation(currentPageIndex).Width;
            var pageHeight = reader.GetPageSizeWithRotation(currentPageIndex).Height;
            switch (pageRotation)
            {
                case 0:
                    writer.DirectContent.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
                    break;
    
                case 90:
                    writer.DirectContent.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, pageHeight);
                    break;
    
                case 180:
                    writer.DirectContent.AddTemplate(
                        importedPage, -1f, 0, 0, -1f, pageWidth, pageHeight);
                    break;
    
                case 270:
                    writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
                    break;
    
                default:
                    throw new Exception("Unexpected page rotation: [{0}].", pageRotation);
            }
        }
    
        document.SetPageSize(originalPageSize);
    }
    

    【讨论】:

    • 感谢您的信息。但是,当它在 MemoryStream 中时,如何将现有的 pdfstream 添加到文档中?
    • 谢谢,如果这对您有任何帮助,您介意投票吗:)
    • 我在你发布后尝试投票,但是我的声誉不够高:-(
    • 如何使用 itextsharp 提取 pdf 文件中每个段落的粗体文本?
    【解决方案2】:

    只要添加的内容仅在新页面上(如您的示例代码所示),您就可以像创建新的中间 PDF 一样创建添加内容(如果不是太大,它可以驻留在内存中)并且然后使用PdfCopy连接PDF:

    using (MemoryStream ms = new MemoryStream()) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        using (PdfCopy copy = new PdfCopy(document, ms)) {
          // step 3
          document.Open();
          // step 4
          for (int i = 0; i < pdf.Count; ++i) {
            PdfReader reader = ...;// retrieve a PdfReader for the i'th PDF to concatenate
            // loop over the pages in that document
            int n = reader.NumberOfPages;
            for (int page = 0; page < n; ) {
              copy.AddPage(copy.GetImportedPage(reader, ++page));
            }
          }
        }
      }
      byte[] data = ms.ToArray();
      ...
    }
    

    (无耻抄袭Webified iTextSharp ExampleConcatenate.cs

    另一方面,如果您想在现有页面上标记某些内容,则更有可能需要PdfStamper

    PdfReader reader = new PdfReader(resource);
    using (var ms = new MemoryStream()) {
      using (PdfStamper stamper = new PdfStamper(reader, ms)) {
        PdfContentByte canvas = stamper.GetOverContent(1);
        ColumnText.ShowTextAligned(
          canvas,
          Element.ALIGN_LEFT, 
          new Phrase("Hello people!"), 
          36, 540, 0
        );
      }
      byte[] data = ms.ToArray();
      ...
    }
    

    (还无耻抄袭Webified iTextSharp ExampleStampText.cs

    有关更多背景信息,请阅读iText in Action — 2nd Edition 的免费示例chapter 6

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多