4

这似乎是一个老问题,但是在花了半个小时搜索整个 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()andsetAverageCharacterTolerance() PDFTextStripper方法,在标准值之上和之下设置不同的值(仅供参考,分别为 0.5 和 0.3),但输出根本没有改变。我哪里错了?提前致谢。

4

2 回答 2

4

正如 Joey 所提到的,PDF 只是一组说明,告诉您应该在哪里打印某个字符。

为了提取单词或行,您必须执行一些数据分割:研究字符的边界框应该可以让您识别出在同一行上的那些,然后识别出哪个构成单词。

于 2012-06-04T10:02:43.890 回答
1

这是您的解决方案: 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();
            }
        }
    }
}
于 2020-02-26T11:05:29.373 回答