2013-02-14 90 views
4

我被困在一個區域。我需要在一個pdf中確定PDAcroForm字段的位置。我需要使用字段的x和y值進行一些處理。如何使用pdfbox獲取字段的位置?

任何想法如何做到這一點?信息是否出現在COS對象中?

+0

我們可以得到的文本位置。但我不知道如何獲得表格字段的位置。請參閱此鏈接並嘗試。 http://pdfbox.apache.org/apidocs/org/apache/pdfbox/util/TextPosition.html – SANN3 2013-02-14 07:22:42

+0

@ SAN3:是的,我已經得到了文本的位置。但我想獲得該領域的位置。我的要求是,我需要將完整的PDF轉換爲html。但在我的pdf中也會有一些表單元素。我不認爲PDF盒子有能力轉換formelements。有什麼建議麼?? – karthick 2013-02-14 08:25:36

+0

對不起,我不知道.. – SANN3 2013-02-14 09:21:29

回答

7

今天我有同樣的問題。以下代碼適用於我的情況:

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)); 
} 

編輯:karthicks代碼更短。所以,我現在使用此代碼:

private PDRectangle getFieldArea(PDField field) { 
    COSDictionary fieldDict = field.getDictionary(); 
    COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT); 
    PDRectangle result = new PDRectangle(fieldAreaArray); 
    return result; 
} 

如果你想測試返回的矩形是正確的,你可以使用此代碼:

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); 
} 
+0

我做了一些simillar這個。我打字,作爲一個答案,以便人們可以參考這兩個代碼。 – karthick 2013-02-18 05:38:10

+0

@karthick:這個答案是否正確?請將其標記爲已回答。如果不正確:你錯過了什麼? – Lukas 2013-02-19 07:53:37

+0

我試圖使用printRect,但沒有看到輸出中的任何內容。你能舉出一個完整的實例嗎? – 2014-02-27 03:24:18

0

我能夠得到這樣

細節
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()); 
2

接受的答案不再有效。我已經嘗試了這種方法,並收到了一些元素的NullPointerException。在PDFBOX 2.x中,您可以直接獲取矩形而無需查詢COS對象樹。

有關字段位置的信息存儲在PDAnnotationWidget中。可以有更多的部件與該領域相關聯。要獲得第一個(不檢查這些是否是一個)。

PDRectangle rectangle = field.getWidgets().get(0).getRectangle(); 

獲得所有的矩形(在情況下,有可能會更多):

List<PDRectangle> rectangles = field.getWidgets().stream().map(PDAnnotation::getRectangle).collect(Collectors.toList()); 
+1

*「接受的答案不再有效」* - 更重要的是:它從未適用於您的PDF。它只適用於只有單個窗口小部件合併到表單域中的表單域。這通常是這種情況,但並非總是如此。 – mkl 2017-07-08 18:21:27