EasyExcel简单使用
EasyExcel简单使用
之前一直用的Apache POI来做数据的导入导出,但听说阿里的EasyExcel也拥有POI的功能的同时,在处理大数据量的导入导出的时候性能上比POI更好,所以就来尝试使用一下
导入Maven依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version> <!-- 请检查并使用最新稳定版本 -->
</dependency>
导出数据功能
导出模型类
定义一个导出数据模型类,用于设置excel文件的格式,通过注解的方式可以定义excel中的格式
@ColumnWidth(20) 设置excel中列的宽度为20;
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER) 设置文本内容是否居中;
@HeadFontStyle(bold = BooleanEnum.FALSE) 设置字体是否加粗;
@ExcelProperty(value = “电话”, index = 0) 设置了excel中的标题,value则是标题内容,index则是内容所在的列的位置
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ColumnWidth(20)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
@HeadFontStyle(bold = BooleanEnum.FALSE)
public class PmembersExportVO {@ColumnWidth(15)@ExcelProperty(value = "电话", index = 0)private String mobile;@ColumnWidth(15)@ExcelProperty(value = "姓名", index = 1)private String realname;@ColumnWidth(10)@ExcelProperty(value = "性别", index = 2)private String gender;@ColumnWidth(10)@ExcelProperty(value = "省份", index = 3)private String resideprovince;@ColumnWidth(10)@ExcelProperty(value = "城市", index = 4)private String residecity;@ColumnWidth(10)@ExcelProperty(value = "区/县", index = 5)private String residedist;@ColumnWidth(20)@ExcelProperty(value = "地址", index = 6)private String address;@ColumnWidth(12)@ExcelProperty(value = "公历生日", index = 7)private String birth;@ColumnWidth(12)@ExcelProperty(value = "农历生日", index = 8)private String yinlibirth;@ColumnWidth(12)@ExcelProperty(value = "是否闰月", index = 9)private String isLeapMonth;}
controller代码
@ApiOperation("导出居士信息")@ApiImplicitParams({@ApiImplicitParam(name = "weiqingview_backend_token", value = "token", required = true, dataType = "String", paramType = "header"),@ApiImplicitParam(name = "uniacid", value = "Unicid", required = true, dataType = "Integer", paramType = "query")})@GetMapping("/export")public void export(@RequestParam Map<String, Object> params, HttpServletResponse response) {mcMembersService.exportExcel(params, response);}
service代码
通过查询数据库中的数据,并封装到List集合中,调用EasyExcel的write方法即可将集合中的数据写入生成excel文件供下载
public void export(Map<String, Object> params, HttpServletResponse response) {Integer uniacid = Integer.valueOf(params.get("uniacid").toString());List<McMembers> mcMembersList = this.list(new QueryWrapper<McMembers>().eq("isBeliever", 1).eq("uniacid", uniacid));List<PmembersExportVO> pmembersExportVOList = mcMembersList.stream().map(m -> {PmembersExportVO pmembersExportVO = new PmembersExportVO();pmembersExportVO.setAddress(m.getAddress());pmembersExportVO.setMobile(m.getMobile());pmembersExportVO.setGender(ObjectUtils.isEmpty(m.getGender()) ? "" : m.getGender().equals(0) ? "女" : "男");pmembersExportVO.setBirth(m.getBirth());pmembersExportVO.setYinlibirth(m.getYinlibirth());pmembersExportVO.setRealname(m.getRealname());pmembersExportVO.setResidedist(m.getResidedist());pmembersExportVO.setResidecity(m.getResidecity());pmembersExportVO.setResideprovince(m.getResideprovince());pmembersExportVO.setIsLeapMonth(ObjectUtils.isEmpty(m.getIsLeapMonth()) ? "否" : m.getIsLeapMonth() == 1 ? "是" : "否");return pmembersExportVO;}).collect(Collectors.toList());// // 导出Excel
// EasyExcel.write("居士信息数据.xls", PmembersExportVO.class)
.head(headersList) // 设置表头
// .sheet("用户信息")
// .doWrite(pmembersExportVOList);// 设置响应头response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");String fileName = null;try {fileName = URLEncoder.encode("居士信息数据.xlsx", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName);EasyExcel.write(response.getOutputStream(), PmembersExportVO.class).sheet("用户信息").doWrite(pmembersExportVOList);} catch (UnsupportedEncodingException e) {log.error("导出居士信息报错 UnsupportedEncodingException:{}", e);} catch (IOException e) {log.error("导出居士信息报错 IOException:{}", e);}}

导入数据功能:
导入数据模型类
我这里用的跟导出数据类基本一致,所以也就改了个类名
只要用@ExcelProperty指定对应列的信息就行,其他指定格式的注解其实可以忽略
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ColumnWidth(20)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
@HeadFontStyle(bold = BooleanEnum.FALSE)
public class ImportPmcMembersDTO {@ColumnWidth(15)@ExcelProperty(value = "电话", index = 0)private String mobile;@ColumnWidth(15)@ExcelProperty(value = "姓名", index = 1)private String realname;@ColumnWidth(10)@ExcelProperty(value = "性别", index = 2)private String gender;@ColumnWidth(10)@ExcelProperty(value = "省份", index = 3)private String resideprovince;@ColumnWidth(10)@ExcelProperty(value = "城市", index = 4)private String residecity;@ColumnWidth(10)@ExcelProperty(value = "区/县", index = 5)private String residedist;@ColumnWidth(20)@ExcelProperty(value = "地址", index = 6)private String address;@ColumnWidth(12)@ExcelProperty(value = "公历生日", index = 7)private String birth;@ColumnWidth(12)@ExcelProperty(value = "农历生日", index = 8)private String yinlibirth;@ColumnWidth(12)@ExcelProperty(value = "是否闰月", index = 9)private String isLeapMonth;}
controller代码
前端页面上传一个name是file的文件
@ApiOperation("导入居士信息")@ApiImplicitParams({@ApiImplicitParam(name = "weiqingview_backend_token", value = "token", required = true, dataType = "String", paramType = "header"),@ApiImplicitParam(name = "uniacid", value = "Unicid", required = true, dataType = "Integer", paramType = "query"),@ApiImplicitParam(name = "file", value = "file", required = true, dataType = "MultipartFile", paramType = "query")})@PostMapping("/uploadExcel")public R uploadExcel(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) {return mcMembersService.importExcel(file, params);}
service代码
下面是接收controller传来的文件后,通过调用EasyExcel的read方法,直接进行导入操作
public R importExcel(MultipartFile file, Map<String, Object> params) {// 检查文件是否为空if (file.isEmpty()) {return R.error("没有检测到文件"); // 返回错误页面}try {// 执行导入操作EasyExcel.read(file.getInputStream(), ImportPmcMembersDTO.class, new ImportPmcMembersListener(this, params)).sheet().doRead();// 返回上传成功页面return R.ok("导入excel成功");} catch (IOException e) {e.printStackTrace();return R.error("导入excel失败");}}
下面是service中基本的添加数据的操作方法,导入数据插库的时候也直接调用,就不写新的插库方法了
public R pAdd(AddPmcMembersDTO addPmcMembersDTO, Map<String, Object> params) {McMembers mcMembers = new McMembers();BeanUtils.copyProperties(addPmcMembersDTO, mcMembers);mcMembers.setIsBeliever((byte) 1);Integer uniacid = Integer.parseInt(params.get("uniacid").toString());mcMembers.setUniacid(uniacid);if (this.save(mcMembers)) {return R.ok("添加成功");}return R.error("添加失败");}
listener代码
上传的话需要定义一个listener,并继承AnalysisEventListener,这里的T类型就是上面定义的模型类的类型。
如果是在listener中进行插库操作,那需要把service注入进来,但是在listener中不能用@Autowired,所以重写一个带参的构造方法,把注入好的service直接传进来使用即可,我下面将注入好的mcMembersService传递了进来,执行插库操作。下面的AddPmcMembersDTO是我另外定义的一个模型类,是用于界面上添加数据用的,这里直接转换后调用进行插库操作了。
当然也可以在listener中先将excel中的数据都封装到List集合中,再统一将List中的数据插库也行。
public class ImportPmcMembersListener extends AnalysisEventListener<ImportPmcMembersDTO> {private McMembersService mcMembersService;private Map<String, Object> params;//通过构造方法,得到注入好的mcMembersServicepublic ImportPmcMembersListener(McMembersService mcMembersService, Map<String, Object> params) {this.mcMembersService = mcMembersService;this.params = params;}@Overridepublic void invoke(ImportPmcMembersDTO data, AnalysisContext context) {// 处理读取到的每行数据,例如保存到数据库System.out.println("读取到一行数据: " + data.toString());// 这里可以添加保存到数据库的逻辑AddPmcMembersDTO addPmcMembersDTO = new AddPmcMembersDTO();addPmcMembersDTO.setMobile(data.getMobile());addPmcMembersDTO.setRealname(data.getRealname());addPmcMembersDTO.setGender((byte) (ObjectUtils.isEmpty(data.getGender()) ? 0 : data.getGender().equals("男") ? 1 : 2));addPmcMembersDTO.setAddress(data.getAddress());addPmcMembersDTO.setBirth(data.getBirth());addPmcMembersDTO.setYinlibirth(data.getYinlibirth());addPmcMembersDTO.setResidedist(data.getResidedist());addPmcMembersDTO.setResidecity(data.getResidecity());addPmcMembersDTO.setResideprovince(data.getResideprovince());addPmcMembersDTO.setIsLeapMonth((byte) (ObjectUtils.isEmpty(data.getIsLeapMonth()) ? 0 : data.getIsLeapMonth().equals("是") ? 1 : 0));// 进行插库操作mcMembersService.pAdd(addPmcMembersDTO, params);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 所有数据解析完毕后的回调System.out.println("所有数据解析完成");}
将一下excel数据进行导入操作

用Api工具测试了下,上传成功

查看数据库,数据也成功导入

整体感觉挺好用的,对于不同的数据进行导入的话,其实可以再封装成通用的listener,这样不用每一个功能导入都去定义一个listener,这个等后面有空再折腾吧。
结束
相关文章:
EasyExcel简单使用
EasyExcel简单使用 之前一直用的Apache POI来做数据的导入导出,但听说阿里的EasyExcel也拥有POI的功能的同时,在处理大数据量的导入导出的时候性能上比POI更好,所以就来尝试使用一下 导入Maven依赖: <dependency><…...
Notes客户端中的漫游功能
大家好,才是真的好。 故事,首先是从一个小图标开始的,很多人问我Domino公共通讯录中,个人文档前面有一个绿色小球图标,这是什么意思? 我的答案:这是Notes客户端中的漫游功能。 说到漫游&…...
为什么要内存对齐?
首先,我们介绍一下结构体内存对齐的规则: 1.第一个成员在与结构体偏移量为0的地址处。 2.其他成员变量要对其到某个数字(对齐数)的整数倍的地址处。 注:对齐数编译器默认的一个对齐数与该成员大小的较小值ÿ…...
23、Flink 的 Savepoints 详解
Savepoints 1.什么是 Savepoints Savepoint 是依据 Flink checkpointing 机制所创建的流作业执行状态的镜像,可以使用 Savepoint 进行 Flink 作业的停止、重启或更新。 Savepoint 由两部分组成:稳定存储(例如 HDFS,S3ÿ…...
【Unity】Unity项目转抖音小游戏(二)云数据库和云函数
业务需求,开始接触一下抖音小游戏相关的内容,开发过程中记录一下流程。 抖音云官方文档:https://developer.open-douyin.com/docs/resource/zh-CN/developer/tools/cloud/develop-guide/cloud-function-debug 1.开通抖音云环境 抖音云地址&a…...
SpringBoot集成jasypt对yml文件指定参数加密并自定义@bean隐藏密钥
1、查看SpringBoot和jasypt对应版本。 Jasypt 1.9.x 通常与 Spring Boot 1.5.x 相对应。 Jasypt 2.1.x 通常与 Spring Boot 2.0.x 相对应。 Jasypt 3.x 通常与 Spring Boot 2.1.x相对应。 2、引入maven <dependency><groupId>com.github.ulisesbocchio</groupI…...
GDB的使用
即目标机直接使用GDB调试 源码安装: Index of /gnu/gdb 或者 wget https://ftp.gnu.org/gnu/gdb/gdb-8.3.1.tar.gz ./configure make main install 编译报错解决方法: 解决编译安装gdb-10.1 unistd.h:663:3: error: #error “Please include con…...
Linux处理用户输入
目录 一、传递参数 1.1 读取参数 1.2 读取脚本名 二、跟踪参数 三、移动参数 四、处理选项 4.1 查找选项 4.1.1 处理简单选项 4.1.2 分离参数和选项 4.1.3 处理含值的选项 五、选项标准化 5.1 使用 getopt 命令 5.1.1 命令格式 5.1.2 在脚本中使用getopt 5.2 使用…...
【代码笔记】高并发场景下问题解决思路
高并发指的是在单位时间内,瞬时流量激增,系统需要同时处理大量并行的请求或操作。这种情况通常出现在面向大量用户或服务的分布式系统中,尤其是当用户请求高度集中时,比如促销活动、秒杀活动、注册抢课、热点事件、定时任务调度等…...
【Docker系列】Linux部署Docker Compose
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
基于SSM的文化遗产的保护与旅游开发系统(有报告)。Javaee项目。ssm项目。
演示视频: 基于SSM的文化遗产的保护与旅游开发系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,…...
整合springboot-mybatis时,MySQL数据库无法连接问题
整合springboot-mybatis时,MySQL数据库无法连接问题 解决步骤 先手动停止MySQL服务,在cmd后的控制台输入services.msc 找到MySql停止服务 修改配置文件,跳过验证 修改MySQL安装目录下的my.ini配置文件,使登录时跳过权限检查&a…...
C语言循环队列
以下是一个使用 C 语言实现的简单循环队列示例: #include <stdio.h> #include <stdlib.h>#define MAX_SIZE 5// 定义循环队列结构体 typedef struct {int items[MAX_SIZE];int front, rear; } Queue;// 初始化队列 void initQueue(Queue *q) {q->fr…...
Docker运行出现iptables: No chain/target/match by that name报错如何解决?
在尝试重启 Docker 容器时遇到的错误信息表明有关 iptables 的配置出了问题。这通常是因为 Docker 需要配置网络,而 iptables 规则没有正确设置或被意外删除。具体到你的错误信息中,报错 iptables: No chain/target/match by that name 表示 Docker 尝试…...
力扣 122. 买卖股票的最佳时机 II python AC
动态规划 class Solution:def maxProfit(self, prices):pre float(inf)ans 0for now in prices:if now > pre:ans now - prepre nowreturn ans定义一个变量保存上一步位置最小的数值,来模拟dp --遍历股票数值 --如果当前数值大于上一次,将股票卖…...
F5 BIG-IP Next Central Manager SQL注入漏洞(CVE-2024-26026、CVE-2024-21793)
0x01 产品简介 BIG-IP Next Central Manager是BIG-IP Next的原生默认用户界面,它可跨平台管理BIG-IP Next实例。BIG-IP Next是F5 Networks公司推出的一款下一代BIG-IP软件,提供了多云应用安全和应用交付服务。 0x02 漏洞概述 CVE-2024-26026:BIG-IP Next Central Manager…...
Python3 笔记:循环结构 for语句
for语句是Python语言中构造循环结构程序的语句之一。 Python中for语句是通过循环遍历某一序列对象(字符串、列表、元组或字典)来构建循环,循环结束的条件就是对象被遍历完。 for循环基本语法格式: for 循环变量 in 遍历对象: …...
信息化与数字化的区别在哪里?
信息化与数字化虽然密切相关,但它们在核心理念、实施范围、目标定位、以及对企业的影响上存在本质区别: 1.中心与目标不同: • 信息化通常以流程为中心,致力于提高工作效率,通过信息技术优化和自动化企业内部的流程。…...
记录MySQL数据库查询不等于xxx时的坑
目录 一、背景 二、需求 三、方法 四、示例 一、背景 在使用MySQL数据库查询数据时,需要查询字段name不等于xxx的记录,通过where name ! xxx查询出来的记录不符合预期,通过检查发现少了name字段为null的记录,后经查询得知在My…...
QT的创建,发现编译器有一个黄色三角形感叹号,提示说Cmake配置错误,该怎么办?
确保你安装了Cmake 2.如果你电脑之前已经装了Cmake,那么在qt安装中,即便你选择了Cmake版本,但依旧不会修改电脑的Cmake版本。这时候就会出现黄色箭头。在勾勾的地方会有一个黄色感叹符号(我已经解决了,所以没有显示&a…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
