当前位置: 首页 > news >正文

用Java提取PDF表格到文本、CSV、Excel工作表

如何精准地提取PDF格式中嵌入的表格数据,并将其无缝转换为更加易于分析和操作的形式,如纯文本、CSV文件或Excel工作表,是一项重要的文档处理技巧。使用Java,我们可以简单地实现这一过程。本文将介绍如何利用Java从PDF文档提取表格数据,并写入文本文件、CSV文件以及Excel工作表

文章目录

    • 提取PDF表格数据写入文本文件
    • 提取PDF表格数据写入CSV文件
    • 提取PDF表格数据写入Excel文件

本文所使用的方法提取PDF表格主要需要免费的Free Spire.PDF for Java库,可下载导入或通过Maven导入:

<dependency><groupId>e-iceblue</groupId><artifactId>spire.pdf.free</artifactId><version>9.13.0</version>
</dependency>

提取PDF表格需要用到库中的PdfTableExtractor类。我们可以为载入的PDF文件创建PdfTableExtractor对象,然后使用PdfTableExtractor.extractTable()方法根据页面在文档中的参数提取指定PDF页面上所有表格,最后再使用PdfTable.getText()方法即可获取表格中的数据。以下是一般操作步骤示例:

  • 创建PdfDocument对象并使用PdfDocument.loadFromFile()方法载入PDF文档。
  • 使用载入的PDF文档创建PdfTableExtractor对象。
  • 使用PdfTableExtractor.extractTable()方法提取每个页面上的表格。
  • 使用PdfTable.getText()方法获取PDF表格的单元格数据。

使用上述方法获取表格数据后,我们就可以将其写入文本文件,或搭配其他工具制作CSV或Excel文件了。

提取PDF表格数据写入文本文件

使用PdfTableExtractor.extractTable()方法提取表格并使用PdfTable.getText()方法获取单元格数据后,我们可以通过构建字符串并写入文本文件来实现提取表格并保存为文本文件的目的。以下是详细操作步骤:

  1. 导入所需模块。
  2. 创建PdfDocument对象并使用PdfDocument.loadFromFile()方法载入PDF文档。
  3. 使用载入的PDF文档创建PdfTableExtractor对象。
  4. 遍历页面,使用PdfTableExtractor.extractTable()方法提取每个页面上的所有表格。
  5. 遍历提取到的表格,为每个表格创建一个StringBuilder对象。
  6. 遍历表格中的行和列,使用PdfTable.getText()方法获取每个单元格的数据并去除换行符。然后将单元格数据添加到StringBuilder对象。
  7. StringBuilder对象写入文本文件。
  8. 释放资源。

代码示例

