使用iText7填充XFA PDF后执行扁平化操作出现报错求助
问题:XFA PDF填充后扁平化抛出"AbstractITextEvent is only for internal usage"异常
背景
我通过XML填充可填写PDF的XFA表单,能正常生成已填充内容的只读PDF,代码如下:
var pdfReader = new PdfReader(@"C:\Temp\2.pdf"); pdfReader.SetUnethicalReading(true); var pdfWriter = new PdfWriter(@"C:\Temp\3.pdf"); var pdfDoc = new PdfDocument(pdfReader, pdfWriter); try { var acroForm = PdfAcroForm.GetAcroForm(pdfDoc, true); var xfa = acroForm.GetXfaForm(); var ns = new XmlSerializerNamespaces(); ns.Add("", "http://www.xfa.org/schema/xfa-data/1.0/"); var memStream = new MemoryStream(); var serializer = new XmlSerializer(typeof(Data)); serializer.Serialize(memStream, data, ns); memStream.Seek(0, SeekOrigin.Begin); using var xmlReader = new StreamReader(memStream); var xmlString = await xmlReader.ReadToEndAsync(); var updatedMemStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)); xfa.FillXfaForm(updatedMemStream); xfa.Write(pdfDoc); } finally { pdfDoc.Close(); pdfReader.Close(); pdfWriter.Close(); }
尝试扁平化该PDF以适配常规阅读器时,使用以下代码抛出异常:
var destFile = new MemoryStream(); var xfaFlattener = new XFAFlattener(); xfaFlattener.Flatten(new MemoryStream( await File.ReadAllBytesAsync(@"C:\Temp\3.pdf")), destFile); await File.WriteAllBytesAsync(@"C:\Temp\4.pdf", destFile.ToArray());
异常信息
AbstractITextEvent is only for internal usage
问题原因
XFAFlattener是iText库的内部工具类,并非对外公开的API,直接实例化调用会触发内部事件校验逻辑,导致抛出该异常。
解决方案
改用XfaForm提供的Flatten()方法完成扁平化操作,这是官方推荐的公共API用法。
方案1:单独处理已填充的PDF
var pdfReader = new PdfReader(@"C:\Temp\3.pdf"); var pdfWriter = new PdfWriter(@"C:\Temp\4.pdf"); var pdfDoc = new PdfDocument(pdfReader, pdfWriter); try { var acroForm = PdfAcroForm.GetAcroForm(pdfDoc, true); var xfa = acroForm.GetXfaForm(); // 执行XFA表单扁平化 xfa.Flatten(pdfDoc); } finally { pdfDoc.Close(); pdfReader.Close(); pdfWriter.Close(); }
方案2:合并填充与扁平化步骤(推荐)
可以在填充表单后直接执行扁平化,避免生成中间文件:
var pdfReader = new PdfReader(@"C:\Temp\2.pdf"); pdfReader.SetUnethicalReading(true); var pdfWriter = new PdfWriter(@"C:\Temp\4.pdf"); // 直接输出扁平化后的文件 var pdfDoc = new PdfDocument(pdfReader, pdfWriter); try { var acroForm = PdfAcroForm.GetAcroForm(pdfDoc, true); var xfa = acroForm.GetXfaForm(); var ns = new XmlSerializerNamespaces(); ns.Add("", "http://www.xfa.org/schema/xfa-data/1.0/"); var memStream = new MemoryStream(); var serializer = new XmlSerializer(typeof(Data)); serializer.Serialize(memStream, data, ns); memStream.Seek(0, SeekOrigin.Begin); using var xmlReader = new StreamReader(memStream); var xmlString = await xmlReader.ReadToEndAsync(); var updatedMemStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)); xfa.FillXfaForm(updatedMemStream); // 填充完成后直接扁平化 xfa.Flatten(pdfDoc); } finally { pdfDoc.Close(); pdfReader.Close(); pdfWriter.Close(); }
内容的提问来源于stack exchange,提问作者Roger Far
相关产品推荐
相关产品推荐

