使用iText7合并PDF时出现Object reference空引用异常求助
iText7合并PDF触发空引用异常的排查与解决
问题背景
原PDF合并功能运行正常,新增SetUnethicalReading(true)以绕过所有者密码校验后,触发空引用异常。待合并PDF外观无异常,字节数据充足,merger和pdf实例均非空。
相关代码
var sr1 = new MemoryStream(data); rdr = new PdfReader(sr1); rdr.SetUnethicalReading(true); pdf = new PdfDocument(rdr); var pages = pdf.GetNumberOfPages(); merger.Merge(pdf, 1, pages);
异常栈信息
System.NullReferenceException: Object reference not set to an instance of an object. at iText.Kernel.Pdf.PdfOutline..ctor(String title, PdfDictionary content, PdfOutline parent) at iText.Kernel.Pdf.PdfCatalog.ConstructOutlines(PdfDictionary outlineRoot, IDictionary`2 names) at iText.Kernel.Pdf.PdfCatalog.GetOutlines(Boolean updateOutlines) at iText.Kernel.Pdf.PdfDocument.GetOutlines(Boolean updateOutlines) at iText.Kernel.Pdf.PdfPage.GetOutlines(Boolean updateOutlines) at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument, Int32 insertBeforePage, IPdfPageExtraCopier copier) at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument, IPdfPageExtraCopier copier) at iText.Kernel.Pdf.PdfDocument.CopyPagesTo(IList`1 pagesToCopy, PdfDocument toDocument) at iText.Kernel.Utils.PdfMerger.Merge(PdfDocument from, IList`1 pages) at iText.Kernel.Utils.PdfMerger.Merge(PdfDocument from, Int32 fromPage, Int32 toPage)
原因分析
异常发生在PDF大纲(PdfOutline)构造阶段,说明待合并的PDF存在损坏的内部大纲结构——虽然PDF显示正常,但大纲字典存在缺失或无效条目。开启SetUnethicalReading后,iText跳过了部分完整性校验,直接读取原本受保护的内容,导致原本被隐藏的结构缺陷暴露,触发空引用。
解决方案
1. 合并时跳过大纲复制
通过PdfMergerProperties禁用大纲合并,避免处理损坏的大纲结构:
// 初始化merger时配置跳过大纲合并 var mergerProps = new PdfMergerProperties().SetMergeOutlines(false); var merger = new PdfMerger(targetPdfDocument, mergerProps); // 后续合并逻辑不变 var sr1 = new MemoryStream(data); using (var rdr = new PdfReader(sr1)) { rdr.SetUnethicalReading(true); using (var pdf = new PdfDocument(rdr)) { merger.Merge(pdf, 1, pdf.GetNumberOfPages()); } }
2. 修复源PDF的损坏大纲
先移除源PDF中无效的大纲结构,再进行合并:
using (var fixedStream = new MemoryStream()) { // 修复源PDF,移除损坏大纲 var reader = new PdfReader(new MemoryStream(data)); reader.SetUnethicalReading(true); using (var fixedDoc = new PdfDocument(reader, new PdfWriter(fixedStream))) { fixedDoc.GetCatalog().Remove(PdfName.Outlines); } // 使用修复后的PDF执行合并 fixedStream.Position = 0; using (var fixedReader = new PdfReader(fixedStream)) { using (var fixedPdf = new PdfDocument(fixedReader)) { merger.Merge(fixedPdf, 1, fixedPdf.GetNumberOfPages()); } } }
3. 升级iText7到最新版本
新版本iText7可能已优化对异常PDF结构的处理逻辑,修复了此类边缘场景的空引用问题。
内容的提问来源于stack exchange,提问作者Daniel Williams
相关产品推荐
相关产品推荐

