How to get the position of a field using pdfbox?
I had the same problem today. The following code works in my case:
private PDRectangle getFieldArea(PDField field) {
COSDictionary fieldDict = field.getDictionary();
COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
float left = (float) ((COSFloat) fieldAreaArray.get(0)).doubleValue();
float bottom = (float) ((COSFloat) fieldAreaArray.get(1)).doubleValue();
float right = (float) ((COSFloat) fieldAreaArray.get(2)).doubleValue();
float top = (float) ((COSFloat) fieldAreaArray.get(3)).doubleValue();
return new PDRectangle(new BoundingBox(left, bottom, right, top));
}
Edit: karthicks code is shorter. So I use this code now:
private PDRectangle getFieldArea(PDField field) {
COSDictionary fieldDict = field.getDictionary();
COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
PDRectangle result = new PDRectangle(fieldAreaArray);
return result;
}
And you can use this code if you want to test that the returned rectangle is correct:
private void printRect(final PDPageContentStream contentStream, final PDRectangle rect) throws IOException {
contentStream.setStrokingColor(Color.YELLOW);
contentStream.drawLine(rect.getLowerLeftX(), rect.getLowerLeftY(), rect.getLowerLeftX(), rect.getUpperRightY()); // left
contentStream.drawLine(rect.getLowerLeftX(), rect.getUpperRightY(), rect.getUpperRightX(), rect.getUpperRightY()); // top
contentStream.drawLine(rect.getUpperRightX(), rect.getLowerLeftY(), rect.getUpperRightX(), rect.getUpperRightY()); // right
contentStream.drawLine(rect.getLowerLeftX(), rect.getLowerLeftY(), rect.getUpperRightX(), rect.getLowerLeftY()); // bottom
contentStream.setStrokingColor(Color.BLACK);
}
The accepted answer does not work anymore. I have tried the approach and received NullPointerException
for some elements. In PDFBOX 2.x, you can obtain the rectangle without querying the COS object tree directly.
The information about the field position is stored in PDAnnotationWidget
. There can be more widgets associated with the field. To obtain the first one (without checking whether these is one).
PDRectangle rectangle = field.getWidgets().get(0).getRectangle();
To obtain all rectangles (in cases there can be more):
List<PDRectangle> rectangles = field.getWidgets().stream().map(PDAnnotation::getRectangle).collect(Collectors.toList());