【问题标题】:Extract all text with string positions from a PDF从 PDF 中提取所有带有字符串位置的文本
【发布时间】:2012-04-02 10:49:36
【问题描述】:

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

【问题讨论】:

  • 啊,PDF的乐趣。根据创建它的原因,很可能 »text« 只是某些位置的字形集合,因此您必须根据位置进行猜测以找出单词和空格的位置。

标签: java pdfbox pdf-parsing


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回复。这就是我最终要做的事情:为每个 PDF“模板”创建一组矩形,并将其应用于基于位置提取文本部分。这将需要大量的手动工作来维护,但这似乎是唯一可靠的方法。
【解决方案2】:

这是您的解决方案: 1.读取文件 2. 使用 PDFParserTextStripper 获取每个页面到文本 3.文本的每个位置都会以char打印。

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();
            }
        }
    }
}

【讨论】:

  • 请补充说明,你是如何得出这个结果的。
  • 该代码类似于 PrintTextLocations 示例。
  • 完全一样的概念。
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 2022-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多