如何使用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 中的其他内容,如图像或矢量图形。目前我还没有用到,日后需要解析非文字内容再做解析。

相关推荐
程序猿大帅2 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪3 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly3 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨4 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜4 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端
SimonKing10 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户2986985301411 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
小bo波1 天前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
nanxun8862 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103512 天前
Day01 | Java 基础(Java SE)
java