如何使用Apache PDFBox从PDF文件中提取文本

38
我希望能够使用Apache PDFBox从给定的PDF文件中提取文本。我编写了以下代码:
```html

I would like to extract text from a given PDF file with Apache PDFBox.

I wrote this code:

```
PDFTextStripper pdfStripper = null;
PDDocument pdDoc = null;
COSDocument cosDoc = null;
File file = new File(filepath);

PDFParser parser = new PDFParser(new FileInputStream(file));
parser.parse();
cosDoc = parser.getDocument();
pdfStripper = new PDFTextStripper();
pdDoc = new PDDocument(cosDoc);
pdfStripper.setStartPage(1);
pdfStripper.setEndPage(5);
String parsedText = pdfStripper.getText(pdDoc);
System.out.println(parsedText);

然而,我遇到了以下错误:

Exception in thread "main" java.lang.NullPointerException
at org.apache.fontbox.afm.AFMParser.main(AFMParser.java:304)

我将pdfbox-1.8.5.jar和fontbox-1.8.5.jar添加到类路径中。

编辑

我在程序开头添加了System.out.println("程序开始");

我运行了程序,然后得到了与上面提到的相同的错误,并且程序开始没有出现在控制台中。

因此,我认为我可能有一个类路径或其他问题。

谢谢。


可能你的PDF文件不完全有效,导致PDFBox出现问题。你可能需要提供PDF文件进行检查。 - mkl
1
你确定你启动了正确的 main() 方法吗?异常看起来像是你启动了 org.apache.fontbox.afm.AFMParsermain(),这个看起来是 PDFBox 的代码,而不是你的代码。 - mkl
你说得对。我重置了运行配置,现在程序可以正常工作了。非常感谢你,mkl。 - Benben
5个回答

54

使用PDFBox 2.0.7,以下是我获取PDF文本的方式:

static String getText(File pdfFile) throws IOException {
    PDDocument doc = PDDocument.load(pdfFile);
    return new PDFTextStripper().getText(doc);
}

按照以下方式调用:

try {
    String text = getText(new File("/home/me/test.pdf"));
    System.out.println("Text in PDF: " + text);
} catch (IOException e) {
    e.printStackTrace();
}

鉴于用户oivemaria在评论中提出了问题:

您可以通过将PDFBox添加到build.gradle的依赖项中,在应用程序中使用它:


dependencies {
  compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.7'
}

点击此处了解使用 Gradle 进行依赖管理的更多信息。


如果您想在解析后的文本中保留 PDF 的格式,请尝试使用 PDFLayoutTextStripper


1
这比被接受的答案更好。我使用相同的方法获取资源作为InputStream,以从“src\resources”文件夹加载文件。您还可以使用来自m2repo https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox 的maven依赖项。 - Lucky
1
使用完 PPDocument 后需要关闭它。 - DKMDebugin

36

我执行了你的代码并且它运行正常。也许你的问题与你给文件的FilePath有关。我将我的PDF文件放在C盘中并硬编码了文件路径。这是我的代码:

// PDFBox 2.0.8 require org.apache.pdfbox.io.RandomAccessRead
// import org.apache.pdfbox.io.RandomAccessFile;

public class PDFReader{
    public static void main(String args[]) throws IOException {
        PDFTextStripper pdfStripper = null;
        PDDocument pdDoc = null;
        File file = new File("C:/my.pdf");
        PDFParser parser = new PDFParser(new FileInputStream(file));
        parser.parse();
        try (COSDocument cosDoc = parser.getDocument()) {
            pdfStripper = new PDFTextStripper();
            pdDoc = new PDDocument(cosDoc);
            pdfStripper.setStartPage(1);
            pdfStripper.setEndPage(5);
            String parsedText = pdfStripper.getText(pdDoc);
            System.out.println(parsedText);
        }
    }
}

当我们从计算机获取PDF文件时,它可以正常工作。但是我尝试从Android的SD卡中获取它时,它会出现错误,如“java.lang.ClassNotFoundException:在路径上找不到类” java.awt.print.Printable“:DexPathList [[zip文件”/ data / app / com.geeklabs.pdfreader-1 / base.apk“],nativeLibraryDirectories = [/ vendor / lib,/ system / lib]]”。 - Shailendra Madda
即使将库添加到构建路径中,仍然会出现“java.lang.NoClassDefFoundError: org.pdfbox.pdmodel.PDDocument”的错误。 - Shailendra Madda
PDFbox怎么用?我对这个概念很新,但不知道从哪里开始。我已经下载了jar文件,但双击它没有反应。 - oivemaria
7
使用pdfbox 2.0.5版本,此代码无法编译,出现错误:java.io.FileInputStream无法转换为org.apache.pdfbox.io.RandomAccessRead。 - Asu
2
构造函数PDFParser(FileInputStream)未定义,给定错误的转换为org.apache.pdfbox.io.RandomAccessRead。 - Walid Bousseta
显示剩余2条评论

6

PdfBox 2.0.3还有一个命令行工具。

  1. 下载jar文件
  2. java -jar pdfbox-app-2.0.3.jar ExtractText [OPTIONS] <inputfile> [output-text-file]
Options:
  -password  <password>        : Password to decrypt document
  -encoding  <output encoding> : UTF-8 (default) or ISO-8859-1, UTF-16BE, UTF-16LE, etc.
  -console                     : Send text to console instead of file
  -html                        : Output in HTML format instead of raw text
  -sort                        : Sort the text before writing
  -ignoreBeads                 : Disables the separation by beads
  -debug                       : Enables debug output about the time consumption of every stage
  -startPage <number>          : The first page to start extraction(1 based)
  -endPage <number>            : The last page to extract(inclusive)
  <inputfile>                  : The PDF document to use
  [output-text-file]           : The file to write the text to

2

Maven依赖:

    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.9</version>
    </dependency>

然后是获取PDF文本字符串的函数。
private static String readPDF(File pdf) throws InvalidPasswordException, IOException {
    try (PDDocument document = PDDocument.load(pdf)) {

        document.getClass();

        if (!document.isEncrypted()) {

            PDFTextStripperByArea stripper = new PDFTextStripperByArea();
            stripper.setSortByPosition(true);

            PDFTextStripper tStripper = new PDFTextStripper();

            String pdfFileInText = tStripper.getText(document);
            // System.out.println("Text:" + st);

            // split by whitespace
            String lines[] = pdfFileInText.split("\\r?\\n");
            List<String> pdfLines = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            for (String line : lines) {
                System.out.println(line);
                pdfLines.add(line);
                sb.append(line + "\n");
            }
            return sb.toString();
        }

    }
    return null;
}

1

使用pdfbox 2.0.6从具有文本内容的PDF文件中提取数据的功能良好。

import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.PDFTextStripperByArea;

public class PDFTextExtractor {
   public static void main(String[] args) throws IOException {
       System.out.println(readParaFromPDF("C:\\sample1.pdf",3, "Enter Start Text Here", "Enter Ending Text Here"));
    //Enter FilePath, Page Number, StartsWith, EndsWith
   }
   public static String readParaFromPDF(String pdfPath, int pageNo, String strStartIndentifier, String strEndIdentifier) {
       String returnString = "";
       try {
           PDDocument document = PDDocument.load(new File(pdfPath));
           document.getClass();        
           if (!document.isEncrypted()) {
               PDFTextStripperByArea stripper = new PDFTextStripperByArea();
               stripper.setSortByPosition(true);
               PDFTextStripper tStripper = new PDFTextStripper();
               tStripper.setStartPage(pageNo);
               tStripper.setEndPage(pageNo);
               String pdfFileInText = tStripper.getText(document);
               String strStart = strStartIndentifier;
               String strEnd = strEndIdentifier;
               int startInddex = pdfFileInText.indexOf(strStart);
               int endInddex = pdfFileInText.indexOf(strEnd);
               returnString = pdfFileInText.substring(startInddex, endInddex) + strEnd;
           }
          } catch (Exception e) {
              returnString = "No ParaGraph Found";
       }
            return returnString;
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接