从PDF中提取包含字符串位置的所有文本

时间:2012-04-02 10:49:36

标签: java pdfbox pdf-parsing

这似乎是一个老问题,但是我花了半个小时在SO上搜索后找不到详尽的答案。

我正在使用PDFBox,我想从PDF文件中提取所有文本以及每个字符串的坐标。我正在使用他们的PrintTextLocations示例(http://pdfbox.apache.org/apidocs/org/apache/pdfbox/examples/util/PrintTextLocations.html)但是我正在使用的那种pdf(电子票证)程序无法识别字符串,分别打印每个字符。输出是一个字符串列表(每个字符串代表一个TextPosition对象),如下所示:

String[414.93896,637.2442 fs=1.0 xscale=8.0 height=4.94 space=2.2240002 width=4.0] s
String[418.93896,637.2442 fs=1.0 xscale=8.0 height=4.94 space=2.2240002 width=4.447998] a
String[423.38696,637.2442 fs=1.0 xscale=8.0 height=4.94 space=2.2240002 width=1.776001] l
String[425.16296,637.2442 fs=1.0 xscale=8.0 height=4.94 space=2.2240002 width=4.447998] e

虽然我希望程序能够将字符串“sale”识别为唯一的TextPosition并给我它的位置。 我还尝试使用setSpacingTolerance()setAverageCharacterTolerance() PDFTextStripper方法,在标准值之上和之下设置不同的值(FYI分别为0.5和0.3),但输出没有彻底改变。我哪里错了?提前谢谢。

2 个答案:

答案 0 :(得分:4)

正如乔伊所说,PDF只是一系列说明,告诉你应该打印某个角色。

为了提取单词或行,你必须进行一些数据分割:研究字符的边界框应该让你识别出同一行的那些,然后是哪一个形成单词。

答案 1 :(得分:0)

这是您的解决方案: 1.读取文件 2.使用PDFParserTextStripper将每个页面提取到文本 3.文本的每个位置将按字符打印。

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
class PDFParserTextStripper extends PDFTextStripper {
    public PDFParserTextStripper(PDDocument pdd) throws IOException {
        super();
        document = pdd;
    }
    public void stripPage(int pageNr) throws IOException {
        this.setStartPage(pageNr + 1);
        this.setEndPage(pageNr + 1);
        Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
        writeText(document, dummy); // This call starts the parsing process and calls writeString repeatedly.
    }
    @Override
    protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
        for (TextPosition text : textPositions) {
            System.out.println("String[" + text.getXDirAdj() + "," + text.getYDirAdj() + " fs=" + text.getFontSizeInPt()
                    + " xscale=" + text.getXScale() + " height=" + text.getHeightDir() + " space="
                    + text.getWidthOfSpace() + " width=" + text.getWidthDirAdj() + " ] " + text.getUnicode());
        }
    }
    public static void extractText(InputStream inputStream) {
        PDDocument pdd = null;
        try {
            pdd = PDDocument.load(inputStream);
            PDFParserTextStripper stripper = new PDFParserTextStripper(pdd);
            stripper.setSortByPosition(true);
            for (int i = 0; i < pdd.getNumberOfPages(); i++) {
                stripper.stripPage(i);
            }
        } catch (IOException e) {
            // throw error
        } finally {
            if (pdd != null) {
                try {
                    pdd.close();
                } catch (IOException e) {
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {
        File f = new File("C://PDFLOCATION//target.pdf");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(f);
            extractText(fis);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}