spring boot-操作excel(EasyExcel 快速开始)/ spring boot接受文件参数 File

文章目录

  • 一、spring boot 操作excel
    • 1. 技术选型
      • 1.1 EasyExcel
      • 1.2 POI
  • 二、EasyExcel使用
    • 0. 工作中使用总结
    • 1. maven 引入
    • 2. demo1:excel写入文件
    • 3. demo2:SpringBoot项目中集成EasyExcel实现Excel文件的下载
      • response的三个属性:编码、类型、头文件
    • 4. demo3:SpringBoot项目中集成EasyExcel实现Excel文件导入(同步处理数据)
      • 4.1 AnalysisEventListener
  • 三、工作常用参考
    • 1. easyexcel 上传返回结果给前端(返回成功/失败数量及原因)
    • 2. easyexcel 导入数据校验
  • 四、参考

一、spring boot 操作excel

1. 技术选型

java本身并不支持读取excel,所有读取excel需要借助一些框架。目前有几种方式:

  1. Apache POI
  2. easyexcel

POI提供的对Excel操作不仅消耗内存而且解压时完全在内存中完成,内存消耗非常大。

  • easyExcel的确比poi方便,但是它的读需要编写监听器
  • 建议大数据用easyExcel,因为大数据时poi对于内存消耗非常大
  • 由于apache poi和jxl,excelPOI都有一个严重的问题,就是非常消耗内存,特别处理数据量多时,速度慢并且时有异常发生,所以改用由阿里研发的easyExcel更可靠一些,它的官方建议对于1000行以内的采用原来poi的写法一次读写,但于1000行以上的数据,有用了一行行进行解析的方案,这样避免了内存的溢出。
  • EasyExcel扩展功能很多,且Api式调用真的轻松很多

1.1 EasyExcel

官方网站: https://yuque.com/easyexcel
https://github.com/alibaba/easyexcel

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

EasyExcel能减少内存占用的原因是它没有将文件一次性加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasylExcel的特点:
1、poi和jxl非常的消耗内存,并发上来后会OOM或是JVM频繁的full gc。

2、EasylExcel对poi进行了封装,使用简单,节省内存。

3、EasyExcel没有把文件数据一次性全部加载到内存中,而是从磁盘一行一行读取数据,逐个解析,并将解析结果以观察者的模式通知处理(AnalysisEventListener)。

1.2 POI

POI是Apache提供的开源代码库,这个代码库用来提供Java客户端对Microsoft Office格式文件的读写操作。

POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。

POI有五种结构

HSSF——提供读写Microsoft Excel(2003)格式档案功能

XSSF——提供读写Microsoft Excel OOXML(2007-今)格式档案的功能

HWPF——提供读写Microsoft Word格式档案的功能

HSLF——提供读写Microsoft PPT格式档案功能

HDGF——提供读写Microsoft Visio格式档案的功能

二、EasyExcel使用

0. 工作中使用总结

  • 目前读取excel文件不再需要指定ExcelTypeEnum,即excel的版本,会自动处理
  • 之前创建ExcelReader都是自己new,现在是通过EasyExcelFactory创建,更加简单和具备通用性。
  • 之前每解析一行的回调的invoke()方法,通用对象Object是list集合,目前是HashMap集合。

1. maven 引入

repo仓库搜索 关键字 EasyExcel ,使用最新版本。

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.3</version>
</dependency>

2. demo1:excel写入文件

@HeadRowHeight(20)	// 表头行高
@ColumnWidth(15)		// 表头行宽
@Data
public class DemoData {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ExcelProperty("数字标题")private Double doubleData;/*** 忽略这个字段*/@ExcelIgnoreprivate String ignore;
}
public class ExcelServiceTest {/*** 最简单的写* <p>1. 创建excel对应的实体对象 参照{@link DemoData}* <p>2. 直接写即可*/@Testpublic void simpleWrite1() {// 写法1String fileName = "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());}@Testpublic void simpleWrite2(){// 写法2String fileName = "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写ExcelWriter excelWriter = null;try {excelWriter = EasyExcel.write(fileName, DemoData.class).build();WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(data(), writeSheet);} finally {// 千万别忘记finish 会帮忙关闭流if (excelWriter != null) {excelWriter.finish();}}}private List<DemoData> data() {List<DemoData> list = new ArrayList<DemoData>();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}}

3. demo2:SpringBoot项目中集成EasyExcel实现Excel文件的下载

SpringBoot项目中集成EasyExcel实现Excel文件的下载
参考URL: https://blog.csdn.net/riemann_/article/details/103648431

如下:demo测试通过, 利用 response.getOutputStream() 、HttpServletResponse response 来设置响应头等信息。

