2012-11-15 24 views
1

我很努力地在多頁PDF上插入圖像。 要創建幾個頁面我正在使用PdfConcatenate,它的工作原理。我可以完美地添加我的模板頁面。當我嘗試添加圖像時,問題就開始了。它只是不加載它們。如何使用模板和連續頁面添加圖像到pdf

這裏的工程,以增加圖像的代碼:

 string pdfTemplate = @"Tools\template.pdf"; 
     string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf"); 

     FileStream output = new FileStream(targetPdfPath, FileMode.Create); 
     PdfConcatenate pdfConcatenate = new PdfConcatenate(output); 

     PdfReader pdfReader = new PdfReader(pdfTemplate); 
     MemoryStream memoryStream = getMemoryStream(output); 
     PdfStamper pdfStamper = new PdfStamper(pdfReader, output); 

     int cardIndex = 1; 

     foreach (Registry reg in registries) 
     { 
      setFields(reg, pdfStamper, cardIndex); 

      if (cardIndex == 4) 
      { 
       pdfConcatenate.AddPages(pdfReader); 
       pdfReader = new PdfReader(pdfTemplate); 
       pdfStamper = new PdfStamper(pdfReader, output); 

       cardIndex = 1; 
      } 
      else 
      { 
       cardIndex++; 
      } 
     } 

     //if (cardIndex != 1) 
     // pdfConcatenate.AddPages(pdfReader); 

     //make the form no longer editable 
     pdfStamper.FormFlattening = true; 

     pdfStamper.Close(); 
     pdfReader.Close(); 
     //pdfConcatenate.Close(); 

如果使用的MemoryStream爲PdfStamper並取消這些行:

//if (cardIndex != 1) 
// pdfConcatenate.AddPages(pdfReader); 
//pdfConcatenate.Close(); 

我把它添加頁面,但沒有圖像。

任何想法是什麼錯?

SOLUTION:(感謝@mkl)

 string pdfTemplate = @"Tools\template.pdf"; 
     string targetPdfPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), fileName + ".pdf"); 

     FileStream output = new FileStream(targetPdfPath, FileMode.Create); 
     PdfConcatenate pdfConcatenate = new PdfConcatenate(output); 

     PdfReader pdfReader = new PdfReader(pdfTemplate); 
     MemoryStream memoryStream = new MemoryStream(); 
     PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream); 

     int cardIndex = 1; 

     foreach (Registry reg in registries) 
     { 
      setFields(reg, pdfStamper, cardIndex); 

      if (cardIndex == 4) 
      { 
       pdfStamper.FormFlattening = true; 
       pdfStamper.Close(); 
       PdfReader tempReader = new PdfReader(memoryStream.ToArray()); 

       pdfConcatenate.AddPages(tempReader); 

       memoryStream = new MemoryStream(); 
       pdfReader = new PdfReader(pdfTemplate); 
       pdfStamper = new PdfStamper(pdfReader, memoryStream); 

       cardIndex = 1; 
      } 
      else 
      { 
       cardIndex++; 
      } 
     } 

     if (cardIndex != 1) 
     { 
      pdfStamper.FormFlattening = true; 
      pdfStamper.Close(); 
      PdfReader tempReader = new PdfReader(memoryStream.ToArray()); 

      pdfConcatenate.AddPages(tempReader); 

      tempReader.Close(); 
     } 

     pdfStamper.Close(); 
     pdfReader.Close(); 
     pdfConcatenate.Close(); 
+0

您有PdfConcatenate和未知數量的PdfStamper實例全都編寫相同的文件。如果你很幸運,那麼其中一個就會獲勝。否則,你會得到一些異常或垃圾。 – mkl

回答

2

最有可能的問題是如何PdfStamper作品的一些誤解。您似乎認爲它不知何故操縱了其印記的PdfReader中的數據,以及預先從該讀取器導出的頁面。這是而不是的情況下,PdfStamper根據閱讀器中的數據生成新的PDF文件(在其輸出流中),但閱讀器本身的內容未更新以反映所有更改(PdfReader對象可能是但是,在這個過程中觸及了這個過程,而且之後不可重用)。所以...

正如已經在評論中提到的那樣,您有PdfConcatenate和一個未知數的PdfStamper實例都會寫入相同的`FileStream'輸出。由於這些對象中的每一個都創建了一個獨立的PDF,如果其中一個獲勝,那麼您很幸運,因爲那樣您至少會得到一個合適的PDF作爲輸出。否則,你會得到一些異常或由多個混合PDF組成的垃圾。因此,僅使PdfConcatenate指向您的輸出文件。

如果您的實際意圖是重複填充,每次4張內容的模板領域和合並結果,你應該從模板的PdfReader頁面添加到PdfConcatenate ---網頁在那個讀者沒有填寫! ---而是將PdfStamper輸出到MemoryStream,填充其字段,平整其表單,關閉它,在新的PdfReader中打開其輸出,並將該閱讀器中的所有頁面添加到PdfConcatenate。

我不敢將它放入代碼,因爲我主要是使用Java和最有可能寫下未經測試的C#代碼將包括多個錯誤...;)

PS:目前你指望所有的PdfReader您打開的實例在某處隱式關閉。雖然目前情況確實如此,但最近iText SVN存儲庫中的簽入似乎表明,這些隱式關閉調用已從代碼中刪除。因此,也請開始明確關閉您不再使用的實例PdfReader。否則,由於讀者太晚關閉,您將很快不得不處理內存泄漏。

+1

我upvoted這個答案,我想從代碼中刪除的問題,否則我會downvote它,因爲我不希望其他人閱讀本和複製代碼是完全錯誤的; eestein應該首先閱讀:http://www.manning.com/lowagie2/samplechapter6.pdf –

+0

感謝您的回答。我真的想重複每次填充模板併合並結果。我有一個PDF格式的模板,但生成的PDF可能包含多個頁面,而不僅僅是一個。而且我遇到了麻煩。我現在正在研究你的方法,並返回結果。再次感謝。 – eestein

+0

@BrunoLowagie感謝您的書籍​​樣本鏈接,我會研究這一點。關於問題中的代碼,這是一個問題,而不是答案,它不應該被視爲正確。 – eestein

相關問題