我正在使用如下所示的itext7 Java库将PdfButtonFormField添加到现有的pdf中:
String src = "sample.pdf";
String dest = "acro_sample_empty_fields.pdf";
PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfButtonFormField button = PdfFormField.createPushButton(pdf, new Rectangle(Integer.parseInt(control.xCord), Integer.parseInt(control.yCord),Integer.parseInt(control.width), Integer.parseInt(control.height)), control.name, control.value);
form.addField(button, page);
String resource = "sample.png";
button.setImage(resource);
此后,我使用以下代码填写如下表格:
String src = "1540982441_313554925_acro_sample_empty_fields_signedFinal.pdf";
String dest = "acro_sample_filled_fields.pdf";
PdfReader reader = new PdfReader(src);
File output = new File(dest);
OutputStream outputStream = new FileOutputStream(output);
PdfDocument document = new PdfDocument(reader,
new PdfWriter(outputStream),
new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(document, true);
Map<String, PdfFormField> fields = form.getFormFields();
String resource = "sample_test.png";
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
对于正常的pdf,一切正常。但是,如果我对创建的pdf进行数字签名,然后尝试填充它。则图像设置不正确。 对于普通pdf,按钮上的图像已按预期更改。但是在经过数字签名的pdf上,图像未设置。
我已经尝试过在Google上寻找此商品,但还没有运气。任何帮助将不胜感激。预先感谢。
答案 0 :(得分:0)
我使用the signed but unfilled PDF you shared测试了此答案中的代码。但是,由于您没有共享示例图像,因此我使用了自己的图像。
你说
对于正常的pdf,一切正常。但是,如果我对创建的pdf进行数字签名,然后尝试填充它。则图像设置不正确。对于普通pdf,按钮上的图像已按预期更改。但是在经过数字签名的pdf上,图像未设置。
这并非完全正确,图像已设置为 ,但并非所有PDF查看器都显示。
详细信息:如果使用代码在签名的PDF中设置图像,则Adobe Reader实际上仅显示一个灰色框
,但其他PDF查看器,例如福昕浏览器或Chrome的内置查看器会显示替换图片
因此,图像也被设置为经过数字签名的PDF。实际的问题是Adobe Reader无法显示它!
经过分析并发现一些红色鲱鱼后,出现问题的原因似乎是如果Adobe Reader显示PDF时AcroForm按钮外观已更改,并且
(不过,其他PDF查看器似乎总是使用更新的外观流。)
iText确实为按钮创建了外观特征字典(因此Adobe Reader假定它可以忽略更新的外观,并可以基于此字典构造一个新的外观),但不幸的是,在构造时,它们都没有向按钮添加一些特定于按钮的信息。按钮或更改按钮时。这尤其涉及以下两个条目:
我 流 (可选;仅按钮字段;应为间接引用)定义小部件注释的常规图标的表格XObject,当其不与用户交互时,将显示该图标。
TP 整数 (可选;仅按钮字段)一个代码,指示小部件注释的标题的文本相对于其图标的位置:
0 没有图标;仅标题
1 无标题;仅限图标
图标下方的2 标题
图标上方的3 标题
图标右侧的4 标题
图标左侧的5 标题
6 字幕直接覆盖在图标上
默认值: 0 。
(ISO 32000-2,表192-外观特征字典中的条目)
由于iText不提供 TP 值,因此会出现默认值,并且Adobe Reader创建带有“无图标;仅标题”的按钮外观。由于未定义标题,因此结果是一个灰色框。
最简单的解决方法是在图像更新过程中删除整个外观特征字典,即替换
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
作者
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
if (button.getPdfObject().containsKey(PdfName.MK)) {
button.setModified();
button.getPdfObject().remove(PdfName.MK);
}
(SetButtonImage辅助方法setLikeGautamAnandImproved
)
现在Adobe Reader找不到任何外观特征,因此不能忽略更新的外观流。
或者,我们可以添加缺少的外观特征条目,例如像这样:
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
PdfWidgetAnnotation widget = button.getWidgets().get(0);
PdfDictionary characteristics = widget.getAppearanceCharacteristics();
if (characteristics != null) {
characteristics.setModified();
characteristics.put(PdfName.I, widget.getNormalAppearanceObject());
characteristics.put(PdfName.TP, new PdfNumber(1));
}
(SetButtonImage辅助方法setLikeGautamAnandImproved2
)
结果看上去略有不同,
如您所见,图像周围有一个小框。相应地设置其他特征,很可能会使它消失。