这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战
关于封面:晚饭后回自习室的路上
前言
最近也是在写的一个小练习中,需要用到这个。趁着这次就将写个整合的Demo给大家。
希望能够让大家有所收获。
阅读完本文,我想你对于使用Java配合Easyexcel操作Excel是完全没有问题的啦。
一、环境准备
1.1、导入相关依赖依赖
我使用Easyexcel的jar包是2021年10月的,说一句是最新版本,莫问题吧😁
1 | xml复制代码<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> |
1.2、项目结构
搭建个项目大家都会啦,这里放一下我自己的结构。
二、读Excel操作 readExcel
2.1、前期准备
准备好一个xslx文件模板,我就是准备了我自己了。
我们创建一个实体类,来对应xlsx中的列名。
实体类
1 | java复制代码@Data |
监听器
1 | java复制代码/** |
mapper层:此处只是模拟
1 | java复制代码/** |
类型转换
2.2、读单个Sheet
1 | java复制代码/** |
这里我们无需指定sheet,因为我们就一个工作表,直接默认就完事了。
控制台输出:
1 | cmd复制代码23:35:52.583 [main] INFO com.crush.excel.listener.DemoListener - 解析到一条数据:{"communityName":"掘金","email":"nzc_wyh@163.com","homePageUrl":"https://juejin.cn/user/2859142558267559","name":"宁在春","specialty":"Java后端开发","startDate":"2021-10-31 12:01:52"} |
这是最简单的方式,也是读取Excel中,单个Sheet的操作,但我们平时中,一个excel是会有多个工作表的。
如下:
2.3、读多个Sheet
其实本质上还是操作单个sheet工作表。
因为各个Sheet的数据不同,因而要建立多个Model和多个监听类。
这边就不再把全部model贴出了,如果不太明白,可以去文末看看源码。
同时也要创建多个监听器。
mapper层在这里就省略了哈。
1 | java复制代码/** |
控制台输出:
1 | cmd复制代码23:42:19.733 [main] INFO com.crush.excel.listener.DocumentListener - 解析到一条数据:{"customerId":1,"name":"Document i"} |
我们可以在获取到数据的时候,存储进数据库。另外我们常常会上传excel,进行数据的导入,所以我们再来看看web中的excel的读。
2.4、web中的读
1 | java复制代码@AutowiredDemoMapper demoMapper;/** * 文件上传 * <p> * 1. 创建excel对应的实体对象 参照{@link UploadData} * <p> * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener} * <p> * 3. 直接读即可 */@PostMapping("upload")@ResponseBodypublic String upload(MultipartFile file) throws IOException { EasyExcel.read(file.getInputStream(), DemoModel.class, new DemoListener(demoMapper)).sheet().doRead(); return "success";} |
我想这样的场景是我们在Web开发中最常用到的那种。
如果是内存足够,数据量不是特别大的话,像我这么写也是完全能够接受的。
如果是操作数据十万或几十万数据的大兄弟,可以前去官网看看优化方案。👉Easyexcel | github
三、写Excle操作 writeExcel
3.1、写到单个Sheet中
1 | java复制代码/** |
这是操作excel文件中单个Sheet的操作,十分简单。
EasyExcel.write(fileName, DemoModel.class).sheet(0).doWrite(models);
关于sheet()中的参数0,我们其实就一张Sheet工作表,填与不填其实都一样,另外,此处也可以填sheet表名字,也是一样 。
操作结果:
注意:
注意
:我发现如果我是直接向这个excel文件进行写入,默认是采用覆盖的方式进行写入,即之前有的信息都会被覆盖掉。
测试:
写之前:
写之后:
补充:
如果我们直接写,是采用覆盖模式的,这肯定是不符合一些业务场景的。所以肯定有解决方式的,
easyexcel中对此也是有处理的。
它有一个根据模板写入,模板如下:
1 | java复制代码/** |
最后的效果如下:
写到注意那一小节的时候,我也有考虑这个是如何进行处理的。
我最开始想的是,是先把文件读出来,然后把数据拼接起来,再写进去。但是我一下就推翻这个想法,一旦那样做,内存消耗什么的都太大了,不太合适。
然后简单看了一下,它是直接new了一个File,加载进内存。(觉得自己好憨)
因为这个我又去测试了个不同的,如果把模板修改的不符合会咋样。
测试的结果就是符合我的猜测,就是copy了一份原文件,在源文件的基础上进行写操作,不管原文件格式如何,都会进行保留。
3.2、重复写入或写到多个Sheet中
重复写入:
其实就是循环了单个的操作。
1 | java复制代码// 方法1 如果写到同一个sheet |
data()就是生成数据的一个方法。
写到多个Sheet中:
其本质也是上面那样,只是调用不同监听类,不同的对象罢了,更简单的方式,以做到不同的处理,目前还没有找到更简单的方法。
和读多个sheet中一样的方式,在此处就不再复述了。
3.3、web中的写
既然有写就要也有读了,有始有终,这个也给大家贴出来了。
1 | java复制代码/** |
结果:
四、可能会产生的问题
- 在实体中已经使用了
@Data
注解,就不要再使用@Accessors(chain = true)
,否则会产生读取为空的现象。
这一点我已经亲自踩坑了(一开始排这个错都排了会😂)
2. 在读的时候Listener
里面需要使用spring的@Autowired
给Listener
创建成员变量,然后在构造方法里面传进去。必须不让spring管理Listener
,每次读取都要new
一个。
这两点是我认为十分常见,又比较容易踩的坑,给大家列出来了。
详细的可点击👉 Easexcel 常见问题
五、自言自语
11月更文开始,每天写写项目,做做记录,充实的每一天。
纸上得来终觉浅,绝知此事要躬行。
大家好,我是博主
宁在春
:主页一名喜欢文艺却踏上编程这条道路的小青年。
希望:
我们,待别日相见时,都已有所成
。
一个可爱的猫咪小表情,实在太可爱了,没办法抵挡住诱惑啊。
本文转载自: 掘金