有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法读取跨行突出显示的确切文本

我正在使用PDBox阅读突出显示的PDF文档。我能够用一行字和多个字来阅读突出显示的文本。然而,我无法跨行阅读突出显示的文本。请查找以下示例代码以阅读突出显示的文本

PDDocument pddDocument = PDDocument.load(new File("C:\\pdf-sample.pdf"));
List allPages = pddDocument.getDocumentCatalog().getAllPages();
        for (int i = 0; i < allPages.size(); i++) {
            int pageNum = i + 1;
            PDPage page = (PDPage) allPages.get(i);
            List<PDAnnotation> la = page.getAnnotations();
            if (la.size() < 1) {
                continue;
            }
            System.out.println("Page number : "+pageNum);
            for (PDAnnotation pdfAnnot: la) {
                if (pdfAnnot.getSubtype().equals("Popup")) {
                    continue;
                }

                PDFTextStripperByArea stripper = new PDFTextStripperByArea();
                stripper.setSortByPosition(true);

                PDRectangle rect = pdfAnnot.getRectangle();
                float x = rect.getLowerLeftX() - 1;
                float y = rect.getUpperRightY() - 1;
                float width = rect.getWidth();
                float height = rect.getHeight() + rect.getHeight() / 4;

                int rotation = page.findRotation();
                if (rotation == 0) {
                    PDRectangle pageSize = page.getMediaBox();
                    y = pageSize.getHeight() - y;
                }

                Rectangle2D.Float awtRect = new Rectangle2D.Float(x, y, width, height);
                stripper.addRegion(Integer.toString(0), awtRect);
                stripper.extractRegions(page);
System.out.println("------------------------------------------------------------------");
                System.out.println("Annot type = " + pdfAnnot.getSubtype());
                 System.out.println("Getting text from region = " + stripper.getTextForRegion(Integer.toString(0)) + "\n");
                 System.out.println("Getting text from comment = " + pdfAnnot.getContents());

            }
        }

在跨行读取高亮显示的文本时,“pdfAnnot.getRectangle()”函数返回文本周围的最小矩形区域。这将提供比所需更多的文本。我找不到任何API来提取精确突出显示的文本

例如: 从测试PDF文件中提取的文本

Anyone, anywhere can open a PDF file. All you need is the free Adobe Acrobat

Reader. Recipients of other file formats sometimes can't open files because they

don't have the applications used to create the documents.

用例1: 阅读第一个粗体文本,即PDF。阅读单行突出显示的文本时没有问题。将按如下所示打印正确的文本:
输出: 从区域获取文本=“PDF

用例2: 阅读第二个粗体文本,即Adobe Acrobat reader,共两行。在这种情况下,运行上述程序时提取的文本为:
输出: 从region获取文本=“任何人、任何地方都可以打开PDF文件。您所需要的只是免费的Adobe Acrobat 读者其他文件格式的收件人有时无法打开文件,因为他们

getRectangle()API提供由高亮显示的文本包围的最小矩形的坐标。因此,它比“AdobeAcrobatReader”更具文本性

  1. 如何知道提取区域中高亮显示的的起点和终点
  2. 如何知道提取区域中的行数

我们将非常感谢您的帮助


