Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从PDF中提取具有字符串位置的所有文本_Java_Pdfbox_Pdf Parsing - Fatal编程技术网

Java 从PDF中提取具有字符串位置的所有文本

Java 从PDF中提取具有字符串位置的所有文本,java,pdfbox,pdf-parsing,Java,Pdfbox,Pdf Parsing,这似乎是一个老生常谈的问题,但我花了半个小时到处搜索,却没有找到一个详尽的答案 我正在使用PDFBox,我想从PDF文件中提取所有文本以及每个字符串的坐标。我使用的是他们的PrintTextLocationsexample(),但对于我使用的那种pdf(电子票据),程序无法识别字符串,无法分别打印每个字符。输出是一个字符串列表(每个字符串表示TextPosition对象),如下所示: String[414.93896,637.2442 fs=1.0 xscale=8.0 height=4.94

这似乎是一个老生常谈的问题,但我花了半个小时到处搜索,却没有找到一个详尽的答案

我正在使用PDFBox,我想从PDF文件中提取所有文本以及每个字符串的坐标。我使用的是他们的
PrintTextLocations
example(),但对于我使用的那种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
,并给出其位置。
我还尝试使用
setPacingTolerance()
setAverageCharacterTolerance()
PDFTextStripper
方法,在标准值上方和下方设置不同的值(参考值分别为0.5和0.3),但输出根本没有改变。我哪里做错了?提前谢谢。

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

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

以下是您的解决方案: 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();
            }
        }
    }
}
import java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStreamWriter;
导入java.io.Writer;
导入java.util.List;
导入org.apache.pdfbox.pdmodel.PDDocument;
导入org.apache.pdfbox.text.PDFTextStripper;
导入org.apache.pdfbox.text.TextPosition;
类PDFParserTextStripper扩展了PDFTextStripper{
公共PDFParserTextStripper(PDDocument pdd)引发IOException{
超级();
文件=pdd;
}
public void stripPage(int pageNr)引发IOException{
本.设置起始页(第n+1页);
此.setEndPage(第1页+1页);
Writer dummy=newoutputstreamwriter(newbytearrayoutputstream());
writeText(document,dummy);//此调用启动解析过程并重复调用writeString。
}
@凌驾
受保护的void writeString(字符串、列表textPositions)引发IOException{
用于(文本位置文本:文本位置){
System.out.println(“字符串[”+text.getXDirAdj()+”,“+text.getYDirAdj()+”fs=“+text.getFontSizeInput())
+“xscale=“+text.getXScale()+”height=“+text.getHeightDir()+”space=”
+text.getWidthOfSpace()+“width=“+text.getWidthDirAdj()+”]“+text.getUnicode());
}
}
公共静态void提取器文本(InputStream InputStream){
pdd文件pdd=null;
试一试{
pdd=PDDocument.load(inputStream);
PDFParserTextStripper剥离器=新PDFParserTextStripper(pdd);
脱扣器。设置端口BYPOSITION(真);
对于(int i=0;i
啊,PDF的乐趣。根据创建它的原因,很可能»text«只是某些位置的一组字形,因此您必须根据位置进行猜测,以找出单词和空格的位置。谢谢您的回答。这就是我最后要做的:为每个PDF“模板”创建一组矩形,并应用这些矩形根据位置提取部分文本。这将需要进行大量的手动维护,但这似乎是唯一可靠的方法。请添加一个解释,说明您是如何得出此结果的。该代码与PrintTextLocations示例类似。概念完全相同。