Ваш PDF является гибридным документом AcroForm / XFA;где часть XFA использует поля с пользовательским интерфейсом imageEdit, часть AcroForm использует поля кнопок.
Таким образом, она позволяет двумя способами проверить, установлено ли поле изображения: Либо вы смотрите на кнопки AcroForm и просматриваетеих появления для изображений, или вы извлекаете XFA XML и проверяете это.
Проверка XFA XML
Изначально я пропустил версию PDFBox в заголовке вопроса и реализовал ее для PDFBox2.0.x.Как выясняется, однако, идентичный код может использоваться для PDFBox 1.8.11, могут быть выброшены только некоторые дополнительные исключения и, следовательно, должны быть рассмотрены.
Последний вариант, проверка XFAXML на самом деле немного проще для документа под рукой.Просто найдите в XML элемент с указанным именем и проверьте его содержимое.В качестве дополнительной проверки работоспособности можно проверить атрибут типа содержимого элемента:
boolean isFieldFilledXfa(Document xfaDom, String fieldName) {
NodeList fieldElements = xfaDom.getElementsByTagName(fieldName);
for (int i = 0; i < fieldElements.getLength(); i++) {
Node node = fieldElements.item(i);
if (node instanceof Element) {
Element element = (Element) node;
if (element.getAttribute("xfa:contentType").startsWith("image/")) {
return element.getTextContent().length() > 0;
}
}
}
return false;
}
( CheckImageFieldFilled вспомогательный метод)
С его помощьюВы можете проверить свой документ:
PDDocument document = PDDocument.load(SOURCE);
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
Document xfaDom = acroForm.getXFA().getDocument();
System.out.println("Filled image fields from ImageField1..ImageField105:");
for (int i=1; i < 106; i++) {
if (isFieldFilledXfa(xfaDom, "ImageField" + i)) {
System.out.printf("* ImageField%d\n", i);
}
}
( CheckImageFieldFilled метод испытания testCheckXfaGsa500Pdf_v4
)
Выход:
Filled image fields from ImageField1..ImageField105:
* ImageField1
* ImageField3
* ImageField6
Проверка внешнего вида AcroForm
Реализация здесь работает только как есть для PDFBox 2.0.x.Структура классов синтаксического анализатора потока контента была значительно переработана в 2.0.0, что сделало бэкпорт этого кода на 1.8.xa немного утомительным.
Чтобы проверить, действительно ли появление кнопки действительно показывает изображение (и не только имеет изображение в своих ресурсах ), можно использовать простой подкласс PDFGraphicsStreamEngine
, например:
public class WidgetImageChecker extends PDFGraphicsStreamEngine
{
public WidgetImageChecker(PDAnnotationWidget widget) {
super(widget.getPage());
this.widget = widget;
}
public boolean hasImages() throws IOException {
count = 0;
PDAppearanceStream normalAppearance = widget.getNormalAppearanceStream();
processChildStream(normalAppearance, widget.getPage());
return count != 0;
}
@Override
public void drawImage(PDImage pdImage) throws IOException {
count++;
}
@Override
public void appendRectangle(Point2D p0, Point2D p1, Point2D p2, Point2D p3) throws IOException { }
@Override
public void clip(int windingRule) throws IOException { }
@Override
public void moveTo(float x, float y) throws IOException { }
@Override
public void lineTo(float x, float y) throws IOException { }
@Override
public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) throws IOException { }
@Override
public Point2D getCurrentPoint() throws IOException { return null; }
@Override
public void closePath() throws IOException { }
@Override
public void endPath() throws IOException { }
@Override
public void strokePath() throws IOException { }
@Override
public void fillPath(int windingRule) throws IOException { }
@Override
public void fillAndStrokePath(int windingRule) throws IOException { }
@Override
public void shadingFill(COSName shadingName) throws IOException { }
final PDAnnotationWidget widget;
int count = 0;
}
( CheckImageFieldFilled вспомогательный класс)
С его помощью вы можете создать метод проверки следующим образом:
boolean isFieldFilledAcroForm(PDAcroForm acroForm, String fieldName) throws IOException {
for (PDField field : acroForm.getFieldTree()) {
if (field instanceof PDPushButton && fieldName.equals(field.getPartialName())) {
for (final PDAnnotationWidget widget : field.getWidgets()) {
WidgetImageChecker checker = new WidgetImageChecker(widget);
if (checker.hasImages())
return true;
}
}
}
return false;
}
( CheckImageFieldFilled вспомогательный метод)
и используйте его следующим образом:
PDDocument document = PDDocument.load(SOURCE);
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
System.out.println("Filled image fields (AcroForm) from ImageField1..ImageField105:");
for (int i=1; i < 106; i++) {
if (isFieldFilledAcroForm(acroForm, "ImageField" + i + "[0]")) {
System.out.printf("* ImageField%d\n", i);
}
}
( CheckImageFieldFilled test testCheckAcroFormGsa500Pdf_v4
)
Вывод, как и выше:
Filled image fields (AcroForm) from ImageField1..ImageField105:
* ImageField1
* ImageField3
* ImageField6