简体   繁体   English

如何使用pdfbox获取字段的位置?

[英]How to get the position of a field using pdfbox?

I got stuck in one area.我被困在一个领域。 I need to identify the positions of the PDAcroForm fields in one pdf.我需要在一个 pdf 中确定PDAcroForm字段的位置。 I need to do some processing with the x and y value of the fields.我需要对字段的 x 和 y 值进行一些处理。

Any idea how to do this?知道如何做到这一点吗? Is the information present in the COS object?信息是否存在于 COS 对象中?

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.编辑:karthicks 代码更短。 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.我已经尝试过这种方法并收到了某些元素的NullPointerException In PDFBOX 2.x, you can obtain the rectangle without querying the COS object tree directly.在 PDFBOX 2.x 中,无需直接查询 COS 对象树即可获取矩形。

The information about the field position is stored in PDAnnotationWidget .有关字段位置的信息存储在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());

I am able to get the details like this我能够得到这样的细节

   COSDictionary trailer = document.getDocument().getTrailer();
   COSDictionary root = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT);
   COSDictionary acroForm = (COSDictionary) root.getDictionaryObject(COSName.getPDFName("AcroForm"));
   if (null != acroForm) {
    COSArray fields1 = (COSArray) acroForm.getDictionaryObject(COSName.getPDFName("Fields"));
    for (int l = 0; l < fields1.size(); l++) {
     COSDictionary field = (COSDictionary) fields1.getObject(l);
     COSArray rectArray= (COSArray)field.getDictionaryObject("Rect");
     PDRectangle mediaBox = new PDRectangle( rectArray ); 
System.out.println("mediaBox: " + mediaBox.getLowerLeftX()  +"||" +mediaBox.getLowerLeftY());
System.out.println("mediaBox: " + mediaBox.getUpperRightX()  +"||" + mediaBox.getUpperRightY());

Use below code for the latest PdfBox dependency releases使用以下代码获取最新的 PdfBox 依赖版本

private PDRectangle getFieldArea(PDField field) {
    COSDictionary fieldDict = field.getCOSObject();
    COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
    PDRectangle rectangle = new PDRectangle(fieldAreaArray);
    System.out.println(rectangle);
    return rectangle;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM