如何使用java来解析一个pdf文件呢?

最近搞到一个任务是要解析一套雅思题目并提取其中的高频单词。那如何使用java来解析一个pdf文件呢?

首先我们要知道这需要springboot框架来进行创建,需要的PDFTextStripper是一个用于PDF文档中提取文本的类,它是Apache PDFBox的一个类用于处理PDF文档的开源的库。其主要功能是解析文档的内容流,所以我们需要定义一个流来提取其中的文字内容。

所以我们先引入pdfbox相关的依赖,具体如下:

java 复制代码
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>fontbox</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>jempbox</artifactId>
    <version>1.8.11</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>xmpbox</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>preflight</artifactId>
    <version>2.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-tools</artifactId>
    <version>2.0.0</version>
</dependency>

这是比较完整的一套依赖。我们把提交pdf和接收pdf用一种post的方式进行上传,这样会显得提交方式非常的灵活。

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Upload PDF</title>
</head>
<body>
<h1>Upload PDF File</h1>
<form action="/api/files/upload-pdf" method="post" enctype="multipart/form-data">
    <input type="file" name="file" accept="application/pdf" required>

    <button type="submit">Upload</button>
</form>
</body>
</html>

然后我们简单写一个controller

java 复制代码
@RestController
@RequestMapping("/api/files")
public class ReadFileController {
    @Autowired
    private ExtractService extractService;
    @PostMapping("/upload-pdf")
    public ResponseEntity<Object> uploadPdf(@RequestParam("file") MultipartFile file) {
        // 验证文件是否为空
        if (file.isEmpty()) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("File is empty");
        }

        // 验证文件类型是否为PDF
        if (!"application/pdf".equals(file.getContentType())) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Only PDF files are allowed");
        }
        String file_name = file.getOriginalFilename();
        
        String filePath = extractService.Run(file,file_name);

我们可以看到表单提交的action就是我们controller里面的路径,提交之后我们在做一个简单的文件类型判断之后就返回给了业务层进行解析。

java 复制代码
private StringBuilder accumulatedText = new StringBuilder();
public List<Map.Entry<String, Integer>> read_file(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            try (PDDocument doc = PDDocument.load(inputStream)) {
                PDFTextStripper textStripper = new PDFTextStripper();
                textStripper.setSortByPosition(true);

                String allText = textStripper.getText(doc);
                accumulatedText.append(allText).append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return getSortedWordList(accumulatedText.toString());
    }

这段代码首先通过file.getInputStream()获取上传文件对应的输入流,这个过程就避免了我们先把文件存到磁盘,而是直接从文件中读数据。PDDocumentApache PDFBox库中的一个类,用于表示PDF文档。此语句确保了PDDocument对象在使用后会被正确关闭。PDFTextStripper Apache PDFBox 库中的一个类,用于从 PDF 文档中提取文本。它提供了一种简单而有效的方法来遍历 PDF 的内容,并将其中的文本元素抽取出来形成字符串。PDFTextStripper 可以解析 PDF 页面上的文本对象,并将它们转换为可读的字符串格式。通过设置 setSortByPosition(true),可以确保提取的文本按照其在页面上的实际位置进行排序,这有助于保持文本的自然阅读顺序。默认情况下,PDFTextStripper 按照文本对象在 PDF 文件中的出现顺序提取文本,这可能会导致文本顺序混乱。

StringBuilder 是 Java 中的一个类,它提供了可变的字符序列,允许你高效地构建、修改和操作字符串。与 String 类不同,String 是不可变的(immutable),每次对 String 的修改都会创建一个新的 String 对象,而 StringBuilder 是可变的(mutable),可以在同一个对象上进行多次修改而不创建新的对象。这使得 StringBuilder 在需要频繁修改字符串的情况下更加高效。

尽管 PDFTextStripper 主要用于文本提取,但它也可以与 PDFStreamEngine 结合使用,以处理 PDF 中的其他内容,如图像或矢量图形。目前我还没有用到,日后需要解析非文字内容再做解析。

相关推荐
躺平大鹅1 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者2 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺2 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart3 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP4 小时前
MyBatis-mybatis入门与增删改查
java
孟陬8 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌8 小时前
一站式了解四种限流算法
java·后端·go
华仔啊8 小时前
Java 开发千万别给布尔变量加 is 前缀!很容易背锅
java
也些宝9 小时前
Java单例模式:饿汉、懒汉、DCL三种实现及最佳实践
java