2011-06-16 77 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