Мы пытаемся читать PDF-файл и динамически подставлять в него значения. На основе входящего запроса мы запускаем некоторые правила и определяем, какой PDF-файл использовать, а затем динамически заполняем его значениями. Мы используем Apache PDFBox версии 2.0.11, и по какой-то причине мы сталкиваемся с проблемами с конкретным шаблоном PDF. Мы не можем прочитать некоторые поля для этого конкретного шаблона, а созданный PDF-файл является неполным. Интересно, связано ли это с самим оригинальным PDF-файлом. Вот фрагмент кода, который мы используем для чтения полей и их заполнения.
PDDocument pdfTemplate = PDDocument.load(inputStream);
PDDocumentCatalog docCatalog = pdfTemplate.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
acroForm.setXFA(null);
COSArrayList<PDField> list = (COSArrayList<PDField>) acroForm.getFields();
for (PDField field : list) {
field.setReadOnly(true);
logger.debug("Field name "+field.getFullyQualifiedName())))
//use logic to populate value by calling field.setValue();
}
Когда мы попытались напечатать имя каждого поля, мы обнаружили, что более 30 процентов полей отсутствуют. Может ли кто-нибудь помочь, как это исправить? PDF-файл из 15 страниц с разными вопросами. Если проблема связана с самим исходным PDF-файлом, то в чем может быть причина, по которой нельзя прочитать некоторые поля?
Привет, Тилам, Спасибо за ответ. Я дважды проверил java-документ и попытался получить детей, но это не помогло. К сожалению, я не смог прикрепить PDF-файл куда-либо, так как это может нарушать политику компании. Вы что-нибудь порекомендуете мне проверить?
Одна из возможностей состоит в том, что PDF-файл содержит только аннотации виджетов (которые связаны со страницами), а не поля (которые связаны с документом, каждое поле может иметь виджеты от 1 до n). Откройте файл с помощью PDFBox PDFDebugger. На странице переместите указатель мыши в область поля. Отображается ли имя поля в строке состояния? Еще одна идея: в меню нажмите «Просмотр», «Показать внутреннюю структуру», затем в дереве перейдите в Root / AcroForm / Fields. Затем посмотрите на всю структуру и попробуйте найти свое поле. Вы его нашли?
Привет, Тилман, я попробовал то, что вы предложили, и я не вижу полей в разделе Root / AcroForm / Fields. В чем может быть причина того, что там нет полей? Нужно ли исправлять сам PDF?
Может, это формы XFA. Pdfbox с этим не справится. Но вы написали, что у вас есть некоторые поля, тогда вы должны их увидеть
Всего полей должно быть около 350, но отображаются только 130 полей. Мы проверяем, можем ли мы снова воссоздать PDF. Интересно, PDF-файл может быть поврежден.
Пожалуйста, попробуйте также другое, что я упомянул, то есть при отображении страницы PDFDebugger переместите мышь туда, где находится поле, и посмотрите имя. Сделайте то же самое с полем, которое, как вы знаете, обрабатывается правильно. Если вы не видите имя, значит, вы используете старую версию PDFDebugger.
Я попробовал, как вы предложили, и поле, в котором есть проблемы, не отображается в строке состояния ниже и отображается нормально для других. Я использую 2.0.11 PDFDebugger
В этом случае в Root/AcroForm/Fields
должно быть что-то (огромное дерево, которое можно расширить). Потому что это путь, по которому PDFDebugger собирает все доступные поля, а затем виджеты для создания эффекта строки состояния.
Наша бизнес-операция снова восстановила PDF-файл, и теперь мы можем получить все поля. Спасибо за помощь.
Рад это слышать. Предлагаю либо удалить вопрос, либо ответить на него самостоятельно.
У вас, вероятно, есть иерархические поля в этой форме. Вместо этого попробуйте что-то вроде приведенного ниже кода ...
PDDocument pdfTemplate = PDDocument.load(inputStream);
PDDocumentCatalog docCatalog = pdfTemplate.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
PDFieldTree fieldTree = acroForm.getFieldTree();
Iterator<PDField> fieldTreeIterator = fieldTree.iterator();
while (fieldTreeIterator.hasNext()) {
PDField field = fieldTreeIterator.next();
if (field instanceof PDTerminalField) {
String fullyQualifiedName = field.getFullyQualifiedName();
logger.debug("Field name "+fullyQualifiedName);
}
}
PDAcroForm.getFields () получает только корневые поля, а не их дочерние поля. PDAcroForm.getFieldTree () получает все поля, но затем вам нужно проверить, являются ли они терминальными, прежде чем устанавливать значение. Нетерминальные поля не могут иметь значения и не имеют связанных с ними виджетов (представлений на странице). Вы поймете, что это проблема, если в полном имени есть точки. Периоды представляют собой иерархию.
Спасибо joelgeraci за предложение. Использование FieldTree тоже не помогло.
Можете ли вы опубликовать PDF-файл где-нибудь, чтобы я мог узнать подробности?
joelgeric, К сожалению, я не смог прикрепить PDF куда-либо, так как это может нарушать политику компании. Вы что-нибудь порекомендуете мне проверить?
Можете ли вы заменить нижележащую страницу пустой и опубликовать PDF-файл только с полями формы?
Проблема была решена после повторного восстановления всего PDF-файла.
Пожалуйста, прочтите javadoc
getFields()
и обновите код. Если это не помогает, поделитесь PDF-файлом и укажите одно поле, которое игнорируется.