VB.Net使用iText生成PDF报错:Trailer not found (iText.Kernel.PdfException)
VB.Net iText PDF生成:解决“Trailer not found”和“ObjectDisposedException”异常
问题根源
- Trailer not found:PdfDocument尚未完成PDF内容的写入与刷新就读取MemoryStream,导致流内没有完整的PDF结构。
- ObjectDisposedException:默认情况下,iText的
PdfDocument关闭时会自动关闭关联的MemoryStream,提前关闭文档后再读取流就会触发该异常。
修复方案
核心是正确管理PdfDocument和MemoryStream的生命周期,避免流被提前释放,同时确保PDF内容完全写入流后再读取。
1. 关键配置:禁用PdfWriter自动关闭流
创建PdfWriter时设置CloseStream = False,这样关闭PdfDocument时不会连带关闭MemoryStream,保留流供后续读取。
2. 正确的代码执行顺序
完成表单填充、扁平化操作后,等待PdfDocument完成写入(利用Using块自动处理),再重置流位置到起始点,最后读取流内容。
VB.Net 完整示例代码
' 外层Using管理MemoryStream,确保最终自动释放 Using oMemoryStream As New MemoryStream() ' 根据语言选择对应模板路径 Dim oTemplatePath As String = If(language = "en", "template_en.pdf", "template_zh.pdf") Dim oReader As New PdfReader(oTemplatePath) ' 创建PdfWriter,设置CloseStream=False避免关闭文档时关闭流 Dim oWriter As New PdfWriter(oMemoryStream) With {.CloseStream = False} ' Using块管理PdfDocument,确保自动完成写入和flush Using oPDF_Document_Form_Filled_Out As New PdfDocument(oReader, oWriter) ' 获取表单并填充字段 Dim oAcroForm As PdfAcroForm = PdfAcroForm.GetAcroForm(oPDF_Document_Form_Filled_Out, True) ' 示例:填充具体字段 oAcroForm.GetField("UserName").SetValue("张三") oAcroForm.GetField("Email").SetValue("zhangsan@example.com") ' 扁平化表单 oAcroForm.FlattenFields() ' 显式调用Flush确保所有内容写入流(可选,但更稳妥) oPDF_Document_Form_Filled_Out.Flush() End Using ' 此处PdfDocument关闭,但MemoryStream仍可用 ' 重置流位置到起始点,否则读取会从流末尾开始 oMemoryStream.Position = 0 ' 后续读取操作示例:保存到文件 Using oFileStream As New FileStream("output.pdf", FileMode.Create, FileAccess.Write) oMemoryStream.CopyTo(oFileStream) End Using ' 或者将流转换为字节数组返回(比如Web场景) ' Dim pdfBytes As Byte() = oMemoryStream.ToArray() End Using
额外注意事项
- 必须在
PdfDocument的Using块结束后再操作MemoryStream,因为Using块结束时iText会完成PDF的最终写入和资源清理。 - 若跳过重置
Position,读取流时会从当前位置(流末尾)开始,读取到空内容,进而触发“Trailer not found”异常。 - 确保模板PDF本身是有效的可填充表单,损坏的模板也可能导致类似异常。
内容的提问来源于stack exchange,提问作者Jojaweb
相关产品推荐
相关产品推荐

