Springboot使用EasyExcel导入导出Excel文件
1,准备Excel文件和数据库表结果


2,导入代码
1,引入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>
2,创建请求body
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** Description** @author WangYaoLong* @createdate 2023/11/01 0001 11:43*/
@Data
public class StudentImportExcelForm {@ExcelProperty(value = "学生姓名", index = 0)private String name;@ExcelProperty(value = "性别", index = 1)private String sex;@ExcelProperty(value = "学号", index = 2)private String stuId;@ExcelProperty(value = "身份证号", index = 3)private String identityNum;@ExcelProperty(value = "所在班级", index = 4)private String classesId;@ExcelProperty(value = "简介", index = 5)private String remarks;@ExcelProperty(value = "生日", index = 6)private String birthday;
}
3,Excel文件数据解析
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.wang.dog.exception.BusinessException;
import com.wang.dog.pojo.form.StudentImportExcelForm;
import com.wang.dog.service.StudentService;
import com.wang.dog.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;/*** Description** @author WangYaoLong* @createdate 2023/11/01 0001 11:42*/
@Slf4j
public class StudentImportExcelListener extends AnalysisEventListener<StudentImportExcelForm> {private final List<StudentImportExcelForm> list = new ArrayList<>();private final StudentService studentService;public StudentImportExcelListener() {this.studentService = SpringContextHolder.getBean(StudentService.class);}private StringBuilder msg = new StringBuilder();@Overridepublic void invoke(StudentImportExcelForm studentExcelForm, AnalysisContext analysisContext) {log.info("学生信息" + studentExcelForm);checkStudentFiled(studentExcelForm);list.add(studentExcelForm);}/*** 校验学生信息** @param studentExcelForm 学生导入表单*/private void checkStudentFiled(StudentImportExcelForm studentExcelForm) {String name = studentExcelForm.getName();String stuId = studentExcelForm.getStuId();String classesId = studentExcelForm.getClassesId();String sex = studentExcelForm.getSex();String identityNum = studentExcelForm.getIdentityNum();if (StringUtils.isBlank(name)) {msg.append("学生姓名不能为空!");}if (StringUtils.isBlank(stuId)) {msg.append("学生学号不能为空!");}if (StringUtils.isBlank(classesId)) {msg.append("学生所在班级不能为空!");}if (StringUtils.isBlank(sex)) {msg.append("学生性别不能为空!");}if (StringUtils.isBlank(identityNum)) {msg.append("学生身份证信息不能为空!");}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {if (StringUtils.isNotBlank(msg)) {throw new ExcelAnalysisException("导入失败!<br/>" + msg.toString());}if (CollectionUtils.isEmpty(list)) {throw new BusinessException("导入文件为空");}// 保存学生信息saveData();// 清空集合和异常信息msg = null;list.clear();}/*** 保存 加上存储数据库*/@Transactional(rollbackFor = Exception.class)public void saveData() {studentService.importExcelData(list);}
}
4,在StudentService中新增接口以及实现类保存数据
接口方法
/*** 导入Excel学生信息** @param list 学生信息集合*/void importExcelData(List<StudentImportExcelForm> list);
实现类
@Overridepublic void importExcelData(List<StudentImportExcelForm> list) {List<Student> studentList = new ArrayList<>();list.forEach(s -> {Student student = new Student();student.setName(s.getName());student.setSex(Integer.parseInt(String.valueOf(s.getSex().equals("男") ? 0 : 1)));student.setStuId(s.getStuId());student.setIdentityNum(s.getIdentityNum());student.setClassesId(s.getClassesId());student.setCreateTime(new Date());student.setUpdateTime(new Date());student.setCreateBy(s.getName());student.setUpdateBy(s.getName());student.setDelFlag(0);student.setRemarks(s.getRemarks());student.setBirthday(s.getBirthday());studentList.add(student);});// 批量保存学生信息this.saveBatch(studentList);}
5,新增导入Excel接口
@Slf4j
@RequestMapping("/student")
@RestController
public class StudentController {@PostMapping("/import")public Result uploadStudentInfo(MultipartFile file) throws IOException {InputStream is = file.getInputStream();EasyExcel.read(is, StudentImportExcelForm.class, new StudentImportExcelListener()).sheet(0).headRowNumber(1).doRead();return Result.ok("success");}
}
6,测试

3,导出Excel
1,导出Excel表单请求
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** Description** @author WangYaoLong* @createdate 2023/11/01 0001 13:03*/
@Data
public class StudentExportExcelForm {@ApiModelProperty(value = "姓名", example = "")private String name;@ApiModelProperty(value = "身份证号", example = "")private String identityNum;@ApiModelProperty(value = "所在班级", example = "")private String classesId;@ApiModelProperty(value = "性别", example = "")private String sex;}
2,返回表单
@Data
@HeadRowHeight(15) // 高度
@HeadFontStyle(fontHeightInPoints = 10)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER) // 字体居中显示
public class StudentExportExcelVo {@ExcelProperty(value = "学生姓名", order = 1)@ColumnWidth(20) // excel 单元格间距private String name;@ExcelProperty(value = "性别", order = 2)@ColumnWidth(20)private String sex;@ExcelProperty(value = "学号", order = 3)@ColumnWidth(20)private String stuId;@ExcelProperty(value = "身份证号", order = 4)@ColumnWidth(20)private String identityNum;@ExcelProperty(value = "所在班级", order = 5)@ColumnWidth(20)private String classesId;@ExcelProperty(value = "简介", order = 6)@ColumnWidth(20)private String remarks;@ExcelProperty(value = "生日", order = 7)@ColumnWidth(20)private String birthday;
}
3,导出查询接口
@GetMapping("/export")public void exportStudentExcel(StudentExportExcelForm studentExportExcelForm, HttpServletResponse response) throws Exception {List<StudentExportExcelVo> list = studentService.exportStudent(studentExportExcelForm);// 不带表头//DownExcelUtils.download(response, StudentExportExcelVo.class, list, "学生信息导出");// 增加表头DownExcelUtils.download(response, StudentExportExcelVo.class, list, "学生信息导出", ExportStudentExcelHandler.class);}
4,学生数据查询
/*** 查询学生信息** @param studentExportExcelForm 学生请求表单* @return List*/List<StudentExportExcelVo> exportStudent(StudentExportExcelForm studentExportExcelForm);
实现类:
@Overridepublic List<StudentExportExcelVo> exportStudent(StudentExportExcelForm form) {List<StudentExportExcelVo> list = Lists.newArrayList();LambdaQueryWrapper<Student> studentQueryWrapper = Wrappers.<Student>lambdaQuery().orderByAsc(Student::getBirthday);if (StringUtils.isNotBlank(form.getName())) {studentQueryWrapper.like(Student::getName, form.getName());}if (StringUtils.isNotBlank(form.getIdentityNum())) {studentQueryWrapper.eq(Student::getIdentityNum, form.getIdentityNum());}if (StringUtils.isNotBlank(form.getClassesId())) {studentQueryWrapper.eq(Student::getClassesId, form.getClassesId());}if (StringUtils.isNotBlank(form.getSex())) {studentQueryWrapper.eq(Student::getSex, form.getSex().equals("男") ? 0 : 1);}List<Student> studentList = studentMapper.selectList(studentQueryWrapper);if (CollectionUtils.isNotEmpty(studentList)) {studentList.forEach(s -> {StudentExportExcelVo vo = new StudentExportExcelVo();BeanUtils.copyProperties(s, vo);vo.setSex(s.getSex() == 0 ? "男" : "女");list.add(vo);});}return list;}
5,导出工具类
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.handler.WriteHandler;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;/*** @author: WangYaoLong* @date: 2022/8/1* @description: excel导出工具类*/
public class DownExcelUtils {/*** 带有表头提示** @param response* @param t* @param list* @param fileName* @param z* @throws IOException* @throws IllegalAccessException* @throws InstantiationException*/public static void download(HttpServletResponse response, Class t, List list, String fileName, Class z) throws IOException, IllegalAccessException, InstantiationException {// 设置文本内省response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");EasyExcel.write(response.getOutputStream(), t).sheet(fileName)//设置拦截器或自定义样式.registerWriteHandler((WriteHandler) z.newInstance())//这里1代表第二行开始.relativeHeadRowIndex(1).doWrite(list);}/*** 不带表头提示** @param response* @param t* @param list* @param fileName* @throws IOException*/public static void download(HttpServletResponse response, Class t, List list, String fileName) throws IOException {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");EasyExcel.write(response.getOutputStream(), t).sheet(fileName).doWrite(list);}
}
6,表头类
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;public class ExportStudentExcelHandler implements SheetWriteHandler {@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Workbook workbook = writeWorkbookHolder.getWorkbook();Sheet sheet = workbook.getSheetAt(0);CellStyle cellStyle = workbook.createCellStyle();// 自动换行cellStyle.setWrapText(true);cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//第一行//设置标题Row row = sheet.createRow(0);row.setHeight((short) 900);Cell cell = row.createCell(0);cell.setCellStyle(cellStyle);cell.setCellValue("这是学生信息导出表格(注:xxxxxxxxx数据内容不可更改)");sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, 7));}
}
7,接口测试导出


相关文章:
Springboot使用EasyExcel导入导出Excel文件
1,准备Excel文件和数据库表结果 2,导入代码 1,引入依赖 <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifac…...
Pytorch L1,L2正则化
L1正则化和L2正则化是常用的正则化技术,用于在机器学习模型中控制过拟合。它们的主要区别在于正则化项的形式和对模型参数的影响。 L1正则化(Lasso正则化): 正则化项形式:L1正则化使用模型参数的绝对值之和作为正则化…...
【Elasticsearch 未授权访问漏洞复现】
文章目录 一、漏洞描述二、漏洞复现三、修复建议 一、漏洞描述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布&am…...
pytorch笔记:PackedSequence对象送入RNN
pytorch 笔记:PAD_PACKED_SEQUENCE 和PACK_PADDED_SEQUENCE-CSDN博客 当使用pack_padded_sequence得到一个PackedSequence对象并将其送入RNN(如LSTM或GRU)时,RNN内部会进行特定的操作来处理这种特殊的输入形式。 使用PackedSequ…...
C#WPF工具提示(ToolTip)实例
本文演示C#WPF工具提示(ToolTip)实例 ToolTip ToolTip是当鼠标移到某个控件上后可以弹出提示的控件 属性说明 1、HasDropShadow 决定工具提示是否具有扩散的黑色阴影,使其和背后的窗口区别开来 2、Placement 使用PlacementMode枚举值决定如何放置工具提示。默认值是M…...
智慧矿山系统中的猴车安全监测与识别
智慧矿山是近年来兴起的一种采用人工智能(AI)技术的矿山管理方式,它通过利用智能传感设备和先进算法来实现对矿山环境和设备进行监测和管理,从而提高矿山的安全性和效率。在智慧矿山的AI算法系列中,猴车不安全行为识别…...
网络协议--TCP连接的建立与终止
18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将详细讨论一个TCP连接是如何建立的以及通信结束后是如何终止的。 这种两端间连接的建立与无连接协议如UDP不同。我们在第11章看到一端使用UDP向另一端发…...
react条件渲染
目录 前言 1. 使用if语句 2. 使用三元表达式 3. 使用逻辑与操作符 列表渲染 最佳实践和注意事项 1. 使用合适的条件判断 2. 提取重复的逻辑 3. 使用适当的key属性 总结 前言 在React中,条件渲染指的是根据某个条件来决定是否渲染特定的组件或元素。这在构…...
Docker中Failed to initialize NVML: Unknown Error
参考资料 Docker 中无法使用 GPU 时该怎么办(无法初始化 NVML:未知错误) SOLVED Docker with GPU: “Failed to initialize NVML: Unknown Error” 解决方案需要的条件: 需要在服务器上docker的admin list之中. 不需要服务器整体的admin权限.…...
学习笔记|单样本秩和检验|假设检验摘要|Wilcoxon符号检验|规范表达|《小白爱上SPSS》课程:SPSS第十一讲 | 单样本秩和检验如何做?很轻松!
目录 学习目的软件版本原始文档单样本秩和检验一、实战案例二、统计策略三、SPSS操作1、正态性检验2.单样本秩和检验 四、结果解读第一,假设检验摘要第二,Wilcoxon符号检验结果摘要。第三,Wilcoxon符号秩检验图第四,数…...
ttkefu在线客服在客户联络领域的价值
随着互联网的快速发展,越来越多的企业开始注重在线客服的应用。ttkefu作为一款智能在线客服系统,在客户联络领域中展现出了巨大的价值。本文将详细介绍ttkefu在线客服在客户联络领域的应用优势、专家分析以及未来发展趋势。 一、ttkefu在线客服简介 tt…...
创新方案|2023如何用5种新形式重塑疫后实体门店体验
在电商盛行的当下,线上购物已成为新零售的重要组成部分,实体零售业正处于两难境地。一方面,实体零售是绝对有必要的:美国约 85% 的销售额来自实体商店。 另一方面,尽管增长放缓,但电商收入占销售总额的比例…...
Aqua Data Studio 2023.1
为什么选择 Aqua Data Studio? 随着数据在业务中的作用不断发展,组织需要一种有效的方法来简化复杂的技术任务并缩小 IT 和业务团队之间的差距。 使用多个数据库平台不再复杂。使用 Aqua Data Studio 简化您的所有数据管理流程和任务:这是一…...
【C++智能指针】
智能指针 为什么使用智能指针?概念分类auto_ptrunique_ptrshared_ptr循环引用weak_ptr 为什么使用智能指针? 考虑以下场景: void div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument("除0错误");return…...
gcc/g++使用格式+各种选项,预处理/编译(分析树,编译优化,生成目标代码)/汇编/链接过程(函数库,动态链接)
目录 gcc/g--编译器 介绍 使用格式 通用选项 编译选项 链接选项 程序编译过程 预处理(宏替换) 编译 (生成汇编) 分析树(parse tree) 编译优化 删除死代码 寄存器分配和调度 强度削弱 内联函数 生成目标代码 汇编 (生成二进制代码) 链接(生成可执行文件) 函…...
OSPF复习(2)
目录 一、LSA的头部 二、6种类型的LSA(课堂演示) 1、type1-LSA:----重要且复杂 2、type2-LSA: 3、type3-LSA: 4、type4-LSA: 5、type5-LSA: 6、type7-LSA: 三、OSPF的网络类…...
FPGA时序分析与约束(9)——主时钟约束
一、时序约束 时序引擎能够正确分析4种时序路径的前提是,用户已经进行了正确的时序约束。时序约束本质上就是告知时序引擎一些进行时序分析所必要的信息,这些信息只能由用户主动告知,时序引擎对有些信息可以自动推断,但是推断得到…...
sqlite3 关系型数据库语言 SQL 语言
SQL(Structured Query Language)语言是一种结构化查询语言,是一个通用的,功能强大的关系型数据库操作语言. 包含 6 个部分: 1.数据查询语言(DQL:Data Query Language) 从数据库的二维表格中查询数据,保留字 SELECT 是 DQL 中用的最多的语句 2.数据操作语言(DML) 最主要的关…...
spring boot中的多环境配置
1.切换环境 spring:profiles:include: devactive: dev的作用是为了启动某个环境,两个作用基本一致, 环境定义如下: spring:profiles: dev或者是查找application-dev.yml这个文件的所有配置 2.加载文件 spring:config:import:- optional:f…...
python3 阿里云api进行巡检发送邮件
python3 脚本爬取阿里云进行巡检 不确定pip能不能安装上,使用时候可以百度一下,脚本是可以使用的,没有问题的 太长时间了,pip安装依赖忘记那些了,使用科大星火询问了下,给了下面的,看看能不能使…...
重型设备预测性维护:时序数据的摄取与治理架构
重型设备预测性维护:时序数据的摄取与治理架构在工业 4.0 的演进路线中,制造企业对生产设备的管理正在经历深刻的范式转移。传统的“定期维护(Preventive Maintenance)”往往会造成零部件的过度替换与运维人力的浪费;而…...
MedGemma-X参数详解:top_k=50在避免幻觉与保持临床相关性间的平衡
MedGemma-X参数详解:top_k50在避免幻觉与保持临床相关性间的平衡 1. 引言:智能影像诊断的新挑战 在医疗AI领域,我们面临着一个关键挑战:如何在保持模型创造力的同时,确保输出的临床准确性。MedGemma-X作为新一代多模…...
OpenClaw版本升级:Qwen2.5-VL-7B兼容性测试与迁移指南
OpenClaw版本升级:Qwen2.5-VL-7B兼容性测试与迁移指南 1. 升级前的准备工作 上周我在本地开发环境遇到了一个棘手问题——现有的OpenClaw版本无法正确调用新部署的Qwen2.5-VL-7B多模态模型。这促使我开始了这次版本升级之旅,过程中积累了不少实战经验想…...
PLC立体车库智能仿真系统:博途V15 3×2车库模型,西门子PLC控制,触摸屏操作,自动出入...
PLC立体车库智能仿真 博途V15 32立体车库 西门子1200PLC 触摸屏仿真 不需要实物 自带人机界面 小车上下行有电梯效果 每一个程序段都有注释 FC块标准化编写 自带变频器输出也可以仿真 现在拥有自动出入仓库的功能 IO表已列出最近在搞的32立体车库仿真项目挺有意思,用…...
从一次Sigar崩溃看Java生态的‘版本地狱’:如何优雅管理JDK与本地库的兼容性矩阵(附jdk1.8.0_241下载与降级实操)
Java生态中的依赖兼容性管理:从Sigar崩溃案例到系统化解决方案 当你在Windows 10环境下运行一个看似简单的Java应用,突然遭遇EXCEPTION_ACCESS_VIOLATION错误,而问题根源指向一个名为sigar-amd64-winnt.dll的本地库文件时,这远不止…...
如何使用node-fetch实现GraphQL批量查询:5个减少请求数量的实用技巧
如何使用node-fetch实现GraphQL批量查询:5个减少请求数量的实用技巧 【免费下载链接】node-fetch A light-weight module that brings the Fetch API to Node.js 项目地址: https://gitcode.com/gh_mirrors/no/node-fetch 在现代API开发中,频繁的…...
禾赛科技Linux BSP工程师面试技术要点解析
1. 禾赛科技高级Linux BSP工程师面试全解析最近参加了禾赛科技高级Linux BSP软件工程师的社招面试,整体感觉技术考察非常全面深入。作为一家专注激光雷达研发的科技公司,他们对底层系统开发能力的要求极高。下面我就把两轮技术面试中遇到的真实问题及技术…...
uv下载软件包
需要在项目根目录执行uv add 包名 否则找不到项目的.venv,会下载到终端的conda环境uv add openai...
产教融合共建失智老年人照护实训室实践路径
本文围绕产教融合模式,结合失智老年人照护岗位实际需求,从合作机制、空间布局、设备配置、教学实施、运营保障五个核心维度,给出可落地的失智老年人照护实训室共建实践路径,兼顾实用性与可操作性,助力院校与企业高效共…...
毕设-情绪雷达
情绪雷达 注: 项目基于芋道的 mini 版,进行二次开发,部署文档就不过多赘述了,可以看人家的官方文档。 概述: 情绪雷达,项目的核心开发路线是:针对用户发来的聊天界面截图,利用 a…...