    @RequestMapping(value = "/xxx/getExcel", method = RequestMethod.GET)public void getExcel(HttpServletResponse response) throws IOException {//配置文件名SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");String datetime = sdf.format(new Date());String fileName = URLEncoder.encode("下载excel", "UTF-8") + datetime;//响应内容格式response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");List<UserVO> list = excelService.getUserVOData();// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(response.getOutputStream(), UserCheckData.class).sheet("下载excel").doWrite(list);}

UserCheckData.class 是自定义的excel对应的java类;其中的
@ExcelProperty注解中的value就是表头的信息,index是在第几列,没有加注解的不会导出。

@HeadRowHeight(20)	// 表头行高
@ColumnWidth(15)		// 表头行宽
@Data
public class SiUserCheckData{/*** 用户名*/@ExcelProperty(value = "用户名", index = 0)private String username;/*** 手机号*/@ExcelProperty(value = "手机号", index = 0)private String mobile;
}

如上demo,经过测试,注意点如下:

  • response 来设置响应头等信息,记得要放在EasyExcel.write 写流之前。
  • controller方法写成void即可。

response的三个属性:编码、类型、头文件

流写出时,关键是配置response的三个属性:编码、类型、头文件

1、ContentType:传输文件类型

application/octet-stream------------------自动匹配文件类型

application/force-download--------------强制下载

text/pain---------------------------------------文本文件

application/vnd.ms-excel-----------------excel文件

2、CharacterEncoding:编码采用通用的UTF-8

3、Header:setHeader(name,value),有两个参数


示例:

response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("UTF-8");response.setHeader("Content-Disposition","attachment;filename=problems"+AMDateUtil.date2String(new Date(),"yyyyMMdd")+".xlsx");

4. demo3:SpringBoot项目中集成EasyExcel实现Excel文件导入(同步处理数据)

SpringBoot项目中集成EasyExcel实现Excel文件上传至MySQL
参考URL: https://blog.csdn.net/riemann_/article/details/103639254
使用easyExcel导入大批量数据
参考URL: https://blog.csdn.net/qq_36109477/article/details/104909535
[推荐]springboot整合阿里easyexcel2.x实现海量数据excel导入导出demo
参考URL: https://www.cnblogs.com/zhengwj-joker/p/12808979.html

整体思路:

  1. 引入easyExcel maven。
  2. 定义导入导出exel字段对应的实体类。(使用easyExcel相关注解)
  3. 自定义 上传Excel的监听类 实现 AnalysisEventListener<你自己定义的excel模型类>。
    核心就是这个监听器类,实现相关方法。
    经过测试: 监听器这个类不能够被Spring管理,每次使用单独的new出来。
// 该类无法交给spring管理
public class ConfigFilterListener  extends AnalysisEventListener<ConfigFilterImport> {private static final Logger logger = LoggerFactory.getLogger(ConfigFilterListener.class);private static final int BATCH_COUNT = 10000;List<ConfigFilterImport> list = new ArrayList<>();private ConfigFilterDao configFilterDao;/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来*/public ConfigFilterListener(ConfigFilterDao configFilterDao){this.configFilterDao = configFilterDao;}/*** 这个每一条数据解析都会来调用** @param configFilter*            one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param analysisContext*/@Overridepublic void invoke(ConfigFilterImport configFilter, AnalysisContext analysisContext) {list.add(configFilter);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (list.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listlist.clear();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();logger.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {logger.info("{}条数据,开始存储数据库!", list.size());configFilterDao.save(list);logger.info("存储数据库成功!");}
}

参考原博主URL(https://www.cnblogs.com/zhengwj-joker/p/12808979.html),即可。

4.1 AnalysisEventListener

上文中,自定义 上传Excel的监听类 实现 AnalysisEventListener<你自己定义的excel模型类>,

其中, invoke() 和 doAfterAllAnalysed() 是必须实现的方法。

在 invoke() 中,我们将数据封装到 list 中,再在控制器中,通过 getter() 方法获取数据,这样我们就可以获取到 easyexcel 帮我们解析好的数据,再将数据进行类型转化,这样,我们就可以对数据进行写入操作。

注意:

  • 每解析一行会回调invoke()方法。
  • 整个excel解析结束会执行doAfterAllAnalysed()方法

经过测试,自定义监听类 实现 AnalysisEventListener不能被spring管理。即使你加了 @Component注解,发现里面 @Autowired 注入不了spring 的bean!

那么,我们要使用spring bean应该怎么做呢?
思路:监听器对象 可以在创建的时候把dao当做参数传进去。

我们自定义监听器类的构造体传入,需要用到bean,如一些Dao

    /**** 不要使用自动装配* 将dao当参数传进来*/public DemoDataListener(TeacherDao teacherDao) {this.teacherDao = teacherDao;}
/*** 添加数据库用到的dao*/@Autowiredprivate TeacherDao teacherDao;/*** 最简单的读*/@Testpublic void simpleRead() {String fileName =  "/Users/lubingyang/Desktop/hhhh.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭/*** 参数1 要读取的文件* 参数2 要读取的数据对应的实体类类对象* 参数3 监听器对象 可以在创建的时候把dao当做参数传进去*/EasyExcel.read(fileName, Teacher.class, new DemoDataListener(teacherDao)).sheet().doRead();}

三、工作常用参考

1. easyexcel 上传返回结果给前端(返回成功/失败数量及原因)

基于EasyExcel的读取exl并返回成功/失败数量及原因,并将导入失败exl的导出到系统路径中
参考URL: https://blog.csdn.net/qq_37361535/article/details/105687708
https://blog.csdn.net/weixin_42059737/article/details/103891013
参考URL: https://blog.csdn.net/weixin_42059737/article/details/103891013

整体思路:
自定义类bean,spring管理,专门处理统计哪些入库成功,哪些失败,在自定义excel监听器构造函数中传入。

controller层如何返回给界面,哪些成功或失败呢?

其中controller层需要返回给前端的数据,可以利用该思想。在监听器构造函数添加需要返回的实例。监听器里面做相关赋值,controller层直接返回即可。

controller层,demo如下:

	@ResponseBody@RequestMapping(value = "orderImport", method = RequestMethod.POST, produces = Constant.CONTENT_TYPE_UTF8)public RestResponse orderImport(HttpServletRequest request,  @RequestParam(value = "file") MultipartFile file) throws Exception {UserVO userVo = this.getCurrentUser(request);// 初始化ajax返回对象 默认是操作成功RestResponse build = RestResponse.build();EasyExcel.read(file.getInputStream(), new NoModleDataListener(orderService, userVo, build)).sheet().doRead();// 直接返回  如果错误这个对象的值已被改变 如果没有错误值没有被改变 返回的是默认成功的对象return build;// return orderService.importOrder(userVo, file);}

建议直接参考原文。

2. easyexcel 导入数据校验

easyExcel+validation+正则实现excel导入校验
参考URL: https://www.yuque.com/oushidazhutou/lwb5fl/mwymlq

四、参考

EasyExcel2.0 实现模板下载、导入和导出功能
参考URL: https://liuyanzhao.com/10060.html
EasyExcel操作API与示例
参考URL: https://www.it610.com/article/1296387796709220352.htm
EasyExcel读取文件-同步处理数据
参考URL: https://www.cnblogs.com/ngrzr/p/11982697.html
SpringBoot图文教程14—阿里开源EasyExcel「为百万数据读写设计」
参考URL: https://my.oschina.net/u/3555122/blog/4355952
惊了!如何通过阿里 EasyExcel 7 行代码, 优雅地实现 Excel 文件导出功能?
参考URL: https://blog.csdn.net/wutian842929/article/details/106994662/
easyExcel+validation+正则实现excel导入校验
参考URL: https://www.yuque.com/oushidazhutou/lwb5fl/mwymlq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gcc -static参数

在使用 GCC&#xff08;GNU Compiler Collection&#xff09;编译器编译C语言或C语言程序时&#xff0c;-static 选项告诉编译器生成一个完全静态链接的可执行文件。这就意味着程序需要的所有库在编译时都会被包含在执行文件中&#xff0c;它不会在运行时链接动态库&#xff08…

openssl3.2 - exp - 选择最好的内建椭圆曲线

文章目录 openssl3.2 - exp - 选择最好的内建椭圆曲线概述笔记将 openssl ecparam -list_curves 实现迁移到自己的demo工程备注END openssl3.2 - exp - 选择最好的内建椭圆曲线 概述 在openssl中使用椭圆曲线, 只允许选择椭圆曲线的名字, 无法给定椭圆曲线的位数. 估计每种椭…

储能系统--户用储能市场现状(三)

1、户用储能市场现状 2022年&#xff0c;俄乌冲突造成能源价格飙升&#xff0c;欧洲居民电价飞涨&#xff0c;成为点燃户储需求的引线。以德国为例&#xff0c;2022年的居民电价达到40欧分/kWh以上&#xff0c;相比2021年初翻了三倍。因此2022年被称为户储爆发元年&#xff0c…

深度学习armv8/armv9 cache的原理

文章目录 前言1、为什么要用cache?2、背景:架构的变化?2、cache的层级关系 ––big.LITTLE架构&#xff08;A53为例)3、cache的层级关系 –-- DynamIQ架构&#xff08;A76为例)4、DSU / L3 cache5、L1/L2/L3 cache都是多大呢6、cache相关的术语介绍7、cache的分配策略(alocat…

Llama-3即将发布:Meta公布其庞大的AI算力集群

Meta&#xff0c;这家全球科技巨头&#xff0c;再次以其在人工智能&#xff08;AI&#xff09;领域的雄心壮志震惊了世界。3月13日&#xff0c;公司在其官方网站上宣布了两个全新的24K H100 GPU集群&#xff0c;这些集群专为训练其大型模型Llama-3而设计&#xff0c;总计拥有高…

C++函数 加括号与不加括号

很多时候&#xff0c;我们会看到一些在创建对象时有的加括号有的不加括号 那么&#xff0c;这是什么情况呢&#xff1f; 总结&#xff1a;函数需要加上括号&#xff0c;加上括号会对函数初始化&#xff0c;不加括号可能导致未知错误 我们来验证一下。 1.基本数据类型不带括…

利用Python进行网络爬虫:Beautiful Soup和Requests的应用【第131篇—Beautiful Soup】

利用Python进行网络爬虫&#xff1a;Beautiful Soup和Requests的应用 在网络数据变得日益丰富和重要的今天&#xff0c;网络爬虫成为了获取和分析数据的重要工具之一。Python作为一种强大而灵活的编程语言&#xff0c;在网络爬虫领域也拥有广泛的应用。本文将介绍如何使用Pyth…

C++进阶学习

模板编程 模板函数和模板类的基本概念和用法 模板编程是C中一种强大的特性&#xff0c;它允许程序员编写与类型无关的代码。这意味着你可以编写一个函数或类&#xff0c;让它能够处理任何数据类型。这不仅可以提高代码的重用性&#xff0c;还可以提高编程效率和程序的可维护性…

Verilog——Verilog的历史

第1节 Verilog的历史 在传统硬件电路的设计方法中&#xff0c;当设计工程师需要设计一个新的硬件、数字电路或数字逻辑系统 时&#xff0c;需要为此设计并画出一张线路图&#xff0c;随后在CAE&#xff08;计算机辅助工程分析&#xff09;工作站上进行设计。所 设计的线路图由线…

.Net Core 与数据库

查询 Linq var indexList new long[] { 1, 2, 3}; List<long> list new List<long>(); if (String.IsNullOrWhiteSpace(request.Key) false) {var ret from aa in _db.TblAAjoin bb in _db.TblBBon aa.PId equals bb.Idjoin cc in _db.TblCCon aa.CId equals…

13、Linux-Shell02:参数传递和运算符

目录 一、参数传递 二、运算符 1、算术运算符&#xff08;、-、*、/、%、、、&#xff01;&#xff09; 2、关系运算符 3、逻辑运算符 4、字符串运算符 5、文件运算符 一、参数传递 执行脚本时可以为脚本文件传递参数&#xff0c;在脚本中可以处理这些参数。 第n个参数…

[LeetCode][LCR172]统计目标成绩的出现次数——二分找边界

题目 LCR 172. 统计目标成绩的出现次数 某班级考试成绩按非严格递增顺序记录于整数数组 scores&#xff0c;请返回目标成绩 target 的出现次数。 示例 1&#xff1a; 输入&#xff1a;scores [2, 2, 3, 4, 4, 4, 5, 6, 6, 8], target 4 输出&#xff1a;3 示例 2&#xff1a…

Elasticseach基础认识

ES的起源&#xff1f; Elasticsearch 是由 Elastic 公司创建 简称&#xff08;ES&#xff09; Elasticsearch 是一个分布式、免费和开放的搜索和分析引擎&#xff0c;适用于所有类型的数据&#xff0c;包括文本、数字、地理空间、结构化和非结构化数据。 Elasticsearch 基于 …

Oracle 主从切换脚本

一、 切换前预检查 1. dg_precheck_main_v1.4.sh #!/bin/bash#********************************************************************************** # Author: Hehuyi_In # Date: 2022年06月16日 # FileName: dg_precheck_main_v1.4.sh # # For sys user, execute the sc…

LLM之RAG实战(二十九)| 探索RAG PDF解析

对于RAG来说&#xff0c;从文档中提取信息是一种不可避免的场景&#xff0c;确保从源文件中提取出有效的内容对于提高最终输出的质量至关重要。 文件解析过程在RAG中的位置如图1所示&#xff1a; 在实际工作中&#xff0c;非结构化数据比结构化数据丰富得多。如果这些海量数据无…

【向课题组提交实习申请模板】

实习申请 尊敬的老师&#xff1a; 本人系xx学院xx专业的学生xx。现已通过xx公司202x届“xx星”实习计划的面试&#xff0c;并成功获得xx工程师实习岗位&#xff1b;工作内容为xx&#xff1b;实习地点位于xx&#xff1b;实习时长为暑期x个月。我希望能够通过此次实习&#xff0…

Redis事务及原理

Redis 事务以及原理 Redis 中的事务是一组命令的集合&#xff0c;是 Redis 的最小执行单位。它可以保证一次执行多个命令&#xff0c;每个事务是一个单独的隔离操作&#xff0c;事务中的所有命令都会序列化、按顺序地执行。服务端在执行事务的过程中&#xff0c;不会被其他客户…

HTML、CSS、JavaScript

W3C标准&#xff1a;网页主要由三部分组成 ➢结构&#xff1a;HTML ➢表现&#xff1a;CSS ➢行为&#xff1a;JavaScript HTML HTML是一门语言&#xff0c;所有的网页都是用HTML这语言编写出来的 HTML(Hyper Text Markup Language)&#xff1a;超文本标记语言 ➢超文本&#x…

【python】(10)语法糖

Python 语法糖(Syntactic Sugar)是指 Python 中的一些语法特性,它们并不改变语言的功能,但能够使代码更加简洁、易读和优雅。 1. 列表推导式(List Comprehensions) 列表推导式是 Python 中一种简洁的创建列表的方法,它允许我们使用单行代码来生成列表,避免了传统的循…

微服务篇-A JavaEE架构演进历程(学习总结)

原创作者&#xff1a;田超凡 版权所有&#xff0c;转载请注明原作者&#xff0c;严禁复制转载 Level1 传统架构 就是大家众所周知的SSM或SSH了&#xff0c; 优点&#xff1a;三层架构职责清晰 缺点&#xff1a;依赖库管理难度大&#xff0c;协同开发代码冲突和功能扩展性差&a…