EasyExcel-最简单的读写excel工具类

前言:
easyExcel 的官网文档给的示例非常全,可以参考https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read
在此我贴出自己的工具类,可以直接用

导包

		<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>

读excel

1:最简单读-使用demo对象

创建对象bean

package com.wkl.testdemo.excel;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:28*/
@Data
public class DemoBean {/*** 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据*/@ExcelProperty("姓名")private String name;/*** 强制读取第二个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配*/@ExcelProperty(index = 1)private String sex;
}

创建读取器

package com.wkl.testdemo.excel;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.util.ListUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;import java.util.List;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:27*/
@Data
public class DemoListener extends AnalysisEventListener<DemoBean> {/*** 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;/*** 缓存的数据*/private List<DemoBean> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private DemoBean demoDAO;public DemoListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数demoDAO = new DemoBean();}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {if (exception instanceof ExcelDataConvertException) {Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;String message = "第" + rowIndex + "行,第" + columnIndex + "列,数据格式有误,请核实";System.out.println("导入数据转换出现错误: " + message);} else if (exception instanceof RuntimeException) {System.out.println("导入错误:" + exception);if (exception.getMessage().contains("列与模板上顺序不符,请勿修改表头模板")) {throw new RuntimeException(exception.getMessage());}}}@Overridepublic void invoke(DemoBean data, AnalysisContext analysisContext) {System.out.println("解析到一条数据:{}"+data);cachedDataList.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();System.out.println("解析完了");}/*** 加上存储数据库*/private void saveData() {System.out.println("{}条数据,开始存储数据库!"+ cachedDataList.size());
//        demoDAO.save(cachedDataList);System.out.println("存储数据库成功!");}}

测试程序

package com.wkl.testdemo.excel;import com.alibaba.excel.EasyExcel;import java.util.List;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:45*/
public class SimpleTest {public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";DemoListener listener = new DemoListener();EasyExcel.read(path,DemoBean.class,listener).sheet().doRead();List<DemoBean> cachedDataList = listener.getCachedDataList();System.out.println("end----");}
}

2:读取多个sheet

