使用Apache PDFBox访问PDF表单字段对应COSArray中COSObject的问题
COSObject{x, y}含义说明
PDF规范中所有非基础类型的内容都以间接对象的形式存储,COSObject{110, 0}里的第一个数字是对象编号,是PDF文件内该对象的唯一标识;第二个数字是生成编号,仅在PDF被增量修改时会变更,未修改的原生PDF该值默认为0。
你打印时看到的COSObject是PDFBox对间接引用的包装类,本身不存储实际内容,调用getCOSObject()方法即可解引用拿到它指向的真实对象(可能是字典、数组、字符串等任意COS类型)。
访问COSArray中元素的方法
你可以直接遍历COSArray的每个元素,对每个元素做解引用和类型判断后操作,在你原有遍历字典的代码基础上补充如下逻辑即可:
if (val instanceof COSArray ) { COSArray kidsArray = (COSArray) val; System.out.println("COSArray size = " + kidsArray.size()); // 遍历数组内所有元素 for (int i = 0; i < kidsArray.size(); i++) { COSBase item = kidsArray.get(i); // 解引用间接对象,拿到真实内容 COSBase realItem = item.getCOSObject(); // 根据真实类型做对应处理 if (realItem instanceof COSDictionary) { COSDictionary kidDict = (COSDictionary) realItem; System.out.println("第" + i + "个元素是字典,大小:" + kidDict.size()); // 字典可以通过COSName取对应值,比如取字段名 String kidFieldName = kidDict.getString(COSName.T); System.out.println("子字段名称:" + kidFieldName); } else if (realItem instanceof COSArray) { COSArray subArray = (COSArray) realItem; System.out.println("第" + i + "个元素是数组,大小:" + subArray.size()); // 数组可以继续按上述逻辑嵌套遍历 } } }
更推荐的上层API用法
你要读取所有表单字段的需求完全不需要手动操作底层COS对象,PDFBox已经封装了直接获取子字段的方法,代码更简洁也不容易出错:
// 读取根字段的所有子字段 List<PDField> childFields = field.getChildren(); for (PDField childField : childFields) { // 打印字段完整名称和当前值 System.out.println("字段名:" + childField.getFullyQualifiedName()); System.out.println("当前值:" + childField.getValueAsString()); // 要自动填充直接调用setValue即可 // childField.setValue("需要填充的内容"); } // 如果子字段还有嵌套的下级字段,可以递归调用getChildren()获取所有层级的字段
内容的提问来源于stack exchange,提问作者spectrum
相关产品推荐
相关产品推荐

