EasyPoi导出 导入(带校验)简单示例 EasyExcel
官方文档 : http://doc.wupaas.com/docs/easypoi
pom的引入:
<!-- easyPoi--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.0.0</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.4.1.Final</version></dependency>
<!-- hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.7.7</version></dependency>
1.建立一个对象体
@Data
public class EasyPoiEntity {@Excel(name = "姓名")private String name;@Excel(name = "年龄")private int age;@Excel(name = "地址")private String addr;}
2.导出代码
@GetMapping("/exportExcel")public void test(HttpServletRequest request, HttpServletResponse response)throws IOException {//模拟数据 实际基本查数据EasyPoiEntity easyPoiEntity = new EasyPoiEntity();easyPoiEntity.setName("张三");easyPoiEntity.setAddr("中国");easyPoiEntity.setAge(18);List<EasyPoiEntity> list = new ArrayList<>();list.add(easyPoiEntity);//2.封装成表格//参数1:表格标题,参数2:sheet名称
// ExportParams exportParams = new ExportParams("学生信息", "1班学生信息");ExportParams exportParams = new ExportParams();exportParams.setSheetName("学生信息");exportParams.setStyle(EasyExcelStyleType.ONE.getCla());//参数1:表格参数 参数2:实体类 参数3:数据Workbook sheets = ExcelExportUtil.exportExcel(exportParams, EasyPoiEntity.class, list);//3.返回表格//设置表格文件名字// 生成时间戳String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");String fileName = "一班学生数据-"+timestamp;fileName = URLEncoder.encode(fileName,"UTF8");//设置返回数据类型response.setContentType("application/vnd.ms-excel;charset=utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");//将表格输出sheets.write(response.getOutputStream());}
导出Excel
导入例子
1.对象加上校验注解 实现 IExcelDataModel, IExcelModel
@Data
public class EasyPoiEntity implements IExcelDataModel, IExcelModel {@Excel(name = "姓名")@Pattern(regexp = "[\u4E00-\u9FA5]*", message = "不是中文")private String name;@Max(value = 15,message = "max 最大值不能超过15")@Excel(name = "年龄")private int age;@NotNull(message = "地址不能为空")@Excel(name = "地址")private String addr;/*** 行号*/private int rowNum;/*** 错误消息*/private String errorMsg;}
导入代码 params.setVerifyHandler(excelVerifyInfo);看后面
@PostMapping("/importExcel")@ResponseBodypublic Object importUser(@RequestParam("uploadFile") MultipartFile multipartFile,HttpServletResponse resp) {ImportParams params = new ImportParams();/*** 这里需要注意表头的行数设置一定要正确!否则集合数据将无法读取,* 可以通过WPS或者office查看实际表头所占用的行数,* 一定要区分表头与标题的区别,表头是列名称,标题是表头上面的文字,* 本文示例文件中没有标题,所以setTitleRows为0*/// 设置表头行数params.setHeadRows(1);// 标题行设置为0行,默认是0,可以不设置params.setTitleRows(0);
// 代表导入这里是需要验证的(根据字段上的注解校验)params.setNeedVerify(true);//设及一个自定义校验 (自定义校验名字不可重复)params.setVerifyHandler(excelVerifyInfo);try {ExcelImportResult<EasyPoiEntity> importResult = ExcelImportUtil.importExcelMore(multipartFile.getInputStream(), EasyPoiEntity.class, params);boolean verfiyFail = importResult.isVerfiyFail();System.out.println(verfiyFail);System.out.println(importResult.getFailList().toString());System.out.println(importResult.getList().toString());//验证是否有失败的数据if (importResult.isVerfiyFail()) {ServletOutputStream fos = resp.getOutputStream();//mime类型resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 生成时间戳String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");resp.setHeader("Content-disposition", "attachment;filename=" + timestamp + "-error.xlsx");importResult.getFailWorkbook().write(fos);fos.close();}return importResult.getList();} catch (Exception e) {e.printStackTrace();}return null;}
导入Excel例子
返回的异常Excel
对于想自定义异常的 自己写一个实现类实现 IExcelVerifyHandler<>即可
代码如下:
@Component
public class ExcelVerifyInfo implements IExcelVerifyHandler<EasyPoiEntity> {private final ThreadLocal<List<EasyPoiEntity>> threadLocal = new ThreadLocal<>();@Overridepublic ExcelVerifyHandlerResult verifyHandler(EasyPoiEntity easyPoiEntity) {StringJoiner joiner = new StringJoiner(",");List<EasyPoiEntity> threadLocalVal = threadLocal.get();if (threadLocalVal == null) {threadLocalVal = new ArrayList<>();}/*** 所有的自定义校验 可以再这里写 比如查数据 比较之类*/
// if (easyPoiEntity.getName().equals("张三")){
// joiner.add("eeeeee");
// }threadLocalVal.forEach(e -> {if (e.getName().equals(easyPoiEntity.getName())) {int lineNumber = e.getRowNum() + 1;joiner.add("名字与" + lineNumber + "行重复");}});// 添加本行数据对象到ThreadLocal中threadLocalVal.add(easyPoiEntity);threadLocal.set(threadLocalVal);if (!Objects.equals(joiner.length(),0)) {return new ExcelVerifyHandlerResult(false, joiner.toString());}return new ExcelVerifyHandlerResult(true);}
}
关于空行问题
Excel经常会有空行但是有格式的行 我们读取的时候 会读到这些行 然后对象就都是空的 这可能会影响到数据的处理 我是在校验类里面做了判断 如下:
@Component
public class ExcelVerifyInfo implements IExcelVerifyHandler<EasyPoiEntity> {private final ThreadLocal<List<EasyPoiEntity>> threadLocal = new ThreadLocal<>();@Overridepublic ExcelVerifyHandlerResult verifyHandler(EasyPoiEntity easyPoiEntity) {if ( StringUtils.isAllBlank(easyPoiEntity.getName(), easyPoiEntity.getAddr()) && Objects.equals(easyPoiEntity.getAge(),0)) {// 空行数据,返回false表示无效,EasyPoi会过滤掉该行数据return new ExcelVerifyHandlerResult(false);} else {// 非空行数据,返回true表示有效StringJoiner joiner = new StringJoiner(",");List<EasyPoiEntity> threadLocalVal = threadLocal.get();if (threadLocalVal == null) {threadLocalVal = new ArrayList<>();}/*** 所有的自定义校验 可以再这里写 比如查数据 比较之类*/
// if (easyPoiEntity.getName().equals("张三")){
// joiner.add("eeeeee");
// }threadLocalVal.forEach(e -> {if (e.getName().equals(easyPoiEntity.getName())) {int lineNumber = e.getRowNum() + 1;joiner.add("名字与" + lineNumber + "行重复");}});// 添加本行数据对象到ThreadLocal中threadLocalVal.add(easyPoiEntity);threadLocal.set(threadLocalVal);if (!Objects.equals(joiner.length(),0)) {return new ExcelVerifyHandlerResult(false, joiner.toString());}return new ExcelVerifyHandlerResult(true);}}
}
假如你对象属性多 不用全都判断是都空 只要找几个必填属性 然后判断为空就认为是空行就行了
数据翻译
1.简单的方式 直接用replace 会在导出导入进行翻译 比如你导出 一般状态是数字 会翻译成中文 导入则相反
@Excel(name = "状态",replace = {"进行中_1", "完成_2","结束_3"})private String status;
Excel导入校验并返回异常Excel
@PostMapping("/importExcel")@ResponseBodypublic void importUser(@RequestParam("uploadFile") MultipartFile multipartFile, HttpServletResponse response) {try {//自己找一个读的utlisList<User> read = EasyExcelUtil.read(multipartFile.getInputStream(), User.class);//拿到数据 校验数据 有问题就set导msg 然后把流写出List<User> errList = new ArrayList<>();for (User user : read) {if (user.getName().equals("张三")){user.setMsg("这是一个错误数据");errList.add(user);}}if (CollectionUtil.isNotEmpty(errList)){// 生成时间戳String timestamp = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");EasyExcelUtil.write(response,"err_"+timestamp,errList,"test");}System.out.println(read);} catch (IOException e) {throw new RuntimeException(e);}}
对象
@Data
public class User {private String name;private String phone;private String addr;@ContentFontStyle(color = Font.COLOR_RED)@ColumnWidth(value = 25)private String msg;}
相关文章:

EasyPoi导出 导入(带校验)简单示例 EasyExcel
官方文档 : http://doc.wupaas.com/docs/easypoi pom的引入: <!-- easyPoi--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.0.0</version></dep…...

八大排序
目录 选择排序-直接插入排序 插入排序-希尔排序 选择排序-简单选择排序 选择排序-堆排序 交换排序-冒泡排序 交换排序-快速排序 归并排序 基数排序 选择排序-直接插入排序 基本思想: 如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素…...

网络安全【黑客技术】自学
1.网络安全是什么 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 掌握技术的听说也需要心怀正义,不要利用技术行不轨之事&…...

【网络通信】socket编程——TCP套接字
TCP依旧使用代码来熟悉对应的套接字,很多接口都是在udp中使用过的 所以就不会单独把他们拿出来作为标题了,只会把第一次出现的接口作为标题 文章目录 服务端 tcp_servertcpserver.hpp(封装)初始化 initServer1. 创建socket2. 绑定 bindhtons —— 主机序…...
ROS2系统学习番外篇2---用VSCode开发ROS2程序
在ROS2系统学习3—第一个“Hello World”程序—即工作空间创建与包创建中已经介绍了如何创建ROS的工作空间以及包。在开发大型工程时,往往需要在IDE下面进行开发,因此本篇介绍使用VSCode来搭建ROS2开发环境的方法。 首先用VSCode打开ROS2的工作空间。 使用快捷键编译ROS2 …...

06 - Stream如何提高遍历集合效率?
前面我们讲过 List 集合类,那我想你一定也知道集合的顶端接口 Collection。 在 Java8 中,Collection 新增了两个流方法,分别是 Stream() 和 parallelStream()。 1、什么是 Stream? 现在很多大数据量系统中都存在分表分库的情况…...

【Spring】使用注解的方式获取Bean对象(对象装配)
目录 一、了解对象装配 1、属性注入 1.1、属性注入的优缺点分析 2、setter注入 2.1、setter注入的优缺点分析 3、构造方法注入 3.1、构造方法注入的优缺点 二、Resource注解 三、综合练习 上一个博客中,我们了解了使用注解快速的将对象存储到Spring中&#x…...

[webpack] 基本配置 (一)
文章目录 1.基本介绍2.功能介绍3.简单使用3.1 文件目录和内容3.2 下载依赖3.3 启动webpack 4.基本配置4.1 五大核心概念4.2 基本使用 1.基本介绍 Webpack 是一个静态资源打包工具。它会以一个或多个文件作为打包的入口, 将我们整个项目所有文件编译组合成一个或多个文件输出出去…...

模板学堂|SQL数据集动态参数使用场景及功能详解
DataEase开源数据可视化分析平台于2022年6月正式发布模板市场(https://dataease.io/templates/)。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板,方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&a…...

Wlan——射频和天线基础知识
目录 射频的介绍 射频和Wifi 射频的相关基础概念 射频的传输 信号功率的单位 射频信号传输行为 天线的介绍 天线的分类 天线的基本原理 天线的参数 射频的介绍 射频和Wifi 什么是射频 从射频发射器产生一个变化的电流(交流电),通过…...
前端实习周记第三周周记
第二周总结 第二周主要是做了一些PC端细节内容。大的地方改的不多,但是小的细节蛮多。 值得一提的是,第二周做的微信小程序,改了很多逻辑。改逻辑需要与后端进行联调,收获很大,思路也愈发清楚。 记录做了什么是好习…...
Android 13 Launcher界面——移除Launcher的删除和卸载功能
目录 一.背景 二.将卸载功能进行屏蔽 三.将移除功能屏蔽 四.将Remove按钮与Uninstall按钮屏蔽...

深度学习:使用卷积神经网络CNN实现MNIST手写数字识别
引言 本项目基于pytorch构建了一个深度学习神经网络,网络包含卷积层、池化层、全连接层,通过此网络实现对MINST数据集手写数字的识别,通过本项目代码,从原理上理解手写数字识别的全过程,包括反向传播,梯度…...

docker search 镜像报错: connect: no route to host (桥接模式配置静态IP)
如下 原因 可能有多种: ① 没有开放防火墙端口 ② ip地址配置有误 解决 我是因为虚拟机采用了桥接模式,配置静态ip地址有问题。 先确认虚拟机采用的是 桥接模式,然后启动虚拟机。 1、打开命令行,输入下面指令,打开…...
【VUE】[Violation] Added non-passive event listener to a scroll-blocking...
环境 chrome: 115.0.5790.170vue: ^3.3.4element-plus: ^2.3.4vite: ^4.4.7 问题 [Violation] Added non-passive event listener to a scroll-blocking <某些> 事件. Consider marking event handler as passive to make the page more responsive. See <URL> …...
runit-docker中管理多个服务
runit-docker中管理多个服务 介绍Runit, systemctl和supervisor是三种不同的服务管理工具区别runit优点程序构成快速开始runit实现服务退出执行指定操作runit监管服务打印日志到syslogrunit监管服务后台运行runit监管服务一些错误总结 介绍 runit 是一个轻量级的、稳定的、跨平…...

Intune 应用程序管理
由于云服务提供了增强的安全性、稳定性和灵活性,越来越多的组织正在采用基于云的解决方案来满足他们的需求。这正是提出Microsoft Endpoint Manager等解决方案的原因,它结合了SCCM和Microsoft Intune,以满足本地和基于云的端点管理。 与 Int…...

Oracle DB 安全性 : TDE HSM TCPS Wallet Imperva
• 配置口令文件以使用区分大小写的口令 • 对表空间进行加密 • 配置对网络服务的细粒度访问 TCPS 安全口令支持 Oracle Database 11g中的口令: • 区分大小写 • 包含更多的字符 • 使用更安全的散列算法 • 在散列算法中使用salt 用户名仍是Oracle 标识…...

leetcode27—移除元素
思路: 参考26题目双指针的思想,只不过这道题不是快慢指针。 看到示例里面数组是无序的,也就是说后面的元素也是可能跟给定 val值相等的,那么怎么处理呢。就想到了从前往后遍历,如果left对应的元素 val时,…...
flask---》更多查询方式/连表查询/原生sql(django-orm如何执行原生sql)/flask-sqlalchemy
更多查询方式 #1 查询: filer:写条件 filter_by:等于的值 # 查询所有 是list对象 res session.query(User).all() # 是个普通列表 print(type(res)) print(len(res))# 2 只查询某几个字段 # select name as xx,email from user; res session.…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...