使用C#评估iText7:内存生成PDF写入文件报错求助
解决iText7生成PDF时“Cannot access a closed Stream”异常及无效PDF问题
我来帮你搞定这个矛盾的问题——你遇到的情况完全是iText7的设计逻辑导致的:关闭Document会自动连锁关闭关联的内存流,但不关闭的话,iText又不会完成PDF的核心结构写入(比如交叉引用表、文件尾标记),导致文件无效。下面给你两种可靠的解决方案:
方案1:配置PdfWriter不自动关闭底层流
iText7默认会在关闭PdfDocument/Document时关闭关联的输出流,我们可以通过WriterProperties修改这个行为,这样关闭文档后还能继续使用内存流:
// 修正冗余的流创建,C#里用MemoryStream而非Java的ByteArrayOutputStream var pdfMemoryStream = new MemoryStream(); // 创建WriterProperties,设置不自动关闭底层流 var writerProperties = new WriterProperties().SetCloseStream(false); var pdfWriter = new PdfWriter(pdfMemoryStream, writerProperties); var pdfDocument = new PdfDocument(pdfWriter); var document = new Document(pdfDocument, PageSize.LETTER, true); // 添加内容到文档 document.Add(new Paragraph("Testing")); // 关闭文档(此时不会关闭内存流) document.Close(); pdfDocument.Close(); // 显式关闭PdfDocument,确保所有内容都写入流 // 重置流指针到起始位置,否则写入的是空内容 pdfMemoryStream.Position = 0; // 写入到物理文件 using var fstream = new FileStream(@"C:\publish\iTextQuoteM.pdf", FileMode.Create); pdfMemoryStream.CopyTo(fstream); // 最后手动关闭内存流 pdfMemoryStream.Close();
关键细节:
- 移除了你代码里重复创建
pdfMemoryStream的冗余行(第1、2行重复初始化了流) SetCloseStream(false)是核心配置,让PdfWriter不会随文档关闭而关闭内存流- 关闭文档后一定要重置流的位置到0,否则后续写入操作会从流的末尾开始,导致内容为空
方案2:在关闭文档前提取PDF字节数组
另一种更稳妥的方式是,在关闭文档前先把内存流的内容提取为字节数组,这样即使流被关闭,我们依然持有完整的PDF数据:
var pdfMemoryStream = new MemoryStream(); var pdfWriter = new PdfWriter(pdfMemoryStream); var pdfDocument = new PdfDocument(pdfWriter); var document = new Document(pdfDocument, PageSize.LETTER, true); document.Add(new Paragraph("Testing")); // 关闭PdfDocument触发所有内容写入流,然后提取字节数组 pdfDocument.Close(); byte[] pdfBytes = pdfMemoryStream.ToArray(); // 用字节数组写入文件或返回给客户端 using var fstream = new FileStream(@"C:\publish\iTextQuoteM.pdf", FileMode.Create); fstream.Write(pdfBytes, 0, pdfBytes.Length);
问题根源复盘:
- 你代码里第7行
document.Close()会触发PdfDocument.Close(),进而让PdfWriter关闭关联的pdfMemoryStream,所以第9行写入时会报“无法访问已关闭的流” - 如果不关闭
Document,iText不会写入PDF的关键结构,生成的文件缺少必要的标识,自然无法被阅读器识别
另外注意:C#版本的iText7应该使用MemoryStream,你代码里的ByteArrayOutputStream是Java版的API,换成MemoryStream才能正常工作。
内容的提问来源于stack exchange,提问作者RobertT
相关产品推荐
相关产品推荐

