iTextPDF报错:There is no associate PdfWriter for making indirects 求助
解决iTextPDF报错:
com.itextpdf.kernel.PdfException: There is no associate PdfWriter for making indirects 问题场景
使用iText7提取PDF单选按钮值时,部分PDF可正常运行,部分PDF触发上述错误。
环境依赖
使用iText7版本7.1.4,依赖Jar包:
- forms-7.1.4.jar
- io-7.1.4.jar
- layout-7.1.4.jar
- kernel-7.1.4.jar
问题原因
报错核心是代码中调用PdfAcroForm.getAcroForm(pdfDoc, true)时,第二个参数createIfMissing设为true,该参数会触发iText自动修复或重建表单内部结构。但当前仅通过PdfReader初始化PdfDocument,处于只读模式,未关联PdfWriter支持写入操作,当PDF表单结构存在异常需要修复时,就会抛出缺少PdfWriter的错误。而正常PDF的表单结构完整,无需修复,因此不会触发报错。
解决方案
两种处理方式可选:
- 仅读取表单值(推荐):将
PdfAcroForm.getAcroForm的第二个参数改为false,因为仅需提取值,不需要自动创建或修复表单结构。 - 需修复表单时:如果必须修复损坏的表单结构,需同时初始化
PdfWriter,即使不需要保存修改,也可使用ByteArrayOutputStream作为临时输出目标。
修改后的代码示例
方案1:只读模式提取表单值
package test; import java.util.Set; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.forms.PdfAcroForm; public class test5 { public static final String DATASHEET = "2.pdf"; public static void main(String[] args) throws Exception { PdfReader reader = new PdfReader(DATASHEET); PdfDocument pdfDoc = new PdfDocument(reader); // 将第二个参数改为false,禁用自动创建/修复表单 PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, false); if (form == null) { System.out.println("PDF中不存在可识别的表单"); pdfDoc.close(); return; } Set<String> fields = form.getFormFields().keySet(); for (String key : fields) { PdfName type = form.getField(key).getFormType(); if (type != null && PdfName.Btn.compareTo(type) == 0) { String[] states = form.getField(key).getAppearanceStates(); for (String state : states) { System.out.println(state); } } } pdfDoc.close(); } }
方案2:关联PdfWriter支持表单修复
package test; import java.io.ByteArrayOutputStream; import java.util.Set; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.forms.PdfAcroForm; public class test5 { public static final String DATASHEET = "2.pdf"; public static void main(String[] args) throws Exception { ByteArrayOutputStream tempOut = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(DATASHEET); PdfWriter writer = new PdfWriter(tempOut); // 同时关联Reader和Writer,支持写入操作 PdfDocument pdfDoc = new PdfDocument(reader, writer); PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); if (form == null) { System.out.println("PDF中不存在可识别的表单"); pdfDoc.close(); return; } Set<String> fields = form.getFormFields().keySet(); for (String key : fields) { PdfName type = form.getField(key).getFormType(); if (type != null && PdfName.Btn.compareTo(type) == 0) { String[] states = form.getField(key).getAppearanceStates(); for (String state : states) { System.out.println(state); } } } pdfDoc.close(); } }
内容的提问来源于stack exchange,提问作者Muhammad Samiullah
相关产品推荐
相关产品推荐