共 (2) 个答案

  1. # 1 楼答案

    要使@roham amini提供的代码在当前版本的Apache PDFBOX(2.0)中工作,您必须做很多更改

    这段代码运行良好,我在Freeplane的groovy脚本中使用了它。您可能需要更换记录器。信息功能

    @Grab(group='org.apache.pdfbox', module='pdfbox', version='2.0.22')
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.pdmodel.PDPage;
    import org.apache.pdfbox.pdmodel.interactive.annotation.*;
    import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
    import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup;
    import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText;
    import org.apache.pdfbox.text.PDFTextStripperByArea;
    import org.apache.pdfbox.pdmodel.common.*;
    import org.apache.pdfbox.pdmodel.common.PDRectangle;
    import java.awt.geom.Rectangle2D;
    import org.apache.pdfbox.cos.*
    
    
    
    
    // PDDocument document = new PDDocument();
    String pdfFilePath = 'temp.pdf'
    PDDocument pdfDoc = PDDocument.load(new File(pdfFilePath));
    ArrayList<String> highlightedTexts = new ArrayList<>();
    
    int pageNum=0;
    for( PDPage pdfpage : pdfDoc.getPages()-60 )
    {
        pageNum++;
        List<PDAnnotation> annotations = pdfpage.getAnnotations();
        //first setup text extraction regions
        for( int i=0; i<annotations.size(); i++ )
        {
            PDAnnotation annot = annotations.get(i);
            annotNote = annot.getContents(); // Conteudo anotado na nota
            annotSubType = annot.getSubtype() // Tipo da nota (Highlight, Text)
            // annotTitle = annot.getTitlePopup(); // Autor da nota
            if( annotSubType.equals('Highlight') )
            {
            // extract highlighted text
                PDFTextStripperByArea stripper = new PDFTextStripperByArea();
                COSArray quadsArray = (COSArray) annot.getCOSObject().getCOSArray(COSName.getPDFName("QuadPoints"));
                String str = null;
                for(int j=1, k=0; j<=(quadsArray.size()/8); j++) {
                    Float ULX = quadsArray.get(0+k).floatValue();
                    Float ULY = quadsArray.get(1+k).floatValue();
                    Float URX = quadsArray.get(2+k).floatValue();
                    Float URY = quadsArray.get(3+k).floatValue();
                    Float LLX = quadsArray.get(4+k).floatValue();
                    Float LLY = quadsArray.get(5+k).floatValue();
                    Float LRX = quadsArray.get(6+k).floatValue();
                    Float LRY = quadsArray.get(7+k).floatValue();
                    k+=8;
                    float ulx = ULX - 1; // upper left x.
                    float uly = ULY; // upper left y.
                    float width = URX - LLX;          // calculated by upperRightX - lowerLeftX.
                    float height = URY - LLY;         // calculated by upperRightY - lowerLeftY.
    
                    PDRectangle pageSize = pdfpage.getMediaBox();
                    uly = pageSize.getHeight() - uly;
    
                    Rectangle2D.Float rectangle_2 = new Rectangle2D.Float(ulx, uly, width, height);
                    stripper.addRegion("highlightedRegion", rectangle_2);
                    stripper.extractRegions(pdfpage);
                    String highlightedText = stripper.getTextForRegion("highlightedRegion").replaceAll("[\\n\\t ]", " ");
    
                    if(j > 1) {
                        str = str.concat(highlightedText);
                    } else {
                        str = highlightedText;
                    }
                }
                highlightedTexts.add(str);
                logInfo = str;
    
                logMsg=">>>>>>>>>>Pagina: " + pageNum + ", Sessão: " + annotNote + ", Nota: " + annotNote + "Texto sublinhado: " + logInfo;
                logger.info(logMsg);
            }
        }
    
    }
    pdfDoc.close();
    
  2. # 2 楼答案

    我使用以下代码成功地提取了突出显示的文本

    // PDF32000-2008
    // 12.5.2 Annotation Dictionaries
    // 12.5.6 Annotation Types
    // 12.5.6.10 Text Markup Annotations
    @SuppressWarnings({ "unchecked", "unused" })
    public ArrayList<String> getHighlightedText(String filePath, int pageNumber) throws IOException {
        ArrayList<String> highlightedTexts = new ArrayList<>();
        // this is the in-memory representation of the PDF document.
        // this will load a document from a file.
        PDDocument document = PDDocument.load(filePath);
        // this represents all pages in a PDF document.
        List<PDPage> allPages =  document.getDocumentCatalog().getAllPages();
        // this represents a single page in a PDF document.
        PDPage page = allPages.get(pageNumber);
        // get  annotation dictionaries
        List<PDAnnotation> annotations = page.getAnnotations();
    
        for(int i=0; i<annotations.size(); i++) {
            // check subType 
            if(annotations.get(i).getSubtype().equals("Highlight")) {
                // extract highlighted text
                PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea();
    
                COSArray quadsArray = (COSArray) annotations.get(i).getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints"));
                String str = null;
    
                for(int j=1, k=0; j<=(quadsArray.size()/8); j++) {
    
                    COSFloat ULX = (COSFloat) quadsArray.get(0+k);
                    COSFloat ULY = (COSFloat) quadsArray.get(1+k);
                    COSFloat URX = (COSFloat) quadsArray.get(2+k);
                    COSFloat URY = (COSFloat) quadsArray.get(3+k);
                    COSFloat LLX = (COSFloat) quadsArray.get(4+k);
                    COSFloat LLY = (COSFloat) quadsArray.get(5+k);
                    COSFloat LRX = (COSFloat) quadsArray.get(6+k);
                    COSFloat LRY = (COSFloat) quadsArray.get(7+k);
    
                    k+=8;
    
                    float ulx = ULX.floatValue() - 1;                           // upper left x.
                    float uly = ULY.floatValue();                               // upper left y.
                    float width = URX.floatValue() - LLX.floatValue();          // calculated by upperRightX - lowerLeftX.
                    float height = URY.floatValue() - LLY.floatValue();         // calculated by upperRightY - lowerLeftY.
    
                    PDRectangle pageSize = page.getMediaBox();
                    uly = pageSize.getHeight() - uly;
    
                    Rectangle2D.Float rectangle_2 = new Rectangle2D.Float(ulx, uly, width, height);
                    stripperByArea.addRegion("highlightedRegion", rectangle_2);
                    stripperByArea.extractRegions(page);
                    String highlightedText = stripperByArea.getTextForRegion("highlightedRegion");
    
                    if(j > 1) {
                        str = str.concat(highlightedText);
                    } else {
                        str = highlightedText;
                    }
                }
                highlightedTexts.add(str);
            }
        }
        document.close();
    
        return highlightedTexts;
    }