武汉市网站建设_网站建设公司_Bootstrap_seo优化
2026/1/7 21:09:48 网站建设 项目流程

一、引言:PDF文本提取的重要性

在现代软件开发中,PDF文件处理是一个常见需求。无论是从网络下载的PDF文档,还是用户上传的PDF文件,我们经常需要提取其中的文本内容进行进一步处理。例如:文档搜索、内容分析、信息归档等场景。

Apache PDFBox作为Java平台上一个成熟的开源库,提供了强大的PDF处理能力。本文将详细介绍如何基于PDFBox构建一个功能完善的PDF文本提取工具类,支持从网络URL和本地文件流中提取文本。

二、技术选型:为什么选择Apache PDFBox?

在Java生态中,处理PDF的库有多种选择,如iText、Apache PDFBox等。我们选择PDFBox的主要原因包括:

  • 完全开源且免费(Apache 2.0许可证)

  • 功能全面,支持文本提取、创建、渲染等

  • 社区活跃,文档完善

  • 与其他Apache项目良好集成

三、工具类完整实现

3.1 导入依赖

<!-- 用于 Java 项目中处理 PDF 文件 --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.24</version> </dependency>

3.2 PDFUtil工具类

import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.util.Strings; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.regex.Pattern; /** * PDF处理工具类 * 提供从PDF文件中提取文本内容的功能 * <p> * 主要功能: * 1. 从网络URL下载PDF文件并提取文本 * 2. 从本地文件流中提取PDF文本 * 3. 支持自定义超时设置 * 4. 提供文本格式化选项(如去除空白字符) * */ @Slf4j public class PDFUtil { /** * 正则表达式模式:用于匹配和替换空白字符 * \s* : 匹配零个或多个空白字符(如空格) * | : 或的关系,表示匹配任意一个模式 * \t : 匹配制表符(Tab键产生的缩进) * \r : 匹配回车符(旧系统的换行符) * \n : 匹配换行符(新行的开始) * <p> * 示例:将"Hello\tWorld\n" 替换为 "HelloWorld" */ private static final Pattern PATTERN = Pattern.compile("\\s*|\t|\r|\n"); /** * 默认连接超时时间:10秒(单位:毫秒) * 含义:建立网络连接的最大等待时间 * 超过此时间仍未连接成功则抛出超时异常 */ private static final Integer DEFAULT_CONNECT_TIMEOUT = 10000; /** * 默认读取超时时间:10秒(单位:毫秒) * 含义:从连接读取数据的最大等待时间 * 超过此时间仍未读取到数据则抛出超时异常 */ private static final Integer DEFAULT_READ_TIMEOUT = 10000; /** * 从网络URL的PDF文件中提取文本内容(使用默认超时设置) * * @throws RuntimeException 如果URL无效、网络连接失败或PDF解析失败 * 使用场景:快速从已知URL提取PDF文本,无需关心超时设置 */ public static String parsingTextFromPdf(String pdfUrl) { // 调用重载方法,传入默认的超时参数 return parsingTextFromPdf(pdfUrl, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT); } /** * 从网络URL的PDF文件中提取文本内容,并去除所有空白字符 * * @param pdfUrl PDF文件的网络地址 * @return 清理后的文本内容(无空格、制表符、换行符等空白字符) * 示例:原文本"Hello\n World" 返回 "HelloWorld" * <p> * 使用场景:当只需要PDF的文字内容,不需要格式信息时 * 常用于文本搜索、关键词提取等场景 */ public static String parsingTextFromPdfRemovePattern(String pdfUrl) { // 1. 先提取原始文本(包含空白字符) String text = parsingTextFromPdf(pdfUrl, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT); // 2. 使用正则表达式移除所有空白字符 // PATTERN.matcher(text): 创建文本匹配器 // .replaceAll(Strings.EMPTY): 将所有匹配到的空白字符替换为空字符串 String textRemovePattern = PATTERN.matcher(text).replaceAll(Strings.EMPTY); return textRemovePattern; } /** * 从指定URL的PDF文件中提取文本内容(可自定义超时时间) * * @param pdfUrl PDF文件的网络地址,必须是有效的URL格式 * @param connectTimeout 连接超时时间(毫秒) * 建议值:5000-30000(5-30秒) * 设置为0表示无限等待(不推荐) * @param readTimeout 读取超时时间(毫秒) * 建议值:10000-60000(10-60秒) * 根据PDF文件大小调整,大文件需要更长超时时间 * @return 提取的文本内容 * @throws RuntimeException 可能抛出以下异常: * 1. MalformedURLException - URL格式错误 * 2. ConnectTimeoutException - 连接超时 * 3. ReadTimeoutException - 读取超时 * 4. IOException - 网络IO错误 * 5. PDF解析相关异常 * <p> * 内部执行流程: * 1. 验证URL格式 * 2. 建立HTTP连接(设置超时和重定向) * 3. 获取输入流 * 4. 解析PDF文本 * 5. 清理连接资源 * <p> * 注意:无论成功或失败,都会确保关闭网络连接 */ public static String parsingTextFromPdf(String pdfUrl, Integer connectTimeout, Integer readTimeout) { try { // 步骤1:将字符串URL转换为Java URL对象 // 如果URL格式不正确,此处会抛出MalformedURLException URL url = new URL(pdfUrl); // 步骤2:创建并配置HTTP连接 HttpURLConnection connection = createHttpConnection(url, connectTimeout, readTimeout); // 步骤3:获取PDF文件输入流 // try-with-resources语句:确保inputStream在使用后自动关闭 try (InputStream inputStream = connection.getInputStream()) { // 步骤4:从输入流中解析PDF文本 return parsingTextFromStream(inputStream); } finally { // 步骤5:无论成功或失败,都断开网络连接释放资源 connection.disconnect(); } } catch (Exception e) { throw new RuntimeException("读取PDF文件失败,原因:{}", e); } } /** * 从输入流中提取PDF文本内容(核心提取逻辑) * * @param inputStream PDF文件的输入流 * 可以是:网络流、文件流、内存流等 * 调用方负责提供和关闭流(本方法内不关闭输入流) * @return 提取的文本内容 * @throws RuntimeException PDF解析失败时抛出 * <p> * 技术原理: * 使用Apache PDFBox库: * 1. PDDocument.load() - 加载PDF文档到内存 * 2. PDFTextStripper - 提取文本的专用工具类 * 3. setSortByPosition(true) - 按页面位置排序文本,保持阅读顺序 * 4. setStartPage()/setEndPage() - 设置提取的页码范围 * <p> * 性能提示: * - 大PDF文件会占用较多内存 * - 考虑使用PDFTextStripper的增量读取功能处理大文件 */ public static String parsingTextFromStream(InputStream inputStream) { try { // 步骤1:加载PDF文档到内存 // PDDocument是PDFBox的核心类,代表整个PDF文档 PDDocument document = PDDocument.load(inputStream); // 步骤2:创建文本提取器 PDFTextStripper stripper = new PDFTextStripper(); // 步骤3:配置提取器 stripper.setSortByPosition(true); // 按位置排序:从左到右、从上到下 stripper.setStartPage(0);// 从第1页开始(页码从0开始) stripper.setEndPage(document.getNumberOfPages());// 提取到最后一页 String text = stripper.getText(document); // 步骤5:关闭文档释放资源(重要!) document.close(); return text; } catch (Exception e) { throw new RuntimeException("读取PDF文本内容失败,原因:{}", e); } } /** * 创建并配置HTTP连接(私有辅助方法) * * @param url 目标URL * @param connectTimeout 连接超时时间(毫秒) * @param readTimeout 读取超时时间(毫秒) * @return 配置好的HttpURLConnection对象 * @throws Exception 如果连接创建失败 * <p> * 配置说明: * 1. GET请求:因为只是下载文件,不需要提交数据 * 2. 设置超时:防止网络问题导致线程长时间阻塞 * 3. 允许重定向:自动跟随302/301跳转 * 4. 使用默认的User-Agent和请求头 * */ private static HttpURLConnection createHttpConnection(URL url, Integer connectTimeout, Integer readTimeout) throws Exception { // 打开URL连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为GET(获取资源) connection.setRequestMethod("GET"); // 设置连接超时(建立TCP连接的最大等待时间) connection.setConnectTimeout(connectTimeout); // 设置读取超时(从服务器读取数据的最大等待时间) connection.setReadTimeout(readTimeout); // 允许自动重定向(如果服务器返回302/301,自动跳转到新地址) connection.setInstanceFollowRedirects(true); return connection; } }

四、使用示例

4.1 从网络URL提取PDF文本内容

@RequestMapping("pdfToHttpUrl") public IResult pdfToHttpUrl() { String url = "https://gitee.com/lyilan8080/loser-res/raw/master/video/66.pdf"; String text = PDFUtil.parsingTextFromPdf(url); return new ResultBean<>(text); }

网络PDF文件处理流程:

  1. 通过URL访问PDF文件

  2. 建立HTTP连接并设置超时时间

  3. 获取输入流并解析PDF

  4. 返回提取的文本内容


地址(https://gitee.com/lyilan8080/loser-res/raw/master/video/66.pdf)的PDF内容如下:


返回结果:

4.2 从文件流提取PDF文本内容

@RequestMapping("pdfToFile") public IResult pdfToFile(MultipartFile file) throws IOException { String text = PDFUtil.parsingTextFromStream(file.getInputStream()); return new ResultBean<>(text); }

本地文件处理流程:

  1. 接收用户上传的PDF文件

  2. 获取文件输入流

  3. 直接调用工具类方法解析文本

  4. 返回提取结果


传递一个66.pdf文件(和上面网络访问的是同一个文件)

返回结果:

五、总结

本文介绍的PDFUtil工具类提供了一个简单而强大的解决方案,用于从PDF文件中提取文本内容。通过合理的设计和封装,它能够:

  1. 处理多种来源:支持网络URL和本地文件流

  2. 配置灵活:可自定义超时时间和文本处理选项

  3. 健壮可靠:完善的异常处理和资源管理

  4. 易于使用:简洁的API设计,开箱即用

这个工具类已经包含了日常开发中最常见的PDF文本提取需求,可以直接集成到你的Java项目中。当然,根据具体业务场景,你还可以在此基础上进一步扩展功能,满足更多复杂需求。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询