从 PDF 文件中提取文本是 Java 开发中常见的需求,适用于文档解析、数据提取、全文索引和发票识别等自动处理流程。PDF 中的内容可能是可搜索的文本,也可能是通过扫描得到的图片。不同类型的 PDF在提取方式上有明显差异。
本文将详细介绍如何使用 Java 从文本型 PDF 和扫描型 PDF 中提取文本,包含完整的代码示例和说明。不论您处理的是报告、发票还是扫描文档,本指南都将帮助您快速实现PDF文本提取任务。
目录
- 为什么要使用 Java 提取 PDF 文本
- 文本型 PDF 与扫描型 PDF 的区别
- 如何使用Java 提取文本型 PDF 的内容
- 如何使用 Java 和 OCR 提取扫描型 PDF 中的文本
- PDF 文本提取常见问题及解决建议
- 总结
- 常见问答(FAQs)
为什么要使用 Java 提取 PDF 文本?
PDF 文件因其跨平台的排版一致性而被广泛用于文档存储和传输。然而,仅凭可视化展示还远远不够,提取其中的文本内容能够帮助开发者实现多种自动化和数据处理目标,包括:
- 支持全文搜索功能,提高信息检索效率
- 自动化处理发票、表单等结构化文档
- 将提取的文本用于训练或输入人工智能模型
- 对内容进行分析、生成数据报表
- 将 PDF 转换为 HTML、Markdown、CSV 等其他可编辑格式,便于再利用
通过 Java 语言结合合适的 PDF 处理库,开发者可以高效实现上述功能,提升文档处理的智能化水平。
文本型 PDF 与扫描型 PDF 的区别
在提取文本之前,首先需要明确 PDF 的类型,因为不同类型的 PDF 所采用的提取方法也不尽相同。
文本型 PDF
- 包含可选择、可复制的文本内容
- 可通过解析 PDF 的文本对象直接获取文字
- 通常由 Word 文档、报表或电子系统导出生成
扫描型 PDF
- 页面内容为图片格式,通常来源于扫描的纸质文档
- 不含嵌入文本,无法直接选择或复制文字
- 必须借助 OCR(光学字符识别)技术将图片转换为可识别的文本
判断 PDF 类型,有助于选择最合适的文本提取方法和工具,从而确保提取的准确性与效率。
如何使用Java 提取文本型 PDF 的内容
对于文本型 PDF,可以直接读取其中的文字内容。借助 Spire.PDF for Java库,开发者可以从整份文档、指定页面或页面中的某个区域提取文字,适用于内容索引、信息提取和数据处理等多种场景。
核心功能亮点
- 支持提取整份文档或指定页面的全部文本内容
- 可按需提取页面中指定的矩形区域
- 尽可能保留原始排版结构,包括换行和段落格式
- 支持多语言文本的识别与提取,适用于跨语言文档处理
Maven 配置
在项目的 pom.xml 文件中添加以下Maven仓库和依赖配置,以集成 Spire.PDF for Java:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>11.7.5</version>
</dependency>
</dependencies>
提取整个 PDF 的文本
如需将整个 PDF 转换为纯文本,可以遍历文档中的所有页面,并通过 PdfTextExtractor 类的 extract 方法提取每页的文本内容。该方法在提取过程中会尽量保留原有的段落结构和换行格式,确保文本的可读性与原始布局的一致性。
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.texts.PdfTextExtractOptions;
import com.spire.pdf.texts.PdfTextExtractor;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class ExtractAllTextFromPDF {
public static void main(String[] args){
// 创建 PdfDocument 实例并加载 PDF 文件
PdfDocument doc = new PdfDocument();
doc.loadFromFile("示例.pdf");
// 创建 StringBuilder 对象用于存储所有页面的提取文本
StringBuilder fullText = new StringBuilder();
// 遍历 PDF 的所有页面
for (int i = 0; i < doc.getPages().getCount(); i++) {
// 获取当前页面
PdfPageBase page = doc.getPages().get(i);
// 创建PdfTextExtractor实例
PdfTextExtractor extractor = new PdfTextExtractor(page);
// 使用默认提取选项提取文本
String text = extractor.extract(new PdfTextExtractOptions());
// 追加提取的文本到StringBuilder,并在页面之间添加空行
fullText.append(text).append("\n\n\n\n");
}
// 将提取的文本保存到 .txt 文件中
try (BufferedWriter writer = new BufferedWriter(new FileWriter("输出.txt"))) {
writer.write(fullText.toString());
} catch (IOException e) {
// 捕获并输出文件写入异常
e.printStackTrace();
}
// 关闭 PDF 文档,释放资源
doc.close();
}
}
提示: 请根据实际文件位置修改 sample.pdf 路径。
提取指定页面的文本
在处理多页 PDF 文件时,如果只需要提取特定页面(如摘要页、封面页或签名页)的内容,可通过页面索引定位目标页,并使用extract方法提取该页的文本信息。
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.texts.PdfTextExtractOptions;
import com.spire.pdf.texts.PdfTextExtractor;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class ExtractTextFromSelectedPage {
public static void main(String[] args){
// 创建 PdfDocument 实例并加载 PDF 文件
PdfDocument doc = new PdfDocument();
doc.loadFromFile("示例.pdf");
// 设置目标页面索引(例如:0 表示第一页)
int pageIndex = 0;
// 确保目标页面存在
if (pageIndex >= 0 && pageIndex < doc.getPages().getCount()) {
// 获取指定页面
PdfPageBase page = doc.getPages().get(pageIndex);
// 创建PdfTextExtractor实例
PdfTextExtractor extractor = new PdfTextExtractor(page);
// 提取该页的全部文本
String text = extractor.extract(new PdfTextExtractOptions());
// 将提取的文本写入 .txt 文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("输出.txt"))) {
writer.write(text);
} catch (IOException e) {
// 捕获并输出文件写入异常
e.printStackTrace();
}
} else {
System.out.println("页面索引无效。");
}
// 关闭 PDF 文档,释放资源
doc.close();
}
}
提示: 请根据需要修改 pageIndex,以提取目标页面的文本。
提取页面指定区域(矩形区域)内的文本
如需从页面的某个特定区域提取文本,可通过定义一个矩形区域(Rectangle2D),并结合 PdfTextExtractOptions.setExtractArea() 方法实现限定区域提取。该方式非常适用于提取表格数据、发票信息或页面中某个固定位置的文本内容。
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.texts.PdfTextExtractOptions;
import com.spire.pdf.texts.PdfTextExtractor;
import java.awt.geom.Rectangle2D;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class ExtractTextFromSelectedPageRegion {
public static void main(String[] args){
// 创建 PdfDocument 实例并加载 PDF 文件
PdfDocument doc = new PdfDocument();
doc.loadFromFile("示例.pdf");
// 设置目标页面索引(从 0 开始计数)
int pageIndex = 0;
// 确保页面存在
if (pageIndex >= 0 && pageIndex < doc.getPages().getCount()) {
// 获取指定页面
PdfPageBase page = doc.getPages().get(pageIndex);
// 定义矩形区域(x, y, 宽度, 高度)
Rectangle2D region = new Rectangle2D.Float(100, 150, 300, 100);
// 创建PdfTextExtractor实例
PdfTextExtractor extractor = new PdfTextExtractor(page);
// 创建提取选项并设置提取区域
PdfTextExtractOptions options = new PdfTextExtractOptions();
options.setExtractArea(region);
// 从指定区域提取文本
String text = extractor.extract(options);
// 将提取的文本写入 .txt 文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("输出.txt"))) {
writer.write(text);
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("页面索引无效。");
}
// 关闭 PDF 文档
doc.close();
}
}
注意: 在Spire.PDF中,坐标系以页面左上角为原点 (0,0),X 轴向右,Y 轴向下。了解更多关于 Spire.PDF 坐标系的信息,请参阅我们的开发者教程:通过 Java 生成 PDF 文件:从零创建、模板填充到 HTML 导出。
如何使用 Java 和 OCR 提取扫描型 PDF 中的文本
扫描型 PDF(即页面为图片形式的 PDF)不包含可直接提取的文本,因此无法通过常规方式解析。针对这类文件,需要先将每一页转换为图片,再借助 OCR(光学字符识别)技术识别图片中的文字。
实现步骤:
- 使用 Spire.PDF for Java 将PDF 的每一页转换为图片;
- 使用 Spire.OCR for Java 扫描图片并识别其中的文本内容。
Maven 配置
在项目的 pom.xml 文件中添加以下Maven仓库和依赖配置,以导入 Spire.PDF for Java和Spire.OCR for Java:
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>11.7.5</version>
</dependency>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.ocr</artifactId>
<version>1.9.22</version>
</dependency>
</dependencies>
下载 OCR 模型
Spire.OCR 依赖特定的语言模型,请根据操作系统选择合适版本(支持 Windows x64、Linux x64、macOS 10.15 及以上),下载并解压至项目可访问的路径。
Java 示例代码:使用 OCR 从扫描型 PDF 提取文本
下面的代码示例展示了如何从扫描型 PDF 中提取文本。首先,通过 saveAsImage() 方法将 PDF 的每一页转换为图片;随后,使用 OCR 引擎 OcrScanner 对每张图片进行文字识别;最后,将所有提取到的文本统一保存到一个 .txt 文件。
import com.spire.ocr.ConfigureOptions;
import com.spire.ocr.OCRImageFormat;
import com.spire.ocr.OcrException;
import com.spire.ocr.OcrScanner;
import com.spire.pdf.PdfDocument;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
public class ExtractTextFromScannedPDF {
public static void main(String[] args) throws IOException, OcrException {
// 加载扫描型 PDF 文件
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("示例.pdf");
// 创建StringBuilder对象,用于存储所有提取的文本
StringBuilder allText = new StringBuilder();
// 遍历 PDF 的每一页
for (int i = 0; i < pdf.getPages().getCount(); i++) {
// 将当前页转换为图片
BufferedImage image = pdf.saveAsImage(i);
// 将图片写入流
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", os);
InputStream imageStream = new ByteArrayInputStream(os.toByteArray());
// 创建 OcrScanner 实例
OcrScanner scanner = new OcrScanner();
ConfigureOptions options = new ConfigureOptions();
// 设置 OCR 语言(支持语言:English, Chinese, Chinesetraditional, French, German, Japanese, Korean)
options.setLanguage("Chinese");
// 设置 OCR 模型路径(需根据实际下载的语言模型路径配置)
options.setModelPath("E:\\win-x64");
// 配置 OCR 依赖
scanner.ConfigureDependencies(options);
// 执行 OCR 识别
scanner.Scan(imageStream, OCRImageFormat.Png);
String text = scanner.getText().toString();
// 添加结果文本到StringBuilder
allText.append(text).append(System.lineSeparator()).append(System.lineSeparator());
}
// 将识别结果保存为 .txt 文件
try (FileWriter writer = new FileWriter("输出.txt")) {
writer.write(allText.toString());
} catch (IOException e) {
System.out.println("保存文本失败!");
e.printStackTrace();
}
// 释放资源
pdf.close();
}
}
提示:setModelPath() 中的路径应指向包含 OCR 模型的文件夹,并确保该目录可被程序访问。
PDF 文本提取常见问题及解决建议
在提取 PDF 文本的过程中,开发者可能会遇到一些常见问题。下表列出了部分问题及相应的解决建议:
问题类型 | 描述 | 建议 |
---|---|---|
布局丢失 | 提取后文本可能失去原有格式 | 使用支持布局保留的库 |
OCR 准确度 | 扫描图片质量低会影响识别效果 | 使用高分辨率图片,搭配合适的OCR库 |
多语言支持 | 扫描文档中可能含多种语言文字 | 使用支持多种语言的 OCR 模型进行识别 |
总结
使用Java提取PDF文本,是实现文档自动化处理及数据分析的重要手段。Spire.PDF for Java 能快速提取文本型 PDF 的内容,而借助 Spire.OCR for Java,还可识别扫描型 PDF 中的文字。
结合使用这两个工具,开发者可以搭建一套功能完整、高效稳定的 PDF 文本提取系统,满足报告分析、发票识别、合同归档等多样化的业务需求。
常见问答(FAQs)
Q1:可以在 Java 中从扫描 PDF 中提取文本吗?
A1: 可以。需将 PDF 页面转换为图片,再使用 OCR 引擎识别图片中的文本内容。
Q2:如何判断 PDF 是扫描型还是文本型?
A2: 用鼠标在 PDF 中选中文字:若可选中即为文本型,否则是扫描图片。
Q3:Java 能提取受密码保护的 PDF 内容吗?
A3: 可以。已知密码情况下,可通过 Spire.PDF 解密后再提取内容。
Q4:可以在 Java 中从 PDF 提取表格或结构化数据吗?
A4: 可以。Spire.PDF 库支持识别并提取PDF表格内容。