0

0

使用Java和PDFBox在PDF中搜索文本及文件操作指南

心靈之曲

心靈之曲

发布时间:2025-11-24 13:02:02

|

748人浏览过

|

来源于php中文网

原创

使用Java和PDFBox在PDF中搜索文本及文件操作指南

本教程详细介绍了如何使用apache pdfbox库在java中高效地从pdf文件中提取文本,并在此基础上实现关键词搜索功能。文章将指导读者如何正确处理pdf文件(而非将其视为纯文本),如何在提取的文本中执行搜索,以及如何根据搜索结果将pdf文件复制或移动到指定目录,同时提供完整的代码示例和最佳实践。

1. 理解PDF文件特性与挑战

PDF(Portable Document Format)文件是一种复杂的二进制格式,它不仅仅包含文本,还包括字体、图像、矢量图形、布局信息等。因此,直接使用Java的 FileReader 或 BufferedReader 对PDF文件进行读取,并不能正确地获取其内部的文本内容。尝试这样做通常会导致乱码或错误,因为这些类是为处理纯文本文件设计的,它们无法解析PDF的内部结构。

要正确地从PDF文件中提取文本,我们需要借助专门的PDF处理库,这些库能够理解PDF的内部结构并解析出可读的文本。

2. 引入Apache PDFBox库

Apache PDFBox 是一个开源的Java库,用于处理PDF文档。它提供了丰富的API,可以执行各种PDF操作,包括创建、修改、打印、渲染和从PDF中提取文本等。

2.1 添加PDFBox依赖

在使用PDFBox之前,需要将其添加到项目的依赖中。如果你使用Maven,可以在 pom.xml 文件中添加以下依赖:

立即学习Java免费学习笔记(深入)”;

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.29</version> <!-- 请使用最新稳定版本 -->
</dependency>

如果你使用Gradle,可以在 build.gradle 文件中添加:

implementation 'org.apache.pdfbox:pdfbox:2.0.29' // 请使用最新稳定版本

3. 从PDF中提取文本

使用PDFBox从PDF文件中提取文本是实现搜索功能的第一步。

Flash Builder操作指南 中文WORD版
Flash Builder操作指南 中文WORD版

本文档主要讲述的是Flash Builder操作指南;Flash Builder将构成应用程序的资源(文件夹和文件)组合到一个容器中,我们将其称为项目。项目包含一组属性,这些属性控制应用程序的构建方式、构建的应用程序所在的位置、调试的处理方式以及该项目于工作空间中其他项目的关系。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载

3.1 核心步骤

  1. 加载PDF文档: 使用 PDDocument.load(File file) 方法加载一个PDF文件。
  2. 创建文本提取器: 实例化 PDFTextStripper 类,它是PDFBox中用于提取文本的核心组件。
  3. 获取文本: 调用 PDFTextStripper 对象的 getText(PDDocument document) 方法,传入已加载的 PDDocument 对象,即可获取PDF的全部文本内容。
  4. 关闭文档: 提取完成后,务必调用 PDDocument.close() 方法关闭文档,释放系统资源。建议使用 try-with-resources 语句确保文档被正确关闭。

3.2 文本提取示例代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;

public class PdfTextExtractor {

    public static String extractTextFromPdf(String filePath) throws IOException {
        File file = new File(filePath);
        // 使用 try-with-resources 确保 PDDocument 在使用后被关闭
        try (PDDocument document = PDDocument.load(file)) {
            PDFTextStripper pdfStripper = new PDFTextStripper();
            String text = pdfStripper.getText(document);
            return text;
        }
    }

    public static void main(String[] args) {
        String pdfPath = "D:\Sample.pdf"; // 替换为你的PDF文件路径
        try {
            String extractedText = extractTextFromPdf(pdfPath);
            System.out.println("PDF文件内容:
" + extractedText.substring(0, Math.min(extractedText.length(), 500)) + "..."); // 打印前500字
        } catch (IOException e) {
            System.err.println("提取PDF文本时发生错误: " + e.getMessage());
        }
    }
}

4. 在提取文本中执行搜索

一旦我们成功地从PDF中提取了所有文本内容(以 String 形式),就可以使用Java标准的字符串处理方法来执行关键词搜索。

4.1 常用搜索方法

