Я использую java-библиотеку itext7, как показано ниже, чтобы добавить 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, но пока не повезло. Любая помощь будет оценена по достоинству. Заранее спасибо.
Связано, но с использованием iText 5: этот ответ
Спасибо за ответ @mkl. Я также ожидал того же, что и вы упомянули, что подпись будет сломана, но изображение будет установлено. Я изучу ответ, который вы указали для itext5, и посмотрю, поможет ли он мне. В противном случае я поделюсь всеми твоими pdf-файлами. 1> сразу после добавления полей acro, 2> после его подписания. 3> после изменения подписанного pdf.
@mkl Я попытался перенести упомянутый вами код для itext5, но мне это не удалось. Ссылка на 3 PDF-файла: [ссылка] jmp.sh/JesPwyE
@mkl спасибо за помощь, я перенес весь свой код на itext5 и смог реализовать ваш код. Вся помощь очень ценится
Посмотрю, скорее всего завтра, сегодня у нас праздник и у меня только смартфон под рукой.
Это действительно интересно. Если вы посмотрите файл (подписанный, изображение изменено) в Adobe Acrobat, вы действительно увидите исходное изображение. Но если вы посмотрите файл в Chrome или Foxit, вы увидите новое изображение. Похоже, это особая функция Adobe ...
Я протестировал код в этом ответе с помощью подписанный, но незаполненный PDF-файл, которым вы поделились. Однако, поскольку вы не поделились образцом изображения, я использовал свое собственное.
Ты говоришь
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly. For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
Это не совсем так, изображение является установлено, но не все программы просмотра PDF Показать его.
Подробно: если вы установите изображение в подписанном PDF-файле с помощью своего кода, Adobe Reader действительно покажет просто серую рамку.
но другие программы просмотра PDF, например Foxit или встроенная программа просмотра Chrome, показывать заменяющее изображение
Таким образом, изображение устанавливается и для PDF-файла с цифровой подписью. Реальная проблема в том, что Adobe Reader не отображает его!
После некоторого анализа и некоторых отвлекающих маневров причина проблемы заключается в том, что если Adobe Reader отображает PDF-файл с измененным внешним видом кнопки AcroForm и
(Однако другие программы просмотра PDF, похоже, всегда используют обновленный поток внешнего вида.)
iText действительно создает словарь характеристик внешнего вида для кнопки (поэтому Adobe Reader предполагает, что он может игнорировать обновленный внешний вид и может создать новый на основе этого словаря), но, к сожалению, не добавляет к нему некоторую информацию, относящуюся к кнопке, ни при создании кнопки, ни при смене кнопки. В частности, это касается следующих двух записей:
I stream (Optional; push-button fields only; shall be an indirect reference) A form XObject defining the widget annotation’s normal icon, which shall be displayed when it is not interacting with the user.
TP integer (Optional; push-button fields only) A code indicating where to position the text of the widget annotation’s caption relative to its icon:
0 No icon; caption only
1 No caption; icon only
2 Caption below the icon
3 Caption above the icon
4 Caption to the right of the icon
5 Caption to the left of the icon
6 Caption overlaid directly on the icon
Default value: 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);
}
(Вспомогательный метод SetButtonImagesetLikeGautamAnandImproved
)
Теперь 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));
}
(Вспомогательный метод SetButtonImagesetLikeGautamAnandImproved2
)
Однако результат выглядит немного иначе:
Как видите, вокруг изображения есть небольшая рамка. Скорее всего, вы можете заставить его исчезнуть, настроив соответствующие другие характеристики.
Спасибо за редактирование @Daniel