iTextSharp的是生产一个腐败的PDF的是、腐败、iTextSharp、PDF

2023-09-04 10:13:25 作者:哥丶看破繁华@

在code段下方返回一个腐败的PDF文档,但是如果我回到mergedDocument相反,它总是返回一个有效的PDF文件。 mergedDocument是根据我使用Word创建的PDF文件,而完成的文档完全是程序生成。在code作品,因为它没有抛出异常。为什么iTextSharp的创建一个腐败的PDF文件?

 字节[] completedDocument = NULL;
使用(MemoryStream的streamCompleted =新的MemoryStream())
{
    使用(文档文件=新的文件())
    {
        PdfCopy复制=新PdfCopy(文件,streamCompleted);
        document.Open();
        copy.Open();

        的foreach(在eventItems VAR项)
        {
            byte []的mergedDocument = NULL;
            PdfReader读卡器=新PdfReader(pdfTemplates [item.DataTokens [NotifyTokenType.OrganisationID]);
            使用(MemoryStream的streamTemplate =新的MemoryStream())
            {
                使用(PdfStamper压模=新PdfStamper(读卡器,streamTemplate))
                {
                    的foreach(在item.DataTokens VAR令牌)
                    {
                        如果(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 =新的字节[streamTemplate.Length]
                streamTemplate.Position = 0;
                streamTemplate.Read(mergedDocument,0,(int)的streamTemplate.Length);
            }
            读者=新PdfReader(mergedDocument);

            的for(int i = 1; I< = reader.NumberOfPages;我++)
            {
                document.SetPageSize(PageSize.A4);
                copy.AddPage(copy.GetImportedPage(读者,我));
            }
        }
        completedDocument =新的字节[streamCompleted.Length]
        streamCompleted.Position = 0;
        streamCompleted.Read(completedDocument,0,(int)的streamCompleted.Length);
    }
}
返回completedDocument;
 

解决方案

您需要关闭文件复制对象刷新PDF写入缓冲器。然而,这试图读取该流为一个阵列时会导致一些问题。该解决方法是使用的的ToArray()方法的MemoryStream 仍然适用于封闭的流。这些变化我做有意见他们。

 字节[] completedDocument = NULL;
        使用(MemoryStream的streamCompleted =新的MemoryStream())
        {
            使用(文档文件=新的文件())
            {
                PdfCopy复制=新PdfCopy(文件,streamCompleted);
                document.Open();
                copy.Open();

                的foreach(在eventItems VAR项)
                {
                    byte []的mergedDocument = NULL;
                    PdfReader读卡器=新PdfReader(pdfTemplates [item.DataTokens [NotifyTokenType.OrganisationID]);
                    使用(MemoryStream的streamTemplate =新的MemoryStream())
                    {
                        使用(PdfStamper压模=新PdfStamper(读卡器,streamTemplate))
                        {
                            的foreach(在item.DataTokens VAR令牌)
                            {
                                如果(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 = streamTemplate.ToArray();
                    }
                    读者=新PdfReader(mergedDocument);

                    的for(int i = 1; I< = reader.NumberOfPages;我++)
                    {
                        document.SetPageSize(PageSize.A4);
                        copy.AddPage(copy.GetImportedPage(读者,我));
                    }
                    //关闭文档和复印件
                    document.Close();
                    copy.Close();
                }
                //的ToArray()可以在封闭的流操作
                completedDocument = streamCompleted.ToArray();
            }
        }
        返回completedDocument;
 
内蒙煤炭生产恢复到年产10亿吨水平,云南开始倒查煤炭领域腐败

The code snippet below returns a corrupt PDF document however if I return mergedDocument instead it always returns a valid PDF. mergedDocument is based on a PDF file i created using Word, whereas completed document is entirely programmatically generated. The code "works" in that it throws no exceptions. Why is iTextSharp creating a corrupt 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;

解决方案

You need to close the document and copy objects to flush the PDF writing buffer. This, however, causes some problems when trying to read the stream into an array. The fix for that is to use the ToArray() method of the MemoryStream which still works on closed streams. The changes I made have comments on them.

        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;