  • String.contains(CharSequence s): 检查字符串是否包含指定的字符序列。这是最简单直接的检查是否存在某个词语的方法。
  • String.indexOf(String str): 返回指定子字符串第一次出现的索引,如果不存在则返回 -1。
  • Pattern 和 Matcher (正则表达式): 对于更复杂的搜索模式(如忽略大小写、全词匹配、模糊匹配等),可以使用Java的正则表达式API。

4.2 结合文本提取和搜索逻辑

以下示例展示了如何在提取的PDF文本中搜索一个或多个关键词:

import java.io.IOException;
import java.util.Scanner;

public class PdfTextSearcher {

    /**
     * 在PDF文本中搜索指定词语
     * @param pdfContent PDF文件的全部文本内容
     * @param searchWord 要搜索的词语
     * @param ignoreCase 是否忽略大小写
     * @return 如果找到词语则返回 true,否则返回 false
     */
    public static boolean searchInPdfContent(String pdfContent, String searchWord, boolean ignoreCase) {
        if (pdfContent == null || pdfContent.isEmpty() || searchWord == null || searchWord.isEmpty()) {
            return false;
        }
        if (ignoreCase) {
            return pdfContent.toLowerCase().contains(searchWord.toLowerCase());
        } else {
            return pdfContent.contains(searchWord);
        }
    }

    public static void main(String[] args) {
        String pdfPath = "D:\Sample.pdf"; // 替换为你的PDF文件路径
        String pdfContent = null;

        try {
            pdfContent = PdfTextExtractor.extractTextFromPdf(pdfPath);
        } catch (IOException e) {
            System.err.println("加载或提取PDF文本失败: " + e.getMessage());
            return;
        }

        if (pdfContent == null || pdfContent.isEmpty()) {
            System.out.println("PDF内容为空,无法执行搜索。");
            return;
        }

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要搜索的词语(输入 'Exit' 结束):");

        while (scanner.hasNextLine()) {
            String searchWord = scanner.nextLine().trim();
            if (searchWord.equalsIgnoreCase("Exit")) {
                break;
            }

            if (searchInPdfContent(pdfContent, searchWord, true)) { // 忽略大小写搜索
                System.out.println("是的,'" + searchWord + "' 在文件中。");
            } else {
                System.out.println("不,'" + searchWord + "' 不在文件中。");
            }
            System.out.println("请输入下一个要搜索的词语(输入 'Exit' 结束):");
        }
        scanner.close();
        System.out.println("搜索程序结束。");
    }
}

5. 根据搜索结果处理PDF文件

在确定PDF文件中包含特定关键词后,下一步是根据业务需求对文件进行操作,例如将其复制或移动到另一个目录。Java的 java.nio.file.Files 类提供了强大的文件操作功能。

5.1 文件复制与移动

  • Files.copy(Path source, Path target, CopyOption... options): 复制文件。
  • Files.move(Path source, Path target, CopyOption... options): 移动文件(剪切)。

常用的 CopyOption 包括:

  • StandardCopyOption.REPLACE_EXISTING: 如果目标文件已存在,则替换它。
  • StandardCopyOption.ATOMIC_MOVE: 以原子方式执行移动操作,确保操作要么完全成功,要么完全失败。

5.2 完整示例:搜索并根据结果复制/移动文件

以下是一个整合了PDF文本提取、关键词搜索和文件复制/移动功能的完整示例。

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Scanner;

public class PdfSearchAndFileOperation {

