我正在使用PDFBox库来填充PDF表单,但我无法将它们展平。我已经尝试过以下解决方案:
PDAcroForm acroForm = docCatalog.getAcroForm();
PDField field = acroForm.getField( name );
field.setReadonly(true); //Solution 1
field.getDictionary().setInt("Ff",1);//Solution 2
但似乎没有任何效果。请为此建议一个解决方案。
答案 0 :(得分:2)
PDFBOX 2.0.0有一个PDAcroForm.flatten()方法
答案 1 :(得分:0)
如Maruan所述,可以使用PDAcroForm.flatten()
方法。
尽管这些字段可能需要一些预处理,最重要的是必须遍历嵌套的字段结构,并检查DV和V的值。
在我们的案例中,有效的方法是:
private static void flattenPDF(String src, String dst) throws IOException {
PDDocument doc = PDDocument.load(new File(src));
PDDocumentCatalog catalog = doc.getDocumentCatalog();
PDAcroForm acroForm = catalog.getAcroForm();
PDResources resources = new PDResources();
acroForm.setDefaultResources(resources);
List<PDField> fields = new ArrayList<>(acroForm.getFields());
processFields(fields, resources);
acroForm.flatten();
doc.save(dst);
doc.close();
}
private static void processFields(List<PDField> fields, PDResources resources) {
fields.stream().forEach(f -> {
f.setReadOnly(true);
COSDictionary cosObject = f.getCOSObject();
String value = cosObject.getString(COSName.DV) == null ?
cosObject.getString(COSName.V) : cosObject.getString(COSName.DV);
System.out.println("Setting " + f.getFullyQualifiedName() + ": " + value);
try {
f.setValue(value);
} catch (IOException e) {
if (e.getMessage().matches("Could not find font: /.*")) {
String fontName = e.getMessage().replaceAll("^[^/]*/", "");
System.out.println("Adding fallback font for: " + fontName);
resources.put(COSName.getPDFName(fontName), PDType1Font.HELVETICA);
try {
f.setValue(value);
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
e.printStackTrace();
}
}
if (f instanceof PDNonTerminalField) {
processFields(((PDNonTerminalField) f).getChildren(), resources);
}
});
}