一.概述
EasyExcel是alibaba开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
1.应用场景
1.数据导入:减轻录入的工作量
2.数据导出:统计信息归档
3.数据传输:异构系统之间数据传输
2.EasyPoi和EasyExcel的区别:
EasyPoi和EasyExcel都是基于Apache POI进行二次开发的。
不同点在于:
- EasyPoi 在读写数据的时候,优先是先将数据写入内存,优点是读写性能非常高,但是当数据量很大的时候,会出现OOM,当然它也提供了 sax 模式的读写方式,需要调用特定的方法实现。它主要的特点就是将更多重复的工作,全部简单化,避免编写重复的代码!
- EasyExcel 基于sax模式一行一行解析进行读写数据,不会出现OOM情况,在并发量很大的情况下,程序在经过高并发场景的验证下,依然能稳定运行!相对于 EasyPoi 来说,读写性能稍慢!
OOM(Out Of Memory) 翻译成中文就是”内存用完了”
SAX(simple API for XML) 是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
二.快速入门
1.导包
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version></dependency>
2.读取操作
读取excel需要先写一个监听器继承AnalysisEventListener
实体类:
@Datapublic class DemoData {//设置excel表头名称@ExcelProperty(value = "学生编号",index = 0)private Integer sno;@ExcelProperty(value = "学生姓名",index = 1)private String sname;}
第一种方式:
单独定义一个类去继承AnalysisEventListener
(1)配置
public class ExcelListener extends AnalysisEventListener<DemoData> {//一行一行读取excel内容@Overridepublic void invoke(DemoData data, AnalysisContext analysisContext) {System.out.println("****"+data);}//读取表头内容@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {System.out.println("表头:"+headMap);}//读取完成之后@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) { }}
(2)代码
public class TestEasyExcelRead {public static void main(String[] args) {//实现excel读操作String filename = "D:\\Desktop\\write.xlsx";EasyExcel.read(filename,DemoData.class,new ExcelListener()).sheet().doRead();}}
(3)运行结果

第二种方式:
(1)代码:
@Testpublic void read2() {List<DemoData> list = new ArrayList<>();//实现excel读操作String filename = "D:\\Desktop\\write.xlsx";// write方法两个参数:第一个参数文件路径名称,第二个参数实体类classEasyExcel.read(filename, DemoData.class, new AnalysisEventListener<DemoData>() {//重写子类方法@Overridepublic void invoke(DemoData demoData, AnalysisContext analysisContext) {list.add(demoData);}//重写子类方法@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}@Overridepublic void invokeHeadMap(Map headMap, AnalysisContext context) {System.out.println("表头:" + headMap);}}).sheet().doRead();//遍历for (DemoData data : list) {System.out.println(data);}}
3.写入操作
(1)实体类
①表头设置
@Datapublic class DemoData {//value:设置表头名称//index:设置对应的列编号,标记对应列关系@ExcelProperty(value = "学生编号",index = 0)private Integer sno;@ExcelProperty(value = "学生姓名",index = 1)private String sname;}
②复杂表头
添加该实体列的注释就可以实现如下:
@Datapublic class DemoData {//设置excel表头名称@ExcelProperty({"主标题","学生编号"})private Integer id;@ExcelProperty({"主标题","学生姓名"})private String name;}
效果:
③列宽 行高
@Data@HeadRowHeight(30) //表头行高@ContentRowHeight(20) //数据行高@ColumnWidth(25) //列宽public class DemoData {//设置excel表头名称@ExcelProperty({"主标题","学生编号"})private Integer id;//局部定义@ColumnWidth(50)@ExcelProperty({"主标题","学生姓名"})private String name;}
效果:
(2)代码
package com.example.easyexceldemo.controller;import com.alibaba.excel.EasyExcel;import com.example.easyexceldemo.entity.DemoData;import java.util.ArrayList;import java.util.List;public class TestEasyExcelWrite {public static void main(String[] args) {//实现excel写的操作//1 设置写入文件夹地址和excel文件名称String filename = "D:\\Desktop\\write.xlsx";// 2 调用easyexcel里面的方法实现写操作// write方法两个参数:第一个参数文件路径名称,第二个参数实体类classEasyExcel.write(filename,DemoData.class).sheet("学生列表").doWrite(getData());}//创建方法返回list集合private static List<DemoData> getData() {List<DemoData> list = new ArrayList<>();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setId(i);data.setName("lucy"+i);list.add(data);}return list;}}
(3)运行结果
三.常用注解
1.读取操作
●ExcelProperty
指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写,默认第
一个字段就是index=0,以此类推。千万注意,要么全部不写,要么全部用index,要么全部用
名字 去匹配。千万别三个混着用,除非你非常了解源代码中三个混着用怎么去排序的。
● ExcelIgnore
默认所有字段都会和excel去匹配,加了这个注解会忽略该字段
● DateTimeFormat
日期转换,用String去接收excel日期格式的数据会调用这个注解。里面的value参照 java.text.SimpleDateFormat
● NumberFormat
数字转换,用String去接收excel数字格式的数据会调用这个注解。里面的value参照 java.text.DecimalFormat
● ExcelIgnoreUnannotated
默认不加ExcelProperty 的注解的都会参与读写,加了不会参与
2.写入操作
● ExcelProperty index
指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字,多
个value可以参照快速开始中的复杂头
● ExcelIgnore
默认所有字段都会写入excel,这个注解会忽略这个字段
● DateTimeFormat
日期转换,将Date写到excel会调用这个注解。里面的value参照java.text.SimpleDateFormat
● NumberFormat
数字转换,用Number写excel会调用这个注解。里面的value参照java.text.DecimalFormat
● ExcelIgnoreUnannotated
默认不加ExcelProperty 的注解的都会参与读写,加了不会参与