import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;import java.io.FileWriter;
import java.io.IOException;public classPDF中提取文本 {public static void main(String[] args) throws IOException {// 创建一个PdfDocument对象PdfDocument pdf = new PdfDocument();// 加载一个PDF文档pdf.loadFromFile("Sample.pdf");// 创建一个PdfTableExtractor对象PdfTableExtractor extractor = new PdfTableExtractor(pdf);// 从每一页中提取表格for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {PdfTable[] tables = extractor.extractTable(pageIndex);// 如果表格不为空,则遍历表格if (tables != null) {for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {PdfTable table = tables[tableIndex];// 创建一个StringBuilder对象StringBuilder tableText = new StringBuilder();// 遍历行和列for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {for (int colIndex = 0; colIndex < table.getColumnCount(); colIndex++) {// 获取单元格文本并移除换行符String cellText = table.getText(rowIndex, colIndex);cellText = cellText.replaceAll("\\r|\\n", "");if (colIndex < table.getColumnCount() - 1) {tableText.append(cellText).append("\t");} else {tableText.append(cellText).append("\n");}}}// 将表格写入文本文件try (FileWriter writer = new FileWriter("output/Tables/Page" + (pageIndex+1) + "-Table" + (tableIndex+1) + ".txt")) {writer.write(tableText.toString());}}}}}
}

提取结果
Python提取PDF表格到文本

提取PDF表格数据写入CSV文件

我们也可以用同样的方法提取表格数据,然后搭配其他模块,如opencsv,将提取到的数据写入CSV文件。也可以使用下面的提取PDF表格写入Excel文件,最后保存时保存为CSV文件。
opencsv:

<dependency><groupId>com.opencsv</groupId><artifactId>opencsv</artifactId><version>5.9</version>
</dependency>

以下是搭配opencsv提取PDF表格数据并写入CSV文件的操作步骤:

  1. 导入所需模块。
  2. 创建PdfDocument对象并使用PdfDocument.loadFromFile()方法载入PDF文档。
  3. 使用载入的PDF文档创建PdfTableExtractor对象。
  4. 历页面面,使用PdfTableExtractor.extractTable()方法提取每个页面上的所有表格。
  5. 遍历提取的表格,并构建CSV文件名。
  6. 创建CSVWriter对象,遍历表格行以及行中的列,使用PdfTable.getText()方法获取每个单元格的数据并去除换行符,将提取的每行表格数据构建为字符串列表。最后将字符串列表写入为CSV数据行。
  7. 释放资源。

代码示例

import com.opencsv.CSVWriter;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;import java.io.FileWriter;
import java.io.IOException;public classPDF表格提取到CSV {public static void main(String[] args) throws IOException {// 创建一个PdfDocument对象PdfDocument pdf = new PdfDocument();// 加载一个PDF文档pdf.loadFromFile("Sample.pdf");// 创建一个PdfTableExtractor对象PdfTableExtractor extractor = new PdfTableExtractor(pdf);// 从每一页中提取表格for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {PdfTable[] tables = extractor.extractTable(pageIndex);// 如果表格不为空,则遍历表格if (tables != null) {for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {PdfTable table = tables[tableIndex];// 创建CSV文件名String csvFileName = "output/Tables/Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1) + ".csv";// 创建一个CSVWriter对象try (CSVWriter writer = new CSVWriter(new FileWriter(csvFileName))) {// 遍历行和列for (int rowIndex = 0; rowIndex < table.getRowCount(); rowIndex++) {String[] row = new String[table.getColumnCount()];for (int colIndex = 0; colIndex < table.getColumnCount(); colIndex++) {// 获取单元格文本并移除换行符String cellText = table.getText(rowIndex, colIndex).replaceAll("\\r?\\n", "");row[colIndex] = cellText;}// 将行写入CSV文件writer.writeNext(row);}}}}}// 关闭PDF文档pdf.close();}
}

提取结果
Python提取PDF表格到CSV

提取PDF表格数据写入Excel文件

保存PDF表格到表格需要用到Free Spire.XLS for Java。我们可以提取到PDF文档表格单元格数据后,使用Worksheet.getRange().setText()方法将数据写入到创建的Excel工作表的相应单元格并保存,从而实现PDF表格数据到Excel文件的提取。同时,我们还可以在保存文件时将格式参数设置为CSV,实现PDF表格数据到CSV文件的提取。
Free Spire.XLS for Java:

<dependency><groupId>e-iceblue</groupId><artifactId>spire.xls.free</artifactId><version>5.3.0</version>
</dependency>

以下是详细操作步骤:

  1. 导入所需模块。
  2. 创建PdfDocument对象并使用PdfDocument.loadFromFile()方法载入PDF文档。
  3. 创建Workbook对象,并使用Workbook.getWorksheets().clear()方法清除默认工作表。
  4. 使用载入的PDF文档创建PdfTableExtractor对象。
  5. 历页面面,使用PdfTableExtractor.extractTable()方法提取每个页面上的所有表格。
  6. 遍历提取的表格,使用Workbook.getWorksheets().add()方法为每个表格创建一个指定名称的工作表。
  7. 遍历表格行和列,使用PdfTable.getText()方法获取每个单元格的数据并去除换行符,然后使用Worksheet.getRange().setText()方法将单元格数据写入到工作表的相应单元格。
  8. 设置工作表单元格的格式。
  9. 使用Worksheet.autoFitRow()Worksheet.autoFitColumn()方法自动调整行高和列宽。
  10. 可以使用Worksheet.saveToFile()方法将工作表保存为CSV文件。
  11. 使用Workbook.saveToFile()方法保存工作簿为Excel文件。
  12. 释放资源。

代码示例

import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import com.spire.xls.*;public classPDF表格提取到Excel {public static void main(String[] args) {// 创建一个PdfDocument对象PdfDocument pdf = new PdfDocument();// 加载一个PDF文档pdf.loadFromFile("G:/Documents/Sample73.pdf");// 创建一个Workbook对象Workbook workbook = new Workbook();workbook.getWorksheets().clear();// 创建一个PdfTableExtractor对象PdfTableExtractor extractor = new PdfTableExtractor(pdf);// 从每一页中提取表格for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {PdfTable[] tables = extractor.extractTable(pageIndex);// 如果表格不为空,则遍历表格if (tables != null) {for (int tableIndex = 0; tableIndex < tables.length; tableIndex++) {// 向工作簿中添加一个工作表Worksheet sheet = workbook.getWorksheets().add("Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1));// 遍历表格中的行和列for (int rowIndex = 0; rowIndex < tables[tableIndex].getRowCount(); rowIndex++) {for (int colIndex = 0; colIndex < tables[tableIndex].getColumnCount(); colIndex++) {// 获取单元格文本并移除换行符String cellText = tables[tableIndex].getText(rowIndex, colIndex).replaceAll("\\r|\\n", "");// 将单元格文本写入工作表sheet.getCellRange(rowIndex+1, colIndex+1).setText(cellText);}}// 设置单元格样式CellRange[] rows = sheet.getRows();rows[0].getStyle().getFont().setFontName("HarmonyOS Sans SC");rows[0].getStyle().getFont().setSize(12);rows[0].getStyle().getFont().isBold(true);rows[0].getStyle().setHorizontalAlignment(HorizontalAlignType.Center);for (int i = 1; i < rows.length; i++) {rows[i].getStyle().getFont().setFontName("HarmonyOS Sans SC");rows[i].getStyle().getFont().setSize(12);rows[i].getStyle().setHorizontalAlignment(HorizontalAlignType.Left);}// 自动调整行和列for (int i = 0; i < rows.length; i++) {sheet.autoFitRow(i+1);}for (int i = 0; i < sheet.getColumns().length; i++) {sheet.autoFitColumn(i+1);}// 保存工作表为CSV文件// sheet.saveToFile("output/Tables/PDFTableToCSV-Page" + (pageIndex + 1) + "-Table" + (tableIndex + 1) + ".csv", ",");}}}// 保存工作簿workbook.saveToFile("output/PDFTableToExcel.xlsx");// 关闭PDF文档pdf.close();// 释放工作簿资源workbook.dispose();}
}

提取结果
Python提取PDF表格到Excel

本文演示了如何使用Java提取PDF表格数据写入文本、CSV以及Excel文件。

更多PDF文档操作技巧请前往Spire.PDF for Java教程查看。

相关文章:

用Java提取PDF表格到文本、CSV、Excel工作表

如何精准地提取PDF格式中嵌入的表格数据&#xff0c;并将其无缝转换为更加易于分析和操作的形式&#xff0c;如纯文本、CSV文件或Excel工作表&#xff0c;是一项重要的文档处理技巧。使用Java&#xff0c;我们可以简单地实现这一过程。本文将介绍如何利用Java从PDF文档提取表格…...

OpenCV视频I/O(10)视频采集类VideoCapture之从视频流中检索一帧图像函数 retrieve()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 解码并返回已抓取的视频帧。 cv::VideoCapture::retrieve() 是 VideoCapture 类的一个成员函数&#xff0c;用于从视频流中检索一帧图像。 retr…...

【RocketMQ】SpringBoot整合RocketMQ

&#x1f3af; 导读&#xff1a;本文档详细介绍了如何在Spring Boot应用中集成Apache RocketMQ&#xff0c;并实现消息生产和消费功能。首先通过创建消息生产者项目&#xff0c;配置POM文件引入RocketMQ依赖&#xff0c;实现同步消息发送&#xff0c;并展示了如何发送普通字符串…...

mysql replace无法替换空格?如何解决

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云/阿里云/华为云/51CTO&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互…...

Redis篇(环境搭建)

目录 一、安装包 1. Windows版下载地址 2. Linux版下载地址 二、安装Redis 1. 在Linux中安装Redis 2. 在Windows中安装Redis 3. 细节问题 三、Redis服务启动 1. 默认启动 2. 指定配置启动 3. 开机自启 四、Redis服务停止 1. Linux系统中启动和停止Redis 2. Window…...

【C++题目】7.双指针_和为 s 的两个数字

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; LCR 179.查找总价格为目标值的两个商品 题目描述&#xff1a; 解法 解法一&#xff08;暴力解法&#xff0c;会超时&#xff09; 两层 for 循环列出所有两个数字的组合…...

网络通信1-传输层

tcp的三次握手&#xff1a; TCP&#xff08;传输控制协议&#xff09;的三次握手是建立一个可靠的连接的过程。这个过程中涉及到的主要参数包括&#xff1a; 序列号&#xff08;Sequence Number, SEQ&#xff09;: 在第一次握手中&#xff0c;发起方&#xff08;客户端&#xf…...

【JAVA源码授权】

悯农二首 代码混淆加密 Class 文件许可证管理数字签名API 调用限制防止反编译使用私有库法律保护动态授权 其一 春种一粒粟&#xff0c;秋收万颗子。 四海无闲田&#xff0c;农夫犹饿死。 其二 锄禾日当午&#xff0c;汗滴禾下土。 谁知盘中餐&#xff0c;粒粒皆辛苦 代码混淆 …...

tauri开发软件中,使用tauri自带的api用浏览器打开指定的url链接

有能力的可以看官方文档&#xff1a;shell | Tauri Apps 就是使用这个api来打开指定的url链接&#xff0c;要在tauri.config.json中配置打开这个api&#xff1a; 然后在前端页面中导入使用&#xff1a; import { open } from tauri-apps/api/shell; // opens the given URL o…...

OpenCV-图像拼接

文章目录 一、基本原理二、步骤三、代码实现1.定义函数2.读取图像3.图像配准&#xff08;1&#xff09;.特征点检测&#xff08;2&#xff09;.特征匹配 4.透视变换5.图像拼接 四、图像拼接的注意事项 图像拼接是一种将多张有重叠部分的图像合并成一张无缝的全景图或高分辨率图…...

C++【类和对象】(取地址运算符重载与实现Date类)

文章目录 取地址运算符重载const成员函数取地址运算符重载 Date类的实现Date.hDate.cpp1.检查日期合法性2. 构造函数/赋值运算符重载3.得到某月的天数4. Date类 - 天数的操作4.1 日期 天数4.2 日期 天数4.3 日期 - 天数4.4 日期 - 天数 5. Date的前后置/--5.1 前置5.2 后置5.…...

oracle 数据库中的异常和游标管理

异常和游标管理 游标&#xff1a; 用来查询数据库&#xff0c;获取记录集合&#xff08;结果集&#xff09;的指针&#xff0c;可以让开发者一次访问一行结果集&#xff0c;在每条结果集上作操作。 分类&#xff1a; 静态游标&#xff1a; 分为显式游标和隐式游标。 REF游标&…...

关于python 日志设定为INFO 但是DEBUG仍旧写入的问题

问题&#xff1a;将logging设定为了INFO级别&#xff0c;但是在打印的时候发现jieba包中的DEBUG级别的信息还是出现了。 原因&#xff1a;在我引用的包中&#xff0c;一些python文件也使用了logging&#xff0c;我设定的INFO级别只能设定我当前使用的文件&#xff0c;而调用的包…...

TypeScript 语法基础 第一部分 类型

【视频链接】尚硅谷TypeScript教程&#xff08;李立超老师TS新课&#xff09; TypeScript TypeScript 语法基础 第二部分 类、接口、泛型1. 类型1.1 | 联合类型1.2 字面量类型1.3 any 任意类型1.4 unkown 类型1.5 as 类型断言1.6 object 对象类型1.7 { } 对象类型1.8 &#xff…...

GO Serial 学习与使用

文章目录 主要特性安装基本用法配置选项错误处理其他功能 github.com/goburrow/serial 是一个 Go 包&#xff0c;提供了一种简单的方式来与串口进行交互。以下是该包的主要特性和用法的简要概述&#xff1a; 主要特性 跨平台支持&#xff1a;支持 Windows、macOS 和 Linux。简…...

安卓app开发系列之-常用工具与库

✨ 关于我 ✨ &#x1f468;‍&#x1f4bb; Hi there! 我是 [Jamson]&#xff0c;一名热爱编程与技术的狂热者&#xff0c;致力于前后端的全栈独立软件系统开发。通过不断学习和实践&#xff0c;我希望将知识分享给更多的朋友们&#xff0c;和大家一起成长。 &#x1f4a1; &…...

视频汇聚EasyCVR视频监控平台调取接口提示“认证过期”是什么原因?

视频汇聚EasyCVR视频监控平台&#xff0c;作为一款智能视频监控综合管理平台&#xff0c;凭借其强大的视频融合汇聚能力和灵活的视频能力&#xff0c;在各行各业的应用中发挥着越来越重要的作用。EasyCVR平台具备强大的拓展性和灵活性&#xff0c;支持多种视频流的外部分发&…...

uniapp视频禁止用户推拽进度条并保留进度条显示的解决方法——方案二

在uniapp项目中&#xff0c;使用<video>组件播放视频非常方便。默认情况下&#xff0c;视频组件会显示进度条&#xff0c;用户可以随意拖动进度条来控制视频播放进度。然而&#xff0c;在某些特定场景&#xff0c;如在线教育、广告宣传等&#xff0c;我们希望禁止用户拖动…...

mysql复合查询 -- 多表查询(介绍,笛卡尔积,使用),自连接(介绍,使用)

目录 多表查询 介绍 使用 表数据 显示雇员名,雇员工资,以及所在部门名 显示部门号为10的部门名,员工名,工资 自连接 介绍 场景 表数据 题目 子查询 自连接 多表查询 介绍 实际开发中往往数据来自不同的表&#xff0c;所以需要多表查询 语法: from 表1,表2 (笛卡…...

【个人笔记】数据一致性的解决方案

保证数据一致性&#xff1a;指保证redis里的数据和mysql的数据是一致的&#xff0c;不能说mysql更新了&#xff0c;但redis里面的还是旧的数据&#xff0c;反之亦然 先说结论&#xff1a;增删改的时候&#xff0c;把Redis中的缓存删了 为什么不先更新数据库&#xff0c;再更新…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...