2

将项目添加到现有 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());
4

2 回答 2

5

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

这适用于来自 a 的原始 PDF Stream,并将合并的输出生成为 another 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);
}
于 2013-02-25T22:05:20.230 回答
3

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

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 Example Concatenate.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 Example StampText.cs复制)

有关其他背景信息,请阅读iText in Action — 第 2 版的免费示例第 6章。

于 2013-02-26T10:46:23.120 回答