2011-06-16 158 views
6

下面的代碼片段返回一個損壞的PDF文檔,但是如果我返回mergedDocument,它總是返回一個有效的PDF。 mergedDocument基於我使用Word創建的PDF文件,而完整的文檔完全是以編程方式生成的。代碼「起作用」,因爲它不會引發異常。爲什麼iTextSharp創建一個損壞的PDF?iTextSharp正在生成損壞的PDF

byte[] completedDocument = null;    
using (MemoryStream streamCompleted = new MemoryStream()) 
{ 
    using (Document document = new Document()) 
    {      
     PdfCopy copy = new PdfCopy(document, streamCompleted); 
     document.Open(); 
     copy.Open();      

     foreach (var item in eventItems) 
     { 
      byte[] mergedDocument = null; 
      PdfReader reader = new PdfReader(pdfTemplates[item.DataTokens[NotifyTokenType.OrganisationID]]); 
      using (MemoryStream streamTemplate = new MemoryStream()) 
      { 
       using (PdfStamper stamper = new PdfStamper(reader, streamTemplate)) 
       { 
        foreach (var token in item.DataTokens) 
        { 
         if (stamper.AcroFields.Fields.Any(fld => fld.Key == token.Key.ToString())) 
         { 
          stamper.AcroFields.SetField(token.Key.ToString(), token.Value); 
         } 
        } 
        stamper.FormFlattening = true; 
        stamper.Writer.CloseStream = false; 
       } 

       mergedDocument = new byte[streamTemplate.Length]; 
       streamTemplate.Position = 0; 
       streamTemplate.Read(mergedDocument, 0, (int)streamTemplate.Length); 
      } 
      reader = new PdfReader(mergedDocument); 

      for (int i = 1; i <= reader.NumberOfPages; i++) 
      { 
       document.SetPageSize(PageSize.A4); 
       copy.AddPage(copy.GetImportedPage(reader, i)); 
      } 
     } 
     completedDocument = new byte[streamCompleted.Length]; 
     streamCompleted.Position = 0; 
     streamCompleted.Read(completedDocument, 0, (int)streamCompleted.Length); 
    }     
} 
return completedDocument; 

回答

20

您需要關閉documentcopy對象刷新PDF寫入緩衝器。然而,這在嘗試將數據流讀入數組時會導致一些問題。解決方法是使用MemoryStreamToArray()方法,該方法仍然適用於封閉流。我所做的更改對它們有評論。

 byte[] completedDocument = null; 
     using (MemoryStream streamCompleted = new MemoryStream()) 
     { 
      using (Document document = new Document()) 
      { 
       PdfCopy copy = new PdfCopy(document, streamCompleted); 
       document.Open(); 
       copy.Open(); 

       foreach (var item in eventItems) 
       { 
        byte[] mergedDocument = null; 
        PdfReader reader = new PdfReader(pdfTemplates[item.DataTokens[NotifyTokenType.OrganisationID]]); 
        using (MemoryStream streamTemplate = new MemoryStream()) 
        { 
         using (PdfStamper stamper = new PdfStamper(reader, streamTemplate)) 
         { 
          foreach (var token in item.DataTokens) 
          { 
           if (stamper.AcroFields.Fields.Any(fld => fld.Key == token.Key.ToString())) 
           { 
            stamper.AcroFields.SetField(token.Key.ToString(), token.Value); 
           } 
          } 
          stamper.FormFlattening = true; 
          stamper.Writer.CloseStream = false; 
         } 
         //Copy the stream's bytes 
         mergedDocument = streamTemplate.ToArray(); 
        } 
        reader = new PdfReader(mergedDocument); 

        for (int i = 1; i <= reader.NumberOfPages; i++) 
        { 
         document.SetPageSize(PageSize.A4); 
         copy.AddPage(copy.GetImportedPage(reader, i)); 
        } 
        //Close the document and the copy 
        document.Close(); 
        copy.Close(); 
       } 
       //ToArray() can operate on closed streams 
       completedDocument = streamCompleted.ToArray(); 
      } 
     } 
     return completedDocument; 
+2

謝謝你這麼多,做的伎倆。 – 2011-06-17 15:25:03

+0

如果可以的話,我會加倍努力。我很難將圖像和PDF合併到一個PDF文檔中,這有助於瞭解正確的過程。 – jtiger 2015-04-10 20:22:24

+0

謝謝你,把內存流陣列解決了我的問題,回來空的PDF文件! – Taurib 2017-10-26 11:56:01

0

另外,還要確保你的HTML不包含小時標籤在轉換HTML到PDF

hdnEditorText.Value.Replace("\"", "'").Replace("<hr />", "").Replace("<hr/>", "") 
+0

爲什麼?有一個hr標籤有什麼問題? – Kevin 2017-06-20 14:30:27