如何借助Java批量操作Excel文件?
最新技术资源(建议收藏)
https://www.grapecity.com.cn/resources/
前言 | 问题背景
在操作Excel的场景中,通常会有一些针对Excel的批量操作,批量的意思一般有两种:
对批量的Excel文件进行操作。如导入多个Excel文件,并处理数据,或导出多个Excel文件。这类场景,往往操作很相似,但是要反复读写Excel文件。对单个或复数个进行批量操作。如对Excel文件,进行批量替换文本,批量添加公式或者批量增加样式。这类场景,一般需要操作的Excel文件不多,但是需要反复执行特定操作,这种时候需要有易用的API来帮忙。
现有的Excel组件中,POI是非常常用的组件,但是针对上述不同的场景,其分别会对组件提出两类要求。
第一类场景会反复读取或者写入文件,需要组件对于内存有足够好的优化,否则很容易出现内存溢出(out of memory)的问题。
第二类场景则需要组件提供易用的API,例如替换字符串,如果没有查找(find)或者替换(replace)的接口API。则需要自己遍历单元格(cell)来查找值。
虽然POI在上面两种要求上可能会有欠缺,但还有其他的组件可以选择,比如EasyExcel,GcExcel等。
下面是以GcExcel为例,对上述两类场景,分别列举的例子。
什么是GcExcel?

场景1 批量导入Excel文件,并读取特定区域的数据
例如有多个Excel文件,名字都是GUID。这些Excel文件来自于填报的数据,需要对其中的内容进行汇总。
如Excel的表单内容如下图:

