.NET 7 Web API使用iText7 8.0.1生成PDF时流关闭异常问题
iText 8 生成PDF时流关闭异常与文件损坏问题解决
问题代码
[HttpGet("generar")] public IActionResult GenerarPdf() { // 创建MemoryStream用于写入PDF内容 using (MemoryStream stream = new MemoryStream()) { // 使用iText 8创建PDF文档 PdfWriter writer = new PdfWriter(stream); PdfDocument pdf = new PdfDocument(writer); Document document = new Document(pdf); // 向PDF添加内容 document.Add(new Paragraph("Hello, this is a PDF generated from ASP.NET Core with iText 8.")); // 设置HTTP响应的内容类型 Response.Headers.Add("Content-Disposition", "attachment; filename=example.pdf"); // 将"inline"改为"attachment"可触发下载 Response.ContentType = "application/pdf"; // 关闭文档 document.Close(); // 将流指针重置到起始位置 stream.Seek(0, SeekOrigin.Begin); // 返回PDF文件 return File(stream.ToArray(), "application/pdf"); } }
问题描述
- 保留
document.Close()时,执行stream.Seek(0, SeekOrigin.Begin)会抛出**“无法访问已关闭的流”**异常; - 移除
document.Close()时,PDF可下载但文件损坏。 - 使用iText版本:8.0.1
问题根源
document.Close()会逐层触发PdfDocument、PdfWriter的关闭操作,默认情况下PdfWriter会自动关闭它关联的底层MemoryStream,导致后续无法操作流;而如果不关闭document,iText不会将PDF的完整结构(如文件尾、交叉引用表等关键内容)写入流,生成的PDF因不完整而损坏。
解决方法
通过配置PdfWriter禁止其自动关闭底层流,这样在document.Close()完成PDF内容的完整写入后,仍能正常操作MemoryStream。
修改后的完整代码:
[HttpGet("generar")] public IActionResult GenerarPdf() { using (MemoryStream stream = new MemoryStream()) { // 配置PdfWriter不自动关闭关联的流 PdfWriter writer = new PdfWriter(stream, new WriterProperties().SetCloseStream(false)); PdfDocument pdf = new PdfDocument(writer); Document document = new Document(pdf); document.Add(new Paragraph("Hello, this is a PDF generated from ASP.NET Core with iText 8.")); // 关闭文档,确保所有PDF内容写入流 document.Close(); // 重置流指针到起始位置 stream.Seek(0, SeekOrigin.Begin); // 直接通过File方法设置响应头并返回文件,无需手动操作Response.Headers return File(stream.ToArray(), "application/pdf", "example.pdf"); } }
说明
WriterProperties().SetCloseStream(false):核心配置,阻止PdfWriter关闭底层MemoryStream;- 必须调用
document.Close():确保iText完成PDF的所有写入操作,生成完整的PDF文件; - 使用
File方法的重载版本:直接指定文件名,ASP.NET Core会自动设置正确的Content-Disposition响应头,无需手动添加。
内容的提问来源于stack exchange,提问作者Alexis252
相关产品推荐
相关产品推荐

