2013-02-25 56 views
2

將項目添加到現有PDF的正確方法是?方法GetFileBytes 從磁盤讀取PDF並將其轉換爲數組,但此工作正常,但 生成的文件NP.PDF與原始文件完全相同。我其實想要 添加條形碼,但想到試着讓它與一個簡單的項目第一次工作。使用iTextSharp將項目添加到現有的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()); 

回答

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); 
} 
+0

感謝您的信息。當你在MemoryStream中時,如何將現有的pdfstream添加到文檔中? – Dave 2013-02-26 09:28:29

+0

已更新答案。 – TimS 2013-02-26 21:50:11

+0

很好的例子,謝謝你。 – Dave 2013-02-27 08:37:15

3

只要添加的內容應是在新的頁面只(如您的示例代碼似乎表明),你可以像創建一個新的中間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

複製如果,另一方面,要杜絕小號omething現有頁面上,你很可能需要一個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 Editionchapter 6

+0

非常感謝您的信息,現在所有人都在工作。 – Dave 2013-02-26 17:13:42