EasyExcel 快速入门
目录
一、 EasyExcel简介
官网链接:
代码链接:
二、 EasyExcel快速上手
引入依赖:
设置Excel相关注解
编写对应的监听类:
简单写入数据:
简单读取数据:
不需要使用监听器:
需要使用监听器:
三、EasyExcel进阶操作
批量写入数据:
批量写入不同的sheet的不同对象:
填充数据:
四、实战EasyExcel(Excel表格的导入和导出)
一、 EasyExcel简介
EasyExcel 是一个基于 Java 的简单、高效的 Excel 处理工具。它由阿里巴巴开源,主要解决了在 Java 应用中处理 Excel 文件时内存溢出的问题。
EasyExcel 和 Apache POI 都是 Java 生态中处理 Excel 文件的库,但它们在设计理念、性能、使用复杂度等方面有所不同。以下是 EasyExcel 相比于 Apache POI 的主要优势和一些差异:
性能:
-
内存占用:EasyExcel 是为低内存占用而设计的。在处理大型 Excel 文件时,EasyExcel 可以实现按行读取和写入,而不需要将整个文件加载到内存中,从而显著降低内存使用。而 Apache POI 在处理大型文件时,可能会因为将整个文件加载到内存而导致内存溢出。
-
处理速度:EasyExcel 对读取和写入操作进行了优化,通常在处理速度上比 Apache POI 更快。
使用复杂度:
-
API 设计:EasyExcel 提供了更为简洁的 API,使得读取和写入操作更加直观和方便。而 Apache POI 提供了丰富的 API,但这也使得它的使用相对复杂。
-
模型映射:EasyExcel 支持使用注解直接将 Excel 的列映射到 Java 实体的字段上,简化了数据转换的过程。Apache POI 需要手动处理每一行和每一列的数据。
官网链接:
EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 (alibaba.com)
代码链接:
https://gitee.com/seniorGitee/easy-excel
二、 EasyExcel快速上手
引入依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.2</version>
</dependency>
设置Excel相关注解
以员工实体类为例:
@ExcelIgnore设置忽略导出的字段信息
@ExcelProperty设置导出的字段名,导出的字段默认按照顺序从0开始排序,如果想指定导出字段的在第几列的话,可以设置对应的index,index的值:字段所在列数-1,类似数组下标索引
@DateTimeFormat定义日期格式
@ColumnWidth设置字段宽度
其实@ExcelProperty还有很多复杂的操作,具体请查看官网文档,这里只教会大家快速入门使用
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee implements Serializable {/*** 忽略这个字段*/@ExcelIgnoreprivate Long id;@ExcelProperty("员工名")private String name;@ExcelProperty("员工年龄")private Integer age;@ExcelProperty(value = "员工工资",index = 3)private BigDecimal salary;@ColumnWidth(15)@DateTimeFormat("yyyy年MM月dd日")@ExcelProperty(value = "入职时间",index = 2)private Date entryTime;}
编写对应的监听类:
编写Employee对应的监听类EmployeeListener
注意:有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class EmployeeListener implements ReadListener<Employee> {/*** 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;/*** 缓存的数据*/private List<Employee> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);private IEmployeeService employeeService;public EmployeeListener(IEmployeeService employeeService){this.employeeService = employeeService;}//每一条数据解析都会进行调用@Overridepublic void invoke(Employee employee, AnalysisContext analysisContext) {log.info("解析到一条数据:{}", JSON.toJSONString(employee));cachedDataList.add(employee);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}//所有的数据解析完后进行调用@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();log.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {log.info("{}条数据,开始存储数据库!", cachedDataList.size());employeeService.save(cachedDataList);log.info("存储数据库成功!");}
}
简单写入数据:
注意:simpleWrite在数据量不大的情况下可以使用(5000以内,具体也要看实际情况),数据量大参照 重复多次写入(可以查看EasyExcel进阶操作:批量写入数据)
@SpringBootTest
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid simpleWrite() {String fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite" + System.currentTimeMillis() + ".xlsx";EasyExcel.write(fileName, Employee.class).sheet("模板").doWrite(employeeService.getData());}}
在resources/static中可以看到导出数据的Excel表格
简单读取数据:
读取数据有两种方式,分别是使用监听器和不使用监听器的方式进行读取数据
不需要使用监听器:
这里的fileName需要修改成读取Excel文件对应的路径
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid simpleRead(){String fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite1726145097517.xlsx";// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行// 具体需要返回多少行可以在`PageReadListener`的构造函数设置EasyExcel.read(fileName, Employee.class, new PageReadListener<Employee>(employeeList -> {for (Employee employee : employeeList) {log.info("读取到一条数据{}", JSON.toJSONString(employee));}})).sheet().doRead();}}
控制台输出的结果:
需要使用监听器:
这里的EmployListener对一个之前写的监听类,读取Excel文件的数据并将数据存储到数据库中
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid simpleReadByListener(){String fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite1726145097517.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, Employee.class, new EmployeeListener(employeeService)).sheet().doRead();}}
控制台输出的结果:
三、EasyExcel进阶操作
批量写入数据:
批量写入通一个sheet同一对象:
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid batchWriteOneSheep(){// 方法1: 如果写到同一个sheetString fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写try (ExcelWriter excelWriter = EasyExcel.write(fileName, Employee.class).build()) {// 这里注意 如果同一个sheet只要创建一次WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();Long total = employeeService.total();Integer pageSize = 10;// 实际使用时根据数据库分页的总的页数来,这里批量插入,每次插入10条数据for (int i = 1; i <= Math.ceil((double) total /pageSize); i++) {// 分页去数据库查询数据 这里可以去数据库查询每一页的数据PageBean pageBean = employeeService.pageEmployee(i,pageSize);excelWriter.write(pageBean.getRows(), writeSheet);}}}}
批量写入不同的sheet同一对象:
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid batchWriteDifferentSheep(){// 方法2: 如果写到不同的sheet 同一个对象String fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 指定文件try (ExcelWriter excelWriter = EasyExcel.write(fileName, Employee.class).build()) {Long total = employeeService.total();Integer pageSize = 10;// 实际使用时根据数据库分页的总的页数来。这里最终会将数据写到多个sheet里面for (int i = 1; i <= Math.ceil((double) total /pageSize); i++) {// 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样WriteSheet writeSheet = EasyExcel.writerSheet(i, "员工表" + i).build();// 分页去数据库查询数据 这里可以去数据库查询每一页的数据PageBean pageBean = employeeService.pageEmployee(i,pageSize);excelWriter.write(pageBean.getRows(), writeSheet);}}}}
批量写入不同的sheet的不同对象:
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid batchWriteDifferentSheepAndObject(){// 方法3 如果写到不同的sheet 不同的对象String fileName = ".\\src\\main\\resources\\static\\"+"simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 指定文件try (ExcelWriter excelWriter = EasyExcel.write(fileName).build()) {Long total = employeeService.total();Integer pageSize = 10;// 实际使用时根据数据库分页的总的页数来。这里最终会将数据写到多个sheet里面for (int i = 1; i <= Math.ceil((double) total /pageSize); i++) {// 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意Employee.class 可以每次都变,我这里为了方便 所以用的同一个class// 实际上可以一直变WriteSheet writeSheet = EasyExcel.writerSheet(i, "模版表" + i).head(Employee.class).build();// 分页去数据库查询数据 这里可以去数据库查询每一页的数据PageBean pageBean = employeeService.pageEmployee(i,pageSize);excelWriter.write(pageBean.getRows(), writeSheet);}}}}
填充数据:
例如我们想将员工表填充到如下的Excel表格中
先对Excel表格模版填写占位符
执行填充Excel表格的代码
@SpringBootTest
@Slf4j
class EasyExcelApplicationTests {@Autowiredprivate IEmployeeService employeeService;@Testvoid fillTemplateData(){//需要填充模版String templateFileName = ".\\src\\main\\resources\\static\\"+"fillTemplate.xlsx";//模版填充后的文件String fileName = ".\\src\\main\\resources\\static\\"+"fillTemplateComplete.xlsx";// 这里 会填充到第一个sheet, 然后文件流会自动关闭EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(employeeService.getData());}}
四、实战EasyExcel(Excel表格的导入和导出)
web中进行Excel表格数据的导入和导出,以员工表为例:
@RestController
@RequestMapping("/employee")
public class EmployeeController {@Autowiredprivate IEmployeeService employeeService;@PostMapping("/upload")public void upload(MultipartFile file,HttpServletResponse response) throws IOException{long begin = System.currentTimeMillis();EasyExcel.read(file.getInputStream(), Employee.class, new EmployeeListener(employeeService)).sheet().doRead();long end = System.currentTimeMillis();response.setContentType("text/html;charset=utf-8");response.getWriter().println("导出数据成功,耗时:"+(end-begin));}@GetMapping("download")public void download(HttpServletResponse response) throws IOException {// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postmanresponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("导出的Excel数据", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), Employee.class).sheet("员工表").doWrite(employeeService.getData());}}
相关文章:

EasyExcel 快速入门
目录 一、 EasyExcel简介 官网链接: 代码链接: 二、 EasyExcel快速上手 引入依赖: 设置Excel相关注解 编写对应的监听类: 简单写入数据: 简单读取数据: 不需要使用监听器: 需要使…...

Sparse4D v1
Sparse4D: Multi-view 3D Object Detection with Sparse Spatial-Temporal Fusion Abstract 基于鸟瞰图 (BEV) 的方法最近在多视图 3D 检测任务方面取得了重大进展。与基于 BEV 的方法相比,基于稀疏的方法在性能上落后,但仍然有很多不可忽略的优点。为了…...
速盾:你知道高防 IP 和高防 CDN 的区别吗?
在当今网络安全形势日益严峻的情况下,网站的安全防护成为了企业和个人关注的焦点。高防 IP 和高防 CDN 作为两种常见的网络安全防护手段,被广泛应用于网站的安全防护中。那么,高防 IP 和高防 CDN 有什么区别呢?防护网站哪个更好呢…...
HTML和CSS网页制作成品
HTML和CSS网页制作成品 一、引言 1. 背景介绍 在当今数字化时代,网页已成为信息传递和交流的重要媒介。HTML和CSS作为网页制作的基石,对于构建美观、功能丰富的网站至关重要。本文将详细介绍如何使用HTML和CSS来制作一个网页成品。 2. 目的和重要性 …...

Ai+若依(集成easyexcel实现excel表格增强)
EasyExcel 介绍 官方地址:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一…...

钻机、塔吊等大型工程设备,如何远程维护、实时采集运行数据?
在建筑和工程领域,重型设备的应用不可或缺,无论是在道路与桥梁建设、高层建筑施工,还是在风电、石油等能源项目的开发中,都会用到塔吊、钻机等大型机械工程设备。 随着数字化升级、工业4.0成为行业发展趋势,为了进一步…...

【AutoX.js】选择器 UiSelector - 查找包名
文章目录 原文:https://blog.c12th.cn/archives/38.html选择器 UiSelector - 查找包名笔记直接查找包名双层判断(推荐)查找最外层控件的子控件 最后 原文:https://blog.c12th.cn/archives/38.html 选择器 UiSelector - 查找包名 笔记 AutoX.js UiSelec…...

ERP进销存多仓库管理系统源码 带完整的安装代码包以及搭建部署教程
系统概述 ERP进销存多仓库管理系统是一款专为中小企业量身定制的集成化管理软件,它集成了采购管理、销售管理、库存管理、财务管理以及多仓库协同作业等核心模块。通过统一的平台,企业可以实时掌握商品从入库到出库的全过程,实现库存的自动化…...
数据清洗-缺失值填充-对XGBoost参数优化填充
目录 一、安装所需的python包二、采用XGboost算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战2.2.1 代码运行过程截屏:2.2.2 填充后的数据截屏:三、网格搜索(Grid Search)对 XGBoost 模型的超参数进行优化原理介绍3.1 说明3.2 参数优化的原理1. 网格搜索(…...

Qt_按钮类控件
目录 1、QAbstractButton 2、设置带图标的按钮 3、设置带有快捷键的按钮 4、QRadioButtion(单选按钮) 4.1 QButtonGroup 5、QCheckBox 结语 前言: 按钮类控件是Qt中最重要的控件类型之一,该类型的控件可以通过鼠标的点击…...
union 的定义和基本结构以及用途
在 C 语言中,union(联合体) 是一种数据结构,它允许多个成员共享相同的内存空间。换句话说,联合体中的所有成员都存储在同一块内存区域,不同的成员会占用相同的内存地址,但在同一时刻只能保存一个…...

混合整数规划及其MATLAB实现
目录 引言 混合整数规划的基本模型 混合整数规划的求解方法 MATLAB中的混合整数规划实现 示例:多变量系统的混合整数规划 表格总结:混合整数规划的求解方法与适用场景 结论 引言 混合整数规划(Mixed Integer Programming, MIP…...
【数据结构】6——图1,概念
数据结构6——图1,概念 文章目录 数据结构6——图1,概念基本概念图的分类图的表示方法 基本概念 由 顶点(Vertex) 和 边(Edge) 组成的集合。顶点表示图中的点,而边表示顶点之间的连接。记为 G …...
技术周总结 09.09~09.15周日(C# WinForm WPF)
文章目录 一、09.09 周一1.1) 问题01: Windows桌面开发中,WPF和WinForm的区别和联系?联系:区别: 二、09.12 周四2.1)问题01:visual studio的相关快捷键有哪些?通用快捷键编辑导航调试窗口管理 2…...

4K投影仪选购全攻略:全玻璃镜头的当贝F6,画面细节纤毫毕现
在当今的投影市场上,4K投影仪已经成了主流产品,越来越多家庭开始关注如何选择一款性价比高、口碑好的4K投影仪。4K投影仪其实指的是具备3840*2160像素分辨率投影仪,它能够提供更清晰、更细腻、更真实的画面效果。 那么4K投影仪该怎么选&…...

除了字符串前导的*号之外,将串中其它*号全部删除
要求 假定输入的字符串中只包含字母和*号。请编写函数fun,它的功能是:除了字符串前导的*号之外,将串中其它*号全部删除。在编写函数时,不得使用C语言提供的字符串函数。函数fun中给出的语句仅供参考。 例如,字符串中的内容为:-**…...

SpringBoot开发——使用@Slf4j注解实现日志输出
文章目录 1、Lombok简介2、SLF4J简介3、实现步骤3.1 创建SpringBoot项目3.2 添加依赖3.3 使用 Slf4j 注解3.4 输出日志信息 4、结论 在现代Java开发中,日志记录是至关重要的。它不仅帮助开发者调试代码,还便于监控系统运行状态和性能。 Lombok 和 SLF4J …...

VSCode拉取远程项目
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

【已解决】SpringBoot3项目整合Druid依赖:Druid监控页面404报错
文章标题 问题描述原因分析解决方案参考资料 问题描述 最近,笔者在SpringBoot3项目中整合Druid连接池时,偶然翻到一条介绍Druid监控的短视频,兴致盎然之下尝试设置了一下Druid监控。 But,按照视频中提供的yml参数对照设置&#x…...
【算法】滑动窗口—找所有字母异位词
“找到字符串中所有字母异位词”的难度为Medium,看一下题目: 给定一个字符串 S 和一个非空字符串 T,找到 S 中所有是 T 的字母异位词的子串,返回这些子串的起始索引。 所谓的字母异位词,其实就是全排列,原题…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...