 public static void main(String[] args) {String path = "C:\\Users\\wenge\\Desktop\\demo.xlsx";DemoListener listener = new DemoListener();//生成读取对象ExcelReader excelReader = EasyExcel.read(path).build();//生成一个sheetReadSheet build = EasyExcel.readSheet(0).head(DemoBean.class).registerReadListener(listener).build();//读取多个sheetExcelReader read = excelReader.read(Arrays.asList(build));List<DemoBean> cachedDataList = listener.getCachedDataList();System.out.println("end----");

3:复杂头的读取

如果遇到这样的excel
在这里插入图片描述

创建对象bean

package com.wkl.testdemo.excel;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** @author wangkanglu* @version 1.0* @description* @date 2023-12-08 17:28*/
@Data
public class DemoBeanheads {/*** 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据*/@ExcelProperty({"大学","姓名"})private String name;/*** 强制读取第二个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配*/@ExcelProperty({"大学","性别"})private String sex;
}

读取器不变

测试程序

public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";DemoHeadListener listener = new DemoHeadListener();//生成读取对象ExcelReader excelReader = EasyExcel.read(path).build();//生成一个sheetReadSheet build = EasyExcel.readSheet(0).head(DemoBeanheads.class).registerReadListener(listener).headRowNumber(2).build();//读取多个sheetExcelReader read = excelReader.read(Arrays.asList(build));List<DemoBeanheads> cachedDataList = listener.getCachedDataList();System.out.println("end----");}

4:不创建对象的对

读取器

package com.wkl.testdemo.excel;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;@Slf4j
public class NoHeadMapListener extends AnalysisEventListener<Map<Integer, String>> {private List<Map<Integer, String>> list = new ArrayList<>();private static final SimpleDateFormat sdfFormat = new SimpleDateFormat("yyyy-MM-dd");//表头private List<String> headList = Arrays.asList("姓名","性别");@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {if (headMap==null){throw new RuntimeException("文件表头为空,请勿上传非法excel文件,请先下载对应的导入模板文件" );}if (headMap.size()!=headList.size()){throw new RuntimeException("文件表头列与模板不符,请勿上传非法excel文件,请先下载对应的导入模板文件" );}for (int i = 0; i < headList.size(); i++) {String tableHead = headMap.get(i);String head = headList.get(i);if (!head.equals(tableHead)) {throw new RuntimeException("表头中'" + tableHead + "'列与模板上顺序不符,请勿修改模板表头");}}}@Overridepublic void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
//        log.info("解析到一条数据:{}", JSON.toJSONString(integerStringMap));List<String> picList = new ArrayList<>();if (!ObjectUtils.isEmpty(integerStringMap)) {list.add(integerStringMap);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("所有数据解析完成!");}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {if (exception instanceof ExcelDataConvertException) {Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;String message = "第" + rowIndex + "行,第" + columnIndex + "列,数据格式有误,请核实";log.error("导入数据转换出现错误: " + message);} else if (exception instanceof RuntimeException) {log.error("导入错误:" + exception);if (exception.getMessage().contains("列与模板上顺序不符,请勿修改表头模板")) {throw new RuntimeException(exception.getMessage());}}}public List<String> getHeadList() {return headList;}public void setHeadList(List<String> headList) {this.headList = headList;}public List<Map<Integer, String>> getList() {return list;}}

测试程序

 public static void main(String[] args) {String path = "C:\\Users\\Desktop\\demo.xlsx";NoHeadMapListener listener = new NoHeadMapListener();EasyExcel.read(path, listener).sheet().doRead();List<String> headList = listener.getHeadList();List<Map<Integer, String>> list = listener.getList();System.out.println("end");}

读取后的得到的数据列表:
在这里插入图片描述

写excel

1:最简单的写

创建对象

@Getter
@Setter
@EqualsAndHashCode
public class DemoData {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ExcelProperty("数字标题")private Double doubleData;/*** 忽略这个字段*/@ExcelIgnoreprivate String ignore;
}

测试程序

List<DemoData> data = new ArrayList();
fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data);

测试程序-导出指定列

List<DemoData> data = new ArrayList();
fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 根据用户传入字段 假设我们要忽略 name列Set<String> excludeColumnFiledNames = new HashSet<String>();excludeColumnFiledNames.add("name");// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板").doWrite(data);// 根据用户传入字段 假设我们只要导出 name列Set<String> includeColumnFiledNames = new HashSet<String>();includeColumnFiledNames.add("name");// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板").doWrite(data);

2:数据写到不同的sheet

fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";// 这里 指定文件try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) {// 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面for (int i = 0; i < 5; i++) {// 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build();// 分页去数据库查询数据 这里可以去数据库查询每一页的数据List<DemoData> data = data();excelWriter.write(data, writeSheet);}}

3:动态表头写入web

private List<List<String>> head() {List<List<String>> list = new ArrayList<List<String>>();List<String> head0 = new ArrayList<String>();head0.add("字符串" + System.currentTimeMillis());List<String> head1 = new ArrayList<String>();head1.add("数字" + System.currentTimeMillis());List<String> head2 = new ArrayList<String>();head2.add("日期" + System.currentTimeMillis());list.add(head0);list.add(head1);list.add(head2);return list;}private List<DemoData> data() {List<DemoData> list = ListUtils.newArrayList();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}@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("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());}

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

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

相关文章

机器学习第15天:GBDT模型

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 文章目录 GBDT模型介绍 Boosting 残差 GBDT的缺点 python代码实现 代码 模型参数解释 结语 GBDT模型介绍 GBDT&#xff08;Gradient Boos…

php+mysql期末作业小项目

目录 1、登录界面 2、注册界面 3、主界面 4、学生表界面 5 、查询学生界面​编辑 6、修改学生信息界面​编辑 7、删除学生信息界面 8、添加学生信息界面 9、后台数据库​编辑 一个简单的php➕mysql项目学生信息管理系统&#xff0c;用于广大学子完成期末作业的参考&…

测试架构工程师需要具备哪些能力 ?

前言 相比于我们常见的研发架构师&#xff0c;测试架构师是近几年才出现的一个岗位&#xff0c;当然岗位title其实没有特殊的含义&#xff0c;在我看来测试架构师其实更像对某一类人的抽象称呼和对其复合能力的期待及认可。 在聊这篇文章的主题之前&#xff0c;先来看这样一个…

TCP通信

第二十一章 网络通信 本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点 这两种通讯方式不通的地方就是TCP是一对一通信 UDP是一对多的通信方式 接下来会一一讲解 TCP通信 TCP通信方式呢 主要的通讯方式是一对一的通讯方式&#xff0c;也有着优点和缺点…

如何在Android平板上远程连接Ubuntu服务器使用code-server代码开发

目录 1.ubuntu本地安装code-server 2. 安装cpolar内网穿透 3. 创建隧道映射本地端口 4. 安卓平板测试访问 5.固定域名公网地址 6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以&#xff0c;这里以VMwhere ubuntu系统为例 下载code server服务…

el-table 表格多选(后端接口搜索分页)实现已选中的记忆功能。实现表格数据和已选数据(前端分页)动态同步更新。

实现效果&#xff1a;&#xff08;可拉代码下来看&#xff1a;vue-demo: vueDemo&#xff09; 左侧表格为点击查询调用接口查询出来的数据&#xff0c;右侧表格为左侧表格所有选择的数据&#xff0c;由前端实现分页。 两个el-table勾选数据联动更新 实现逻辑&#xff1a; el-…

低代码开发到底是补品还是垃圾食品?

2023&#xff0c;低代码彻底火了&#xff0c;甚至火到没有点相关经验&#xff0c;都不好意思出去面试的程度。 从业者对低代码的发展充满了想象&#xff0c;都认为未来低代码的商业价值不可估量。 据Gartner的最新报告显示&#xff0c;2023年全球低代码开发技术市场规模预计将…

内部文件上传以及渲染-接口API

文件上传 地址http://172.16.0.118:8090/api/pm/base/affix/upload请求类型POSTContent-Type:text/plain;charsetutf-8参数 prjData {"prjId":"", "jobId":"3031b2c8-c809-4110-8e88-22c80a9c1ec0721aca89-96a1-4346-9b6e-022331d221d1Nec…

【EMNLP 2023】面向Stable Diffusion的自动Prompt工程算法BeautifulPrompt

近日&#xff0c;阿里云人工智能平台PAI与华南理工大学朱金辉教授团队合作在自然语言处理顶级会议EMNLP2023上发表了BeautifulPrompt的深度生成模型&#xff0c;可以从简单的图片描述中生成高质量的提示词&#xff0c;从而使文生图模型能够生成更美观的图像。BeautifulPrompt通…

【MATLAB】MODWT分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 MODWT分解FFTHHT组合算法是一种综合性的信号处理方法&#xff0c;它结合了经验小波变换&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;、快速傅里叶变换&#xff…

爱智EdgerOS之深入解析如何应用爱智的视频流模块完成拉流

一、ONVIF 规范和常见视频流传输协议 ① ONVIF 规范 随着视频监控产业链的成熟&#xff0c;市面上陆陆续续出现了各式各样的网络摄像设备&#xff0c;这些设备都需要通讯协议才能进行数据传输。早期厂商都采用私有协议&#xff0c;但是现在厂商分工明确&#xff0c;有的负责生…

程序员的技术成长攻略

推荐语&#xff1a;偶尔在公众号看到的一篇文章&#xff0c;写的非常好&#xff0c;在此分享给各位程序员兄弟&#xff0c;不光是对技术成长有帮助&#xff0c;其他领域也是同样适用的&#xff01;建议反复阅读&#xff0c;形成一套自己的技术成长策略。 原文地址&#xff1a;…

【EI会议征稿】2024年粤港澳大湾区数字经济与人工智能国际学术会议(DEAI2024)

2024年粤港澳大湾区数字经济与人工智能国际学术会议(DEAI2024) 2024 Guangdong-Hong Kong-Macao Greater Bay Area International Conference on Digital Economy and Artificial Intelligence(DEAI2024) 2024年粤港澳大湾区数字经济与人工智能国际学术会议(DEAI2024)由广东科…

探索鸿蒙 TextInput组件

TextInput 根据组件名字&#xff0c;可以得知他是一个文本输出框。 声明代码&#x1f447; TextInput({placeholder?:ResourceStr,text?:ResourceStr}); placeholder: 就是提示文本&#xff0c;跟网页开发中的placeholder一样的 text&#xff1a;输入框当前的文本内容 特殊属…

52 代码审计-PHP项目类RCE及文件包含下载删除

目录 漏洞关键字:演示案例:xhcms-无框架-文件包含跨站-搜索或应用-includeearmusic-无框架-文件下载-搜索或应用功能-down等zzzcms-无框架-文件删除RCE-搜索或应用-unlink、eval 漏洞关键字: SQL注入&#xff1a; select insert update mysql_query mysql等 文件上传&#xff…

【FreeRTOS】信号量——简介、常用API函数、注意事项、项目实现

在FreeRTOS中&#xff0c;信号量是一种非常重要的同步机制&#xff0c;用于实现任务间的互斥访问和同步操作。通过信号量&#xff0c;不同的任务可以安全地共享资源&#xff0c;避免竞争和冲突&#xff0c;从而确保系统的稳定性和可靠性。本篇博客将介绍FreeRTOS中信号量的基本…

使用Huggingface创建大语言模型RLHF训练流程的完整教程

ChatGPT已经成为家喻户晓的名字&#xff0c;而大语言模型在ChatGPT刺激下也得到了快速发展&#xff0c;这使得我们可以基于这些技术来改进我们的业务。 但是大语言模型像所有机器/深度学习模型一样&#xff0c;从数据中学习。因此也会有garbage in garbage out的规则。也就是说…

AUTOSAR CP Int-Watchdog简介

Int Watchdog 1 简介2 EB 中配置 TC39X3 Wdg 在代码中使用1 简介 内部看门狗驱动[sws_Wdg_00161]要访问内部看门狗硬件,对应的 Wdg 模块实例应该直接访问看门狗服务的硬件。提示:内部看门狗驱动程序是微控制器抽象层的一部分,它允许直接的硬件访问。注意:内部看门狗的日常服…

第21章总结 网络通信

21.1 网络程序设计基础 网络程序设计编写的是与其他计算机进行通信的程序。Java已经将网络程序所需要的元素封装成不同的类&#xff0c;用户只要创建这些类的对象&#xff0c;使用相应的方法&#xff0c;即使不具备有关的网络知识&#xff0c;也可以编写出高质量的网络通信程序…

【评测脚本】机器信息评测(初版)

背景 QA的实际工作过程中,除了业务相关的测试外,也会涉及到一些评测相关的工作,甚至还要做多版本、多维度的评估分析。尤其是现在火热的大模型,相关的评测内容更是核心中的核心。当然本文的内容只是做一些初级的机器相关的评测信息,更多更广的评测需要更多时间的积累和总…