需要对B3到C6的格子进行取值,可以用下面的代码提取数据。
@Testpublic void testImportFormFile() {String folderPath = "path/testFolder"; //使用你的路径File folder = new File(folderPath);File[] files = folder.listFiles();if (files != null) {for (File file: files){if(file.isFile() && file.getName().endsWith(".xlsx")){Workbook wb = new Workbook();wb.open(file.getAbsolutePath());Object[][] value = (Object[][]) wb.getActiveSheet().getRange("B3:C6").getValue();System.out.println(value[0][1]); //小葡萄System.out.println(value[1][1]); //20.0System.out.println(value[2][1]); //开发部System.out.println(value[3][1]); //610123456789012345//添加处理数据的逻辑}}}}
通过listFiles()方法,获取所有的Excel文件。循环读取每一个文件,通过GcExcel打开Excel文件。使用IRange上的getValue()方法可以把Excel中的格子以二维数组的方式读取出来。
之后就可以通过访问二维数组来处理业务逻辑。
场景2 批量导出Excel文件,导出前把数据写在特定位置
继续以第一个Excel文件为例子,当在数据库中已经存有一些数据,希望把数据写入并导出到复数个Excel文件里或者导出为PDF文件。
真实的场景有,如企业发放工资,每个月需要给每一位员工发放一份电子版的工资单,因为每个员工的工资单信息不相同,这个场景下,则需要把数据批量导出为复数个PDF。
@Testpublic void testExportFormFile() {String outPutPath = "E:/testFolder";//给valueList初始化数据,替换为从数据库,CSV或者JSON等中获取数据。ArrayList<Object[][]> valueList = new ArrayList<Object[][]>();for (Object[][] value : valueList) {Workbook wb = new Workbook();wb.getActiveSheet().getRange("B3:C6").setValue(value);wb.save(outPutPath + UUID.randomUUID().toString() + ".xlsx");}}
GcExcel可以直接把二维数组设置给一个range,从数据库中把数据加载出来以后,可以整理成二维数组。
之后通过GcExcel的SetValue()把二维数组直接设置到sheet上,最后通过工作簿(workbook)上的save方法保存导出。
场景3 打开Excel文件,批量替换关键字
在这个场景中,需要把Excel文件作为模板,把其中的一些自定义关键字,替换成数据。
比如在有一个制式的报表,需要把数据填写进去。例如表头,姓名,报表相关的条目,数据等信息。可能会把报表制作成一个模板,之后把表头,姓名等位置留空,或者用关键字作为占位符。例如“%Name%”可以作为名字的占位符,在填写数据的时候,可以对%Name%进行替换。
@Testpublic void testReplaceTemplateFile() {String templateFilePath = "test.xlsx";Workbook wb = new Workbook();wb.open(templateFilePath);IRange usedRange = wb.getActiveSheet().getUsedRange();//load dataArrayList<Object[]> valueList = new ArrayList<Object[]>();for (Object[] value : valueList) {usedRange.replace(value[0],value[1]);}wb.save("result.xlsx", SaveFileFormat.Xlsx);}
通过工作簿(workbook)打开模板(template)文件,准备好数据以后,直接通过IRange的replace方法替换自定义的关键字。
替换完之后,保存为新的Excel即可。
对于更高级复杂的数据填充,GcExcel也有模板功能,设置好模板后,可以直接绑定数据源,GcExcel会自动填充数据到模板里。
场景4 打开Excel模板文件,批量获取计算结果
例如有一个Excel文件,用于计算保险或者行业数据。需要在固定的位置填入值,使用Excel中的公式计算结果。
@Testpublic void testCalcFormulaByTemplateFile() {String templateFilePath = "E:/testFolder/testFormula.xlsx";Workbook wb = new Workbook();wb.open(templateFilePath);//``获取特定的值,比如以下ArrayList<Object[]> valueList = new ArrayList<Object[]>();for (Object[] value : valueList) {Object A1Value = value[0];Object A2Value = value[1];Object result = null;wb.getActiveSheet().getRange("A1").setValue(A1Value);wb.getActiveSheet().getRange("A2").setValue(A2Value);result = wb.getActiveSheet().getRange("A3").getValue();System.out.println(result);}}
GcExcel的公式计算是在取值的时候计算的,因此不需要显示调用calculate之类的方法,只需要把输入的参数准备好,放在Excel特定的cell中,就可以直接获取公式的计算结果了。
以上就是一些常见的批量处理Excel的方法,仅使用GcExcel Java的代码为例,同样的思路也可以使用其他的组件来实现。
扩展链接:
GrapeCity Documents for Excel(服务端Excel组件)V3.0 正式发布
用它来开发“在线Excel”系统,竟如此简单!
如何使用JavaScript实现前端导入和导出excel文件
相关文章:
如何借助Java批量操作Excel文件?
最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/ 前言 | 问题背景 在操作Excel的场景中,通常会有一些针对Excel的批量操作,批量的意思一般有两种: 对批量的Excel文件进行操作。如导入多个Excel文件…...
JUC并发编程_Lock锁
JUC并发编程_Lock锁 1、Lock锁介绍2、主要方法3、与 synchronized 的区别4、Condition 使用示例 1、Lock锁介绍 Java中的 Lock 锁是 java.util.concurrent.locks 包下的一个接口,它提供了比 synchronized 关键字更灵活的锁定机制。 2、主要方法 lock():…...
Unity中的功能解释(数学位置相关和事件)
向量计算 Vector3.Slerp(起点坐标,终点坐标,t),可是从起点坐标以一个圆形轨迹到终点坐标,有那么多条轨迹,那怎么办 Vector3.Slerp 进行的是沿球面插值,因此并不是沿着严格的“圆形…...
ElementPlus---Timeline 时间线组件使用示例
介绍 使用ElementPlus时间线组件在后台首页实现通知公告列表展示,使用Vue3开发。 实现代码 Vue3代码 <el-timeline><el-timeline-itemstyle"max-width: 600px"v-for"(activity, index) in activities":key"index":times…...
推荐4款2024年大家都在用的高质量翻译器。
翻译器在我们的生活中有着很重要的作用,不管是我们在学习还是工作,生活娱乐,出国旅游等场合都会派上用场,它是我们解决沟通的障碍,提高阅读效率的好帮手。我自己使用的翻译器有很多,可以给大家列举几款特别…...
Mybatis 返回 Map 对象
一、场景介绍 假设有如下一张学生表: CREATE TABLE student (id int NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(100) NOT NULL COMMENT 姓名,gender varchar(10) NOT NULL COMMENT 性别,grade int NOT NULL COMMENT 年级,PRIMARY KEY (id) ) ENGINEInnoD…...
Vue3(三)路由基本使用、工作模式(history,hash)、query传参和param传参、props配置、编程式路由导航
文章目录 一、路由的基本使用二、路由器的工作模式三、RouterLink中to的两种写法四、嵌套路由五、路由传参1. query传参2. params传参 六、路由的propos配置七、编程式路由导航 一、路由的基本使用 安装:npm i vue-router 在src/pages文件下,创建三个路…...
TypeScript概念讲解
简单来说,TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准; TypeScript 由微软开发的自由和开源的编程语言; TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 Jav…...
C++ | Leetcode C++题解之第437题路径总和III
题目: 题解: class Solution { public:unordered_map<long long, int> prefix;int dfs(TreeNode *root, long long curr, int targetSum) {if (!root) {return 0;}int ret 0;curr root->val;if (prefix.count(curr - targetSum)) {ret pref…...
回复《对话损友 2》
回复《对话损友 2》 承蒙贵人挂念,亦感激贵人给予这般交流的契机(对话损友 2 -- 回复-CSDN博客)。我自身也一直期望能留存些岁月的痕迹,然而却常困惑于不知哪些事物值得铭记,哪些又应被永远忘却。 随着时光流转&#x…...
MySQL - 运维篇
一、日志 1. 错误日志 2. 二进制日志 3. 查询日志 记录了所有的增删改查语句以及DDL语句 4. 慢查询日志 二、主从复制 1. 概述 2. 原理 3. 搭建 三、分库分表 1. 介绍 2. Mycat概述 3. Mycat入门 4. Mycat配置 5. Mycat分片 6. Mycat管理及监控 四、读写分离 1. 介绍 2. 一…...
WebGIS开发及市面上各种二三维GIS开发框架对比分析
GIS前端开发是现代WebGIS应用开发中非常重要的一环,通过前端开发框架,可以实现地图展示、交互、分析等功能。本文将介绍当前市面上常用的GIS前端开发框架,并进行对比分析。 Leaflet Leaflet是一款轻量级的开源地图库,它提供了丰…...
[论文精读]TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor
期刊名称:IEEE Transactions on Information Forensics and Security 发布链接:TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor | IEEE Journals & Magazine | IEEE Xplore 中文译名:TorWard:…...
pytest - 多线程提速
import timedef test1_test1():time.sleep(1)assert 1 1, "11"def test1_test2():time.sleep(1)assert 1 1, "11" 上面2个函数,执行情况: 正常执行时,花费 2.08s2个进程执行时,花费 1.18s2个线程执行时&a…...
python中logging的用法
logging.error 是 Python logging 模块中的一个方法,专门用于记录错误级别(ERROR)的日志信息。logging 模块是 Python 提供的标准日志工具,用于生成各种级别的日志消息,并支持日志的格式化和存储。 logging.error 的基…...
【YOLO目标检测车牌数据集】共10000张、已标注txt格式、有训练好的yolov5的模型
目录 说明图片示例 说明 数据集格式:YOLO格式 图片数量:10000(2000张绿牌、8000张蓝牌) 标注数量(txt文件个数):10000 标注类别数:1 标注类别名称:licence 数据集下载:车牌数据…...
gdb xterm 调试 openmpi 程序
1,编写编译一个openmpi程序 迭代计算 PI 的源程序: pi_reduce.c #include <stdio.h>#include <math.h> #include <mpi.h>double f(double); double f(double x) {return (4.0/(1.0x*x)); }int main(int argc, char* argv[]) {int d…...
【STM32】江科大STM32笔记汇总(已完结)
STM32江科大笔记汇总 STM32学习笔记课程简介(01)STM32简介(02)软件安装(03)新建工程(04)GPIO输出(05)LED闪烁& LED流水灯& 蜂鸣器(06)GPIO输入(07)按键控制LED 光敏传感器控制蜂鸣器(08)OLED调试工具(09)OLED显示屏(10)EXTI外部中断(11)对射式红外传感器计次 旋转编码器…...
Java基础扫盲(二)
想看Java基础扫盲(一)的可以观看我的上篇文章Java基础扫盲 目录 String为什么设计为不可变的 String有长度限制吗 为什么JDK9将String的char[]改为byte[] 泛型中K,T,V,E,Object,?等都代表什么含义 怎么修改一个类中使用了private修饰的String类型…...
兼容React的刮刮乐完整代码实现
需要兼容React的刮刮乐完整代码实现 在现代Web开发中,React作为一种流行的前端框架,为开发者提供了构建动态界面的强大工具。刮刮乐效果作为一种趣味性的用户交互,能够显著提升用户体验和参与度。本文将详细介绍如何在React项目中实现一个兼…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
