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…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
