EasyExcel对大数据量表格操作导入导出
作者:互联网
前言
最近有个项目里面中有大量的Excel文档导入导出需求,数据量最多的文档有上百万条数据,之前的导入导出都是用apache的POI,于是这次也决定使用POI,结果导入一个四十多万的文档就GG了,内存溢出... 于是找到EasyExcel的文档,学习了一番,解决了大数据量导入导出的痛点。
由于项目中很多接口都需要用到导入导出,部分文档都是根据日期区分,部分文档是需要全表覆盖,于是抽出一个工具类,简化下重复代码,在此把实现过程记录一下。
测试结果
数据量100W
导入
测试了几次,读取完加保存到数据库总耗时都是在140秒左右
导出
由于在业务中不涉及到大数据量的导出,最多只有10W+数据的导出,所以用的是最简单的写,测试二十万的数据量五十秒左右
依赖
1 2 3 4 5 |
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version> 3.1 . 2 </version> </dependency> |
具体实现
实体类
@ExcelProperty注解对应Excel文档中的表头,其中默认属性是value,对应文字,也有index属性,可以对应下标。converter属性是指定一个转换器,这个转换器中实现了把Excel内容转换成java对象(导入使用),Java对象转Excel内容(导出使用),我这里实现的是LocalDateTime和文本的转换。
@ExcelIgnoreUnannotated注解的意思就是在导入导出的时候忽略掉未加@ExcelProperty注解的字段
1 @Data 2 @TableName("t_test_user") 3 @ApiModel(value = "TestUserEntity对象", description = "测试表") 4 @ExcelIgnoreUnannotated 5 public class TestUserEntity implements Serializable { 6 7 private static final long serialVersionUID = 1L; 8 9 @TableId(value = "id", type = IdType.AUTO) 10 private Long id; 11 12 @ExcelProperty("用户名") 13 @ApiModelProperty("用户名") 14 @TableField("user_name") 15 private String userName; 16 17 @ExcelProperty("账号") 18 @ApiModelProperty("账号") 19 @TableField("account") 20 private String account; 21 22 @ExcelProperty("性别") 23 @ApiModelProperty("性别") 24 @TableField("sex") 25 private String sex; 26 27 @ExcelProperty(value = "注册时间", converter = StringToLocalDateTimeConverter.class) 28 @ApiModelProperty("注册时间") 29 @TableField("registered_time") 30 private LocalDateTime registeredTime; 31 32 @ApiModelProperty("数据日期") 33 @TableField("data_date") 34 private Integer dataDate; 35 36 @ApiModelProperty("创建人") 37 @TableField("create_user") 38 private String createUser; 39 40 @ApiModelProperty("创建时间") 41 @TableField("create_time") 42 private LocalDateTime createTime; 43 }
转换器
在这里实现导入导出的数据格式转换
1 /** 2 * @author Tang 3 * @describe easyExcel格式转换器 4 * @date 2022年08月29日 09:41:03 5 */ 6 public class StringToLocalDateTimeConverter implements Converter<LocalDateTime> { 7 /** 8 * 这里读的时候会调用 9 */ 10 @Override 11 public LocalDateTime convertToJavaData(ReadConverterContext<?> context) { 12 String stringValue = context.getReadCellData().getStringValue(); 13 return StringUtils.isBlank(stringValue) ? null : DateUtil.stringToLocalDatetime(stringValue); 14 } 15 16 /** 17 * @describe 写的时候调用 18 * @Param context 19 * @return com.alibaba.excel.metadata.data.WriteCellData<?> 20 * @date 2022年11月17日 16:03:39 21 * @author Tang 22 */ 23 @Override 24 public WriteCellData<?> convertToExcelData(WriteConverterContext<LocalDateTime> context) { 25 return new WriteCellData<>(DateUtil.localDateToDayString(context.getValue())); 26 } 27 28 }