Spring Boot + EasyExcel实现Excel文件导入导出

Java解析、生成Excel比较有名的框架有Apache poi、jxl等,使用者可自行斟酌。

一、 为什么使用 EasyExcel

1.1 内存控制

Apache poi、jxl也能解析Excel,但他们都存在一个问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。

easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

1.2 使用简洁

EasyExcel 可以映射excel和实体类,让代码变的更加简洁,读写更方便。

二、springboot 整合 EasyExcel

2.1 添加maven依赖
<!-- spring-boot 使用自己项目的版本就好 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- alibaba 相关依赖 -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.3</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId>
</dependency>
<!-- lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version>
</dependency>
2.2 读Excel
2.2.1 准备数据源,Excel 表
姓名证件号证件类型
张三500000000000000000x户口簿
李四5111111111111111111身份证
王不二5222222222222222222身份证
赵五5252513xdg护照
2.2.2 创建与数据表对应的实体类
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;/*** @author lqf* @date 2024/1/11 11:00*/
@Data
@EqualsAndHashCode
public class AccountCenterByExcelVO {/*** 姓名*/// 可以使用指定 表格下标或者 表头名字 的方式来对应数据。视情况选择,优弊如下:// 使用表下标,会让制表变得不灵活,使用表名会造成 名字重复,只有一个字段读取到数据// @ExcelProperty(index = 1)@ExcelProperty("姓名")private String name;/*** 证件号*/@ExcelProperty("证件号")private String IdNumber;/*** 证件类型*/@ExcelProperty("证件类型")private String IdType;/*** 这里用string 去接日期才能格式化。我想接收年月日格式*/@ExcelProperty("日期")@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")private String date;/*** 想接收百分比的数字*/@ExcelProperty("余额")@NumberFormat("#.##%")private String doubleData;
}
2.2.3 自定义转换器(可以不自定义,可使用EasyExcel 自带的 PageReadListener)
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.insupro.flexibleServerJ.dto.resp.vo.AccountCenterByExcelVO;
import lombok.extern.slf4j.Slf4j;import java.util.List;/*** 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去* @author lqf*/
@Slf4j
public class ACByExcelListener implements ReadListener<AccountCenterByExcelVO> {/*** 每隔 N 条 进行一次数据处理,根据实际使用情况处理,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;/*** 缓存的数据*/private List<AccountCenterByExcelVO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。* 用来存储或者处理数据*/private AccountCenterByExcelVO excelVo;/*** 每次创建Listener的时候需要把spring管理的类传进来** @param excelVo*/public ACByExcelListener(AccountCenterByExcelVO excelVo) {this.excelVo = excelVo;}/*** 这个每一条数据解析都会来调用** @param data* @param context*/@Overridepublic void invoke(AccountCenterByExcelVO data, AnalysisContext context) {cachedDataList.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();log.info("所有数据解析完成!");}/*** 加上存储数据库*/public void saveData() {log.info("{}条数据,开始处理数据!", cachedDataList.size());log.info("解析结果:"+JSON.toJSONString(cachedDataList));// 调用业务逻辑服务处理数据,实例是假装有业务逻辑log.info(excelVo.toString());log.info("数据处理成功!");}
}
2.2.4 创建一个文件处理 Controller

只是示例代码,业务逻辑没有写入server 层,使用的时候自行将业务代码归类


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.insupro.flexibleServerJ.dto.resp.vo.AccountCenterByExcelVO;
import com.insupro.flexibleServerJ.utils.ACByExcelListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.util.ArrayList;
import java.util.List;/*** @author lqf* @date 2024/1/11 13:46*/
@Slf4j
@RestController
@RequestMapping("api/easyExcel")
public class EasyExcelController {@RequestMapping("upExcel")public String upExcel(MultipartFile multipartFile){try {List<AccountCenterByExcelVO> acvoList = new ArrayList<>();// 第一种 使用 EasyExcel 自带的 PageReadListener,可以将数据读取后拿到读取的所有数据// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行// 具体需要返回多少行可以在`PageReadListener`的构造函数设置EasyExcel.read(multipartFile.getInputStream(), AccountCenterByExcelVO.class,new PageReadListener<AccountCenterByExcelVO>(dateList ->{// 这里默认每次会读取100条数据,然后进入下一次读取log.info(JSON.toJSONString(dateList));// 保存每一次的数据读取即可acvoList.addAll(dateList);})).sheet().doRead();System.out.println(acvoList);// 第二种,使用自定义监听器, 数据集处理需要再监听器中定义EasyExcel.read(multipartFile.getInputStream(), AccountCenterByExcelVO.class,new ACByExcelListener(new AccountCenterByExcelVO())).sheet()// 不添加属性,默认头部是1行.headRowNumber(1).doRead();}catch (Exception e){e.printStackTrace();}return "完成";}
}
2.3 写出excel
2.3.1 创建写出的 实体类

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.util.Date;/*** @author lqf* @date 2024/1/11 11:00*/
@Data
@EqualsAndHashCode
public class AccountWriteForExcelVO {/*** 姓名* */// 可以使用指定 表格下标或者 表头名字 的方式来对应数据。视情况选择,优弊如下:// 使用表下标,会让制表变得不灵活,使用表名会造成 名字重复,只有一个字段读取到数据// @ExcelProperty(index = 1)@ExcelProperty("姓名")private String name;/*** 证件号*/@ExcelProperty("证件号")private String IdNumber;/*** 证件类型*/@ExcelProperty("证件类型")private String IdType;/*** 这里用string 去接日期才能格式化。我想接收年月日格式*/@ExcelProperty("日期")@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")private Date date;/*** 想接收百分比的数字*/@ExcelProperty("余额")@NumberFormat("#.##%")private Double doubleData;
}
2.3.2 实现简单写出逻辑
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import vo.AccountWriteForExcelVO;import java.util.Date;
import java.util.List;/*** @author lqf* @date 2024/1/11 11:00*/
public class WriteExcleDemo {public static void main(String[] args) {// 使用自己指定输出的文件路径String fileName = "D:/workSpace/" + "simpleWrite" + System.currentTimeMillis() + ".xlsx";System.out.println(fileName);// 注意 数据量大参照 重复多次写入// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, AccountWriteForExcelVO.class).sheet("模板").doWrite(() -> {// 分页查询数据return data();});// 写法2// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, AccountWriteForExcelVO.class).sheet("模板").doWrite(data());// 写法3// 这里 需要指定写用哪个class去写try (ExcelWriter excelWriter = EasyExcel.write(fileName, AccountWriteForExcelVO.class).build()) {WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(data(), writeSheet);}}private static List<AccountWriteForExcelVO> data() {List<AccountWriteForExcelVO> list = ListUtils.newArrayList();for (int i = 0; i < 10; i++) {AccountWriteForExcelVO data = new AccountWriteForExcelVO();data.setName("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}
}

结语

更多使用方法,见官方文档
https://easyexcel.opensource.alibaba.com/docs/current/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ZK监控方法以及核心指标

文章目录 1. 监控指标采集1.1 zk版本高于3.6.0监控指标采集1.2 zk版本低于3.6.0监控指标采集1.3 配置promethues采集和大盘 2. 核心告警指标3. 参考文章 探讨zk的监控数据采集方式以及需要关注的核心指标&#xff0c;便于日常生产进行监控和巡检。 1. 监控指标采集 3.6.0 版本…

apache 前30个开源项目

由于Apache软件基金会的开源项目 前30个具有代表性的项目 序号项目名称功能描述业务范围活跃度&#xff08;参考性描述&#xff09;1Apache HTTP Server高性能Web服务器提供HTTP服务支持非常活跃2Apache TomcatJava应用服务器部署Java Web应用程序非常活跃3Apache Hadoop分布式…

ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连

用了网上的办法&#xff1a; 1、修改listener.ora的参数,把动态的参数设置为静态的参数,红色标注部分 位置D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME D:\oracle\produ…

基于PHP反序列化练习

PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age&#xff0c;进行序列化&#xff0c;输出序列化以后的数据。 <!-- PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age --> <?…

【C/C++】C/C++编程——第一个 C++ 程序:HelloWorld

第一个 C 程序&#xff1a;HelloWorld 大家好&#xff0c;我是 shopeeai&#xff0c;也可以叫我虾皮&#xff0c;中科大菜鸟研究生。昨天我们成功搭建好了 C 的开发环境&#xff0c;今天我们来介绍一下第一个 C 程序,打印一个"hello world"。首先我们先贴一下示例代…

《WebKit技术内幕》学习之十三(2):移动WebKit

2 移动化用户界面 HTML5为移动领域做了大量的工作&#xff0c;其中“meta”标签中的众多设置值能够帮助提供非常好的移动用户体验。一个典型的例子就是上面提到的用该标签来控制网页缩放&#xff0c;如示例代码13-2使用了一些JavaScript代码来完成&#xff0c;而实际上&#x…

【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

这里写目录标题 Verilog HDL简介与VHDL比较 Verilog HDL基础语法逻辑值关键字moduleendmodule 模块名输入信号输出信号既做输入也做输出线网型变量 wire寄存器型变量 reg参数 parameter参数 localparam常量赋值方式阻塞赋值非阻塞赋值 always语句assign 语句 算数运算符归元运算…

【C语言】分支循环语句

分支 if elseif else if else if elseswitch() case default 循环 while 防止死循环for 已知所需循环次数do while 至少执行一次 break 和continue在循环中的应用 break &#xff1a;退出当前循环&#xff1b; continue&#xff1a;推出本次/轮循环 goto 太乱了&#xff0c;不…

C++ Qt day2

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <io…

翻译: 使用 GPT-4 将您的 Streamlit 应用程序提升到一个新的水平一

帮助您更快地设计、调试和优化 Streamlit 应用的专业技巧 设计和扩展 Streamlit 应用程序可能是一项艰巨的任务&#xff01;作为开发人员&#xff0c;我们经常面临一些挑战&#xff0c;例如设计良好的 UI、快速调试我们的应用程序以及快速制作它们。 如果有一个工具可以加快速…

Tomcat运维

目录 一、Tomcat简介 二、系统环境说明 1、关闭防火墙&#xff0c;selinux 2、安装JDK 3、安装Tomcat 三、Tomcat目录介绍 1、tomcat主目录介绍 2、webapps目录介绍 3、Tomcat配置介绍&#xff08;conf&#xff09; 4、Tomcat的管理 四、Tomcat 配置管理页面(了解) …

类和对象 第三部分第三小节:const修饰成员函数

一.常函数&#xff1a; &#xff08;一&#xff09;成员函数后面加const后我们成这个函数为常函数 &#xff08;二&#xff09;常函数内不可以修改成员函数属性 额外补充&#xff1a; this指针的本质&#xff0c;是指针常量&#xff0c;指针指向的是不可以修改的 但是指针指向的…

点击查看灯塔工厂

“灯塔工厂”项目由达沃斯世界经济论坛与管理咨询公司麦肯锡合作开展遴选&#xff0c;被誉为“世界上最先进的工厂”&#xff0c;是工业4.0技术应用的最佳实践工厂&#xff0c;代表着全球智能制造的最高水平。目前全球“灯塔工厂”共有 153 座&#xff0c;包含中国 62 座。 做…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-11 HTML5 表单验证

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 表单验证</title> </head><body> <form action"#" method"get" novalidate>请输入您的邮箱:<input type&q…

无限学模式-“科研创新的加速器:全面掌握ChatGPT,推动研究方法和工作模式现代化!“

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

小型商用机器人,如何做到小而强?

兼顾体型和性能。 体型和性能的矛盾 一直以来&#xff0c;商用清洁机器人的应用场景主要集中在大型商场、超市、写字楼等&#xff0c;为什么1000平米以下的小型商超等中小场景却很少涉足&#xff1f;原因可以说有很多&#xff0c;但核心为两方面&#xff0c;一方面&#xff0…

工厂模式-策略工厂模式 两者的区别

模拟支付分为 微信支付 &#xff0c;支付宝支付&#xff0c;银联支付 1、工厂模式 &#xff08;1&#xff09;、支付枚举类 import lombok.Getter;/*** author zwh* date 2024/1/26*/ Getter public enum PayEnum {/*** 支付类型*/WX_PAY(1, "微信支付"),ALI_PAY(…

YOLOv8优化策略:注意力涨点系列篇 | 一种轻量级的加强通道信息和空间信息提取能力的MLCA注意力

🚀🚀🚀本文改进:一种轻量级的加强通道信息和空间信息提取能力 MLCA注意力 🚀🚀🚀在YOLOv8中如何使用 1)作为注意力机制使用;2)与c2f结合使用; 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研…

PaddleOCR将自己训练的模型转换为openvino格式模型

1 训练模型 python train_steelseal_det.py2 checkpoints模型转换为inference 模型 加载配置文件ch_PP-OCRv4_det_student_steelseal.yml&#xff0c;从./output/ch_PP-OCRv4/best_model/目录下加载model模型&#xff0c;inference模型保存在./output/ch_PP-OCRv4/best_model…

机器学习 | 深入探索Numpy的高性能计算能力

目录 初识numpy numpy基本操作 数组的基本操作 ndarray运算 数组间运算 矩阵 初识numpy Numpy&#xff08;Numerical Python&#xff09;是一个开源的Python科学计算库&#xff0c;用于快速处理任意维度的数组。Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务&…