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 コンテンツを新しいドキュメントに追加する必要があります。これは、これを実行する最良または最も効率的な方法ではない可能性があります。

これは、 からの元の PDF で動作しStream、マージされた出力を別の として生成し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の例 StampText.csから恥知らずにコピーされました)

追加の背景情報については、iText in Action —2ndEditionの無料サンプル第6をお読みください。

于 2013-02-26T10:46:23.120 に答える