阿里开源(EasyExcel)---导出EXCEL
程序员文章站
2022-07-13 15:55:00
...
一. 简介
导出是后台管理系统的常用功能,当数据量特别大的时候会内存溢出和卡顿页面,曾经自己封装过一个导出,POI百万级大数据量EXCEL导出 采用了分批查询数据来避免内存溢出和使用SXSSFWorkbook方式缓存数据到文件上以解决下载大文件EXCEL卡死页面的问题。不过一是存在封装不太友好使用不方便的问题,二是这些poi的操作方式仍然存在内存占用过大的问题,以及存在内存溢出的隐患。无意间查询到阿里开源的EasyExcel框架,发现可以将解析的EXCEL的内存占用控制在KB级别,并且绝对不会内存溢出(内部实现待研究),还有就是速度极快, 大概100W条记录,十几个字段, 只需要70秒即可完成下载。遂抛弃自己封装的,转战研究阿里开源的EasyExcel. 不过 说实话,当时自己封装的那个还是有些技术含量的,例如 外观模式,模板方法模式,以及委托思想,组合思想,可以看看。
EasyExcel的github地址是:https://github.com/alibaba/easyexcel
二. 案例
2.1 POM依赖
<!-- 阿里开源EXCEL -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.1</version>
</dependency>
2.2 POJO对象
package com.authorization.privilege.excel;
import java.util.Date;
/**
* @author qjwyss
* @date 2019/3/15
* @description
*/
public class User {
private String uid;
private String name;
private Integer age;
private Date birthday;
public User() {
}
public User(String uid, String name, Integer age, Date birthday) {
this.uid = uid;
this.name = name;
this.age = age;
this.birthday = birthday;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
2.3 测试
2.3.1 数据量少的:一个SHEET一次查询导出
/**
* 针对较少的记录数可以调用该方法一次性查出然后写入到EXCEL的一个SHEET中
* 注意: 一次性查询出来的记录数量不宜过大,不会内存溢出即可。
*
* @throws IOException
*/
@Test
public void writeExcelOneSheetOnce() throws IOException {
// 生成EXCEL并指定输出路径
OutputStream out = new FileOutputStream("E:\\temp\\withoutHead1.xlsx");
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
// 设置SHEET
Sheet sheet1 = new Sheet(1, 0);
sheet1.setSheetName("sheet1");
// 设置标题
Table table = new Table(1);
List<List<String>> titles = new ArrayList<List<String>>();
titles.add(Arrays.asList("用户ID"));
titles.add(Arrays.asList("名称"));
titles.add(Arrays.asList("年龄"));
titles.add(Arrays.asList("生日"));
table.setHead(titles);
// 查询数据导出即可
List<List<String>> userList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
userList.add(Arrays.asList("ID_" + i, "小明" + i, String.valueOf(i), new Date().toString()));
}
writer.write0(userList, sheet1, table);
writer.finish();
}
2.3.2 数据量适中: 一个SHEET分批查询导出
/**
* 针对106W以内的记录数可以调用该方法分多批次查出然后写入到EXCEL的一个SHEET中
* 注意:
* 每次查询出来的记录数量不宜过大,根据内存大小设置合理的每次查询记录数,不会内存溢出即可。
* 数据量不能超过一个SHEET存储的最大数据量105W
*
* @throws IOException
*/
@Test
public void writeExcelOneSheetRepeatly() throws IOException {
// 生成EXCEL并指定输出路径
OutputStream out = new FileOutputStream("E:\\temp\\withoutHead2.xlsx");
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
// 设置SHEET
Sheet sheet1 = new Sheet(1, 0);
sheet1.setSheetName("sheet1");
// 设置标题
Table table = new Table(1);
List<List<String>> titles = new ArrayList<List<String>>();
titles.add(Arrays.asList("用户ID"));
titles.add(Arrays.asList("名称"));
titles.add(Arrays.asList("年龄"));
titles.add(Arrays.asList("生日"));
table.setHead(titles);
// 模拟分批查询:总记录数50条,每次查询20条, 分三次查询
Integer totalRowCount = 50;
Integer pageSize = 20;
Integer writeCount = totalRowCount % pageSize == 0 ? (totalRowCount / pageSize) : (totalRowCount / pageSize + 1);
for (int i = 0; i < writeCount - 1; i++) {
// 此处到时候可以使用DAO分批查询即可
List<List<String>> userList = new ArrayList<>();
for (int j = i * pageSize + 1; j <= (i + 1) * pageSize; j++) {
userList.add(Arrays.asList("ID_" + j, "小明", String.valueOf(j), new Date().toString()));
}
writer.write0(userList, sheet1, table);
}
if (totalRowCount % pageSize != 0) {
List<List<String>> userList = new ArrayList<>();
for (int k = (writeCount - 1) * pageSize + 1; k <= totalRowCount; k++) {
userList.add(Arrays.asList("ID_" + k, "小明", String.valueOf(k), new Date().toString()));
}
writer.write0(userList, sheet1, table);
}
writer.finish();
}
2.3.3 数据里很大: 多个SHEET分批查询导出 TODO
三. 实际使用 TODO
推荐阅读
-
Excel-Boot(一款Excel导入导出解决方案组成的轻量级开源组件)
-
建议收藏:.net core 使用EPPlus导入导出Excel详细案例,精心整理源码已更新至开源模板
-
ASP.NET 开源导入导出库Magicodes.IE 完成Excel图片导入导出
-
阿里easyexcel通过模板导出excel
-
阿里开源(EasyExcel)---导出EXCEL
-
项目中Excel导出大数据量记录解决方案及实战(POI,Hutools,EasyExcel)
-
EasyExcel导出excel,设置行中单个单元格的样式
-
Java使用easyexcel导出excel动态数据字段
-
JAVA 使用阿里EasyExcel完成对Excel文件进行读写操作
-
SpringBoot引用阿里easyexcel,Excel导出返回浏览器下载