一、EasyExcel
传统Excel操作或者解析都是利用Apach POI
进行操作,但是使用过这个框架的人都知道,这个框架并不完美,有较多的缺陷:
OOM
注:OOM (Out Of Menmory Error): 内存不足错误
基于上述原因,阿里开源出一款易上手,且比较节省内存的Excel
操作框架:EasyExcel
官方文档
Apach POI
当利用Apach POI
去读取Excel文件时,首先先将数据全部加载到内存当中(**主要原因**)
,然后返回给调用者,当数据量比较大的时候,就会发生OOM
EasyExcel
当利用EasyExcel
进行转换的时候,主要是采用SAX模式,进行一行一行解析,并且将每一行的解析结果以行为单位用观察者模式通知处理,所以即使数据量比较大的时候也不会发生``OOM`
准备工作
添加maven
依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>2.2.7version>
dependency>
/**
* Created by IntelliJ IDEA.
* User: LvHaoIT (asus)
* Date: 2022/1/21
* Time: 13:33
*/
@Data
@TableName("WBCX_APPLYSOURCE")
@ApiModel(value = "WBCX_APPLYSOURCE扫描单次记录表", description = "WBCX_APPLYSOURCE扫描单次记录表")
public class SingleOneScan implements Serializable {
@TableId(type = IdType.AUTO)
@ApiModelProperty(value = "id")
private Integer id;
@ApiModelProperty(value = "类别 二维码0 数据包1")
private int orCategory;
@ApiModelProperty(value = "当前页")
private int nowPage;
@ApiModelProperty(value = "总共页数")
private int pageCount;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd hh:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
@ApiModelProperty(value = "添加时间")
private Date scanTime;
@ApiModelProperty(value = "添加人id")
private String userId;
@ApiModelProperty(value = "添加人姓名")
private String userName;
}
生成Excel方法 ,通过使用EasyExcel
这个工具类,可以完成操作
public List<SingleOneScan> getData() {
List<SingleOneScan> list = new ArrayList<>();
for(int i = 0; i <= 10; i++) {
SingleOneScan singleOneScan = new SingleOneScan();
singleOneScan.setId(i + 1);
singleOneScan.setUserName("张三");
//.... 添加数据,动态数据这里增加即可
list.add(singleOneScan);
}
return list;
}
EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class).sheet().doWrite(getData());
如下
代码解释
EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)
EasyExcel.write
表示创建一个Excel写对象,两个参数
观察源码
public class EasyExcelFactory {
/**
* 构建一个Excel写对象
*
* @return
*/
public static ExcelWriterBuilder write() {
return new ExcelWriterBuilder();
}
/**
* 构建一个Excel写对象
*
* @param file 用来写出文件对象
*
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(File file) {
return write(file, null);
}
/**
* 构建 Excel写对象
*
* @param file
* 用来写出的文件对象
* @param head
* 写出的数据类型的class对象
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(File file, Class head) {
ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
excelWriterBuilder.file(file);
if (head != null) {
excelWriterBuilder.head(head);
}
return excelWriterBuilder;
}
/**
* 构建Excel 写对象
*
* @param pathName
* 写出的文件路径名
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(String pathName) {
return write(pathName, null);
}
/**
* 构建excel 写对象
*
* @param pathName
* 写出的文件路径名
* @param head
* 写出数据的数据类型的class对象
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(String pathName, Class head) {
ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
excelWriterBuilder.file(pathName);
if (head != null) {
excelWriterBuilder.head(head);
}
return excelWriterBuilder;
}
/**
* 构建excel写对象
*
* @param outputStream
* 写出的输出流对象
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(OutputStream outputStream) {
return write(outputStream, null);
}
/**
* 构建excel写对象
*
* @param outputStream
* 写出的输出流
* @param head
* 写出数据的数据类型的class对象
* @return Excel writer builder
*/
public static ExcelWriterBuilder write(OutputStream outputStream, Class head) {
ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
excelWriterBuilder.file(outputStream);
if (head != null) {
excelWriterBuilder.head(head);
}
return excelWriterBuilder;
}
}
sheet()
表示需要在 Excel
的哪一个 sheet(页)
里面写入数据,如果不指定,默认在第一个sheet页写入数据,值为0
观察源码
public class ExcelWriterBuilder extends AbstractExcelWriterParameterBuilder<ExcelWriterBuilder, WriteWorkbook> {
/*
选中第一个sheet页
写操作 sheet 页的值为 0
*/
public ExcelWriterSheetBuilder sheet() {
return sheet(null, null);
}
/*
选中 第一个的 sheet页
sheet 页的名字 为 sheetNo
*/
public ExcelWriterSheetBuilder sheet(Integer sheetNo) {
return sheet(sheetNo, null);
}
/*
选中第一个的 sheet页
sheet 页的名字 为 sheetName
*/
public ExcelWriterSheetBuilder sheet(String sheetName) {
return sheet(null, sheetName);
}
/*
选中第一个 sheet页
sheet 页的名字 为 sheetNo 或者 sheetName
*/
public ExcelWriterSheetBuilder sheet(Integer sheetNo, String sheetName) {
ExcelWriter excelWriter = build();
ExcelWriterSheetBuilder excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
if (sheetNo != null) {
excelWriterSheetBuilder.sheetNo(sheetNo);
}
if (sheetName != null) {
excelWriterSheetBuilder.sheetName(sheetName);
}
return excelWriterSheetBuilder;
}
}
可以看到可以写入两个参数,指定 页
与 页的名称
doWrite
表示需要写出的数据,写出的数据为一个List
集合
自定义表头
之前不做设置的情况下,表头均为属性名称,并且排列的顺序为类中属性排列顺序,但是实际需求中,表头为自定义信息,并且顺序也不一定按照属性的顺序来
利用注解来自定义表头@ExcelProperty
@ExcelProperty("自定义表头名称")
private int orCategory;
自定义排列顺序
order
的值越大,表项越往右边
@ExcelProperty(value="自定义表头名称",order = 10)
private int orCategory;
多级表头
@ExcelProperty(value={"自定义表头名称1","子表头1"})
private int orCategory;
@ExcelProperty(value={"自定义表头名称1","子表头2"})
private int count;
如图
设置单元格宽高
1.统一设置(简单,但是宽度不美观)
@HeadRowHeight(value = 35) // 表头行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 50) // 列宽
public class User{
//...
}
2.设置自适应宽度
//1.去掉列宽注解
@HeadRowHeight(value = 35) // 表头行高
@ContentRowHeight(value = 25) // 内容行高
public class User{
//...
}
//2.修改生成代码
EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)
//自适应宽度
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.sheet().doWrite(getData());
生成表项**日期格式化 **
@DateTimeForMat(yyyy-MM-dd)
@com.alibaba.excel.annotation.format.DateTimeFormat
private Date applyDateEnd;
区分spring框架中提供的DateTimeFormat
忽略写入表项
@ExcelIgnore
可以把不需要生成的表项进行忽略
@ExcelIgnore
private Date applyDateEnd;
指定写入
.includeColumnFiledNames(set)
这种方式可以在忽视注解的情况下,指定需要哪些表项进行生成。
//1.创建一个hashSet 里面存放需要导出列的属性名称
//必须要和类中的属性名称相同
Set<String> set = new HashSet<>();
set.add("id");
set.add("userName");
//2.在生成的时候增加.includeColumnFiledNames(set)
EasyExcel.write("单次扫描表.xlsx", SingleOneScan.class)
//指定写入
.includeColumnFiledNames(set)
//自适应宽度
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.sheet().doWrite(getData());
简介:读取在实际开发中也占据了较大地位,但是读取并不是读取任意的一个Excel
文件,而是读取按照事先提供好的Excel
模板,用户在模块版上修改数据的Excel