使用PDFBox获取文本行的位置

时间:2015-10-06 19:33:12

标签: java pdf pdfbox

我正在使用PDFBox从pdf中提取信息,我当前试图找到的信息与该行中第一个字符的x位置有关。我找不到任何与如何获取该信息有关的内容。我知道pdfbox有一个叫做TextPosition的类,但我也找不到如何从PDDocument中获取TextPosition对象。如何从pdf获取一行文本的位置信息?

1 个答案:

答案 0 :(得分:13)

一般

要使用PDFBox提取文本(包含或不包含位置,颜色等额外信息),您可以实例化PDFTextStripper或从中派生的类,并使用它:

PDFTextStripper stripper = new PDFTextStripper();
String text = stripper.getText(document);

(有许多PDFTextStripper属性允许您限制从中提取文本的页面。)

在执行getText的过程中,将解析相关页面的内容流(以及从这些页面引用的xObject形式的内容流),并处理文本绘图命令。

如果要更改文本提取行为,则必须通过重写此方法来更改此文本绘制命令处理,这通常应该执行此操作:

/**
 * Write a Java string to the output stream. The default implementation will ignore the <code>textPositions</code>
 * and just calls {@link #writeString(String)}.
 *
 * @param text The text to write to the stream.
 * @param textPositions The TextPositions belonging to the text.
 * @throws IOException If there is an error when writing the text.
 */
protected void writeString(String text, List<TextPosition> textPositions) throws IOException
{
    writeString(text);
}

如果您还需要知道新行何时开始,您可能还想覆盖

/**
 * Write the line separator value to the output stream.
 * @throws IOException
 *             If there is a problem writing out the lineseparator to the document.
 */
protected void writeLineSeparator( ) throws IOException
{
    output.write(getLineSeparator());
}

writeString可以被覆盖以将文本信息引导到单独的成员中(例如,如果您可能希望结果采用比String更结构化的格式),或者可以覆盖它以简单地添加一些结果String中的额外信息。

可以重写

writeLineSeparator以触发行之间的某些特定输出。

有更多方法可以覆盖,但一般情况下你不太可能需要它们。

在手头的情况下

  

我使用PDFBox从pdf中提取信息,我当前想要查找的信息与该行中第一个字符的x位置有关。

这可以如下实现(只需在每行的开头添加信息):

PDFTextStripper stripper = new PDFTextStripper()
{
    @Override
    protected void startPage(PDPage page) throws IOException
    {
        startOfLine = true;
        super.startPage(page);
    }

    @Override
    protected void writeLineSeparator() throws IOException
    {
        startOfLine = true;
        super.writeLineSeparator();
    }

    @Override
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException
    {
        if (startOfLine)
        {
            TextPosition firstProsition = textPositions.get(0);
            writeString(String.format("[%s]", firstProsition.getXDirAdj()));
            startOfLine = false;
        }
        super.writeString(text, textPositions);
    }
    boolean startOfLine = true;
};

text = stripper.getText(document);

extractLineStart测试的ExtractText.java方法testExtractLineStartFromSampleFile