【问题标题】:PdfBox - Get font Information usingPdfBox - 使用获取字体信息
【发布时间】:2014-01-18 06:33:45
【问题描述】:

我正在尝试使用 Square Annotation 从 pdf 中获取文本。我使用下面的代码使用 PDFBOX.
CODE

从 PDF 中提取文本
try {    
            PDDocument document = null;
            try {
                document = PDDocument.load(new File("//Users//" + usr + "//Desktop//BoldTest2 2.pdf"));
                List allPages = document.getDocumentCatalog().getAllPages();
                for (int i = 0; i < allPages.size(); i++) {
                    PDPage page = (PDPage) allPages.get(i);
                    Map<String, PDFont> pageFonts = page.getResources().getFonts();
                    List<PDAnnotation> la = page.getAnnotations();
                    for (int f = 0; f < la.size(); f++) {
                        PDAnnotation pdfAnnot = la.get(f);
                        PDFTextStripperByArea stripper = new PDFTextStripperByArea();
                        stripper.setSortByPosition(true);
                        PDRectangle rect = pdfAnnot.getRectangle();

                        float x = 0;
                        float y = 0;
                        float width = 0;
                        float height = 0;
                        int rotation = page.findRotation();

                        if (rotation == 0) {
                            x = rect.getLowerLeftX();
                            y = rect.getUpperRightY() - 2;
                            width = rect.getWidth();
                            height = rect.getHeight();
                            PDRectangle pageSize = page.findMediaBox();
                            y = pageSize.getHeight() - y;
                        }
                        Rectangle2D.Float awtRect = new Rectangle2D.Float(x, y, width, height);
                        stripper.addRegion(Integer.toString(f), awtRect);
                        stripper.extractRegions(page);
                        PrintTextLocation2 prt = new PrintTextLocation2();
                        if (pdfAnnot.getSubtype().equals("Square")) {
                            testTxt = testTxt + "\n " + stripper.getTextForRegion(Integer.toString(f));
                        }
                    }
                }
            } catch (Exception ex) {
            } finally {
                if (document != null) {
                    document.close();
                }
            }
        } catch (Exception ex) {
        }

通过使用此代码,我只能获取 PDF 文本。如何在文本中获取像 BOLD ITALIC 这样的字体信息。非常感谢您的建议或参考。

【问题讨论】:

  • 查看this answer 以了解一般过程(源自PDFTextStripper 并覆盖writeString)及其当前问题。提供给该方法的TextPosition 实例包含有关字体和绘制文本时其余当前状态的一些信息。是否必须从字体本身或某些图形状态中获取样式信息,取决于样式是如何生成的。

标签: java pdf fonts annotations pdfbox


【解决方案1】:

PDFTextStripperByArea 扩展的PDFTextStripper 规范化(即删除格式)文本(参见JavaDoc comment):

* This class will take a pdf document and strip out all of the text and ignore the
* formatting and such.

如果你看源码,你会看到字体信息在这个类中是可用的,但是在打印之前它被规范化了:

protected void writePage() throws IOException
{
    [...]
        List<TextPosition> line = new ArrayList<TextPosition>();
        [...]
            if(!overlap(positionY, positionHeight, maxYForLine, maxHeightForLine))
            {
                writeLine(normalize(line,isRtlDominant,hasRtl),isRtlDominant);
                line.clear();
                [...]
            }
............

ArrayList 中的TextPosition 实例具有所有格式信息。解决方案可以专注于根据需求重新定义现有方法。我在下面列出了一些选项:

  • private List normalize(List line, boolean isRtlDominant, boolean hasRtl)

如果你想要自己的normalize方法,你可以在你的项目中复制整个PDFTextStripper类并更改复制的代码。我们将这个新类称为MyPDFTextStripper,然后根据要求定义新方法。同样,将PDFTextStripperByArea 复制为MyPDFTextStripperByArea,这将扩展MyPDFTextStripper

  • 受保护的无效 writePage()

如果您只需要一个新的writePage 方法,您可以简单地扩展PDFTextStripper,并覆盖此方法,然后如上所述创建MyPDFTextStripperByArea

  • writeLine(normalize(line,isRtlDominant,hasRtl),isRtlDominant)

其他解决方案可能会通过将pre-normalization 信息存储在某个变量中然后使用它来覆盖 writeLine 方法。

希望这会有所帮助。

【讨论】:

  • 根据您采用的上述方法,您可能会遇到 PDFBox 问题PDFBOX-1804,该问题可能会在 1.8.4 版中得到解决。
  • 你知道如何离开,比如说,只有文本的“粗体”特征吗?
猜你喜欢
  • 1970-01-01
  • 2014-03-09
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
相关资源
最近更新 更多