    public static void main(String[] args) {
        String sourcePdfPath = "C:\Users\user012\Desktop\Evalution.pdf"; // 替换为你的PDF文件路径
        String targetDirectoryPath = "C:\Users\user012\Desktop\Search\"; // 替换为目标目录路径

        // 1. 确保目标目录存在,如果不存在则创建
        Path targetDirPath = Paths.get(targetDirectoryPath);
        if (!Files.exists(targetDirPath)) {
            try {
                Files.createDirectories(targetDirPath);
                System.out.println("已创建目标目录: " + targetDirectoryPath);
            } catch (IOException e) {
                System.err.println("无法创建目标目录 '" + targetDirectoryPath + "': " + e.getMessage());
                return; // 无法创建目录则退出
            }
        }

        // 2. 尝试加载并提取PDF文本一次
        String pdfContent = null;
        try (PDDocument document = PDDocument.load(new File(sourcePdfPath))) {
            PDFTextStripper pdfStripper = new PDFTextStripper();
            pdfContent = pdfStripper.getText(document);
            System.out.println("PDF文本提取成功。");
        } catch (IOException e) {
            System.err.println("加载或提取PDF文本失败: " + e.getMessage());
            return; // 如果无法读取PDF,则退出程序
        }

        if (pdfContent == null || pdfContent.isEmpty()) {
            System.out.println("PDF内容为空,无法搜索。");
            return;
        }

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要搜索的词语(输入 'Exit' 结束):");

        // 3. 循环处理用户输入的搜索词
        boolean fileMovedOrCopied = false; // 标志位,确保文件只被操作一次
        while (scanner.hasNextLine()) {
            String searchWord = scanner.nextLine().trim();
            if (searchWord.equalsIgnoreCase("Exit")) {
                break;
            }

            // 4. 执行搜索(忽略大小写)
            if (pdfContent.toLowerCase().contains(searchWord.toLowerCase())) {
                System.out.println("是的,'" + searchWord + "' 在文件中。");

                // 5. 如果找到关键词且文件尚未被操作,则执行文件复制/移动
                if (!fileMovedOrCopied) {
                    Path sourcePath = Paths.get(sourcePdfPath);
                    Path destinationPath = targetDirPath.resolve(sourcePath.getFileName()); // 保持原文件名

                    try {
                        // 复制文件到目标目录
                        // 如果需要移动文件,请使用 Files.move() 代替 Files.copy()
                        // Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
                        Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
                        System.out.println("文件 '" + sourcePath.getFileName() + "' 已成功复制到 '" + targetDirectoryPath + "'。");
                        fileMovedOrCopied = true; // 设置标志位,避免重复操作
                    } catch (IOException e) {
                        System.err.println("复制文件失败: " + e.getMessage());
                    }
                } else {
                    System.out.println("文件已因之前的搜索结果被操作,不再重复。");
                }
            } else {
                System.out.println("不,'" + searchWord + "' 不在文件中。");
            }
            System.out.println("请输入下一个要搜索的词语(输入 'Exit' 结束):");
        }
        scanner.close();
        System.out.println("程序结束。");
    }
}

6. 注意事项与最佳实践

  • 资源管理: 始终使用 try-with-resources 语句来加载 PDDocument,确保在处理完成后自动关闭文档并释放资源,避免内存泄漏。
  • 异常处理: 对文件I/O操作(如 IOException)进行适当的异常处理,以提高程序的健壮性。
  • 性能考量: 对于非常大的PDF文件,提取文本可能会消耗较多的内存和时间。如果需要处理大量文件或超大文件,可能需要考虑分批处理或优化内存使用。
  • PDF复杂性: PDFBox在处理大多数PDF文件时表现良好,但对于某些非常复杂、损坏或加密的PDF文件,文本提取可能会失败或不完整。
    • 加密PDF: 如果PDF文件受密码保护,PDDocument.load() 方法可能需要提供密码参数。
    • 图片PDF (扫描件): 如果PDF文件是扫描件(即只包含图像而没有可选择的文本层),PDFBox将无法提取文本。在这种情况下,你需要结合OCR(光学字符识别)技术(如Tesseract)来识别图像中的文本。
  • 文本格式: PDFBox提取的文本可能不总是完美地保留原始布局和格式,尤其是在处理多列、复杂表格或特殊排版的文档时。在搜索前,你可能需要对提取的文本进行额外的清洗和标准化。
  • 文件操作: Files.copy() 和 Files.move() 是原子操作,但如果目标路径已存在且未指定 REPLACE_EXISTING 选项,则会抛出 FileAlreadyExistsException。根据你的需求选择合适的 CopyOption。

通过遵循本教程的指导,你可以有效地利用Apache PDFBox库在Java应用程序中实现PDF文本搜索和文件自动化处理功能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

258

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

765

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

219

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

356

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

244

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

547

2023.12.06

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.2万人学习

C# 教程
C# 教程

共94课时 | 10.8万人学习

Java 教程
Java 教程

共578课时 | 78.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号