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…...
如何在VMware上运行macOS虚拟机:终极Unlocker完整指南
如何在VMware上运行macOS虚拟机:终极Unlocker完整指南 【免费下载链接】unlocker VMware Workstation macOS 项目地址: https://gitcode.com/gh_mirrors/unloc/unlocker 你是不是一直想在Windows或Linux电脑上体验macOS系统,却被VMware的限制挡在…...
FaceRecon-3D与TensorFlow:深度学习模型优化
FaceRecon-3D与TensorFlow:深度学习模型优化 1. 引言 你是否曾经遇到过这样的场景:训练了一个效果不错的FaceRecon-3D模型,但在实际部署时却发现推理速度太慢,内存占用太高?或者想要在移动设备上运行3D人脸重建&…...
丹青识画系统在网络安全中的应用:图像内容安全审核实战
丹青识画系统在网络安全中的应用:图像内容安全审核实战 最近和几个做内容平台的朋友聊天,他们都在头疼同一个问题:用户上传的图片越来越多,人工审核根本看不过来,而且尺度很难把握。漏掉一张违规图,可能就…...
Qwen3Guard安全模型HTTPS部署:保姆级Nginx反向代理配置指南
Qwen3Guard安全模型HTTPS部署:保姆级Nginx反向代理配置指南 1. 引言 1.1 为什么需要HTTPS部署 在当今数字化环境中,内容安全审核已成为各类在线平台的基础需求。Qwen3Guard作为阿里开源的安全审核模型,能够有效识别和过滤不安全内容。然而…...
从FEE到FLS:深入Autosar存储栈底层,搞懂Flash模拟EEPROM的完整流程
从FEE到FLS:深入Autosar存储栈底层,搞懂Flash模拟EEPROM的完整流程 在汽车电子领域,非易失性存储管理一直是嵌入式系统设计的核心挑战之一。当工程师需要在片内Flash上实现类似EEPROM的细粒度数据更新功能时,Autosar存储协议栈提…...
实测雪女-斗罗大陆-造相Z-Turbo:简单几步,让文字描述变成精美动漫图
实测雪女-斗罗大陆-造相Z-Turbo:简单几步,让文字描述变成精美动漫图 1. 模型介绍与准备工作 1.1 什么是雪女-斗罗大陆-造相Z-Turbo 雪女-斗罗大陆-造相Z-Turbo是一款基于Xinference部署的文生图模型服务,专门用于生成斗罗大陆中雪女角色的…...
编写程序实现智能乐器音准检测偏差时,提示“需要调音”,新手也能调好音。
1. 实际应用场景描述场景:一名吉他初学者刚刚买回一把新吉他,或者在干燥天气后琴弦音准发生了偏移。他不知道电子调音表如何使用,也不具备绝对音感。本系统功能:用户拨动琴弦(例如第 6 弦 E2),电…...
Qwen3.5-9B-AWQ-4bit Anaconda环境管理大师:依赖冲突解决与虚拟环境配置
Qwen3.5-9B-AWQ-4bit Anaconda环境管理大师:依赖冲突解决与虚拟环境配置 1. 为什么需要环境管理助手 Python开发中最让人头疼的问题之一就是依赖冲突。当你兴冲冲地准备运行一个新项目时,却看到满屏红色错误提示:"Could not find a ve…...
如何在 React 中正确绑定 onClick 事件以避免类型错误
React 中 onClick 期望接收一个函数,若传入字符串或直接执行表达式(如 window.href...)会导致“Expected onclick listener to be a function”报错;正确做法是使用箭头函数包裹逻辑。 react 中 onclick 期望接收一个函数&am…...
OpenClaw自动化测试进阶:Phi-3-vision-128k验证APP多语言界面一致性
OpenClaw自动化测试进阶:Phi-3-vision-128k验证APP多语言界面一致性 1. 为什么需要自动化多语言测试 作为独立开发者,去年我发布了一款工具类APP到国际市场。当用户基数突破1万时,收到了30多条关于德语界面错译的差评——某个按钮的"取…...
