-
Notifications
You must be signed in to change notification settings - Fork 66
3 大数据量导出
guanquan.wang edited this page Nov 7, 2022
·
16 revisions
前面已经展示了简单的导出示例,例子中大部分都传入一个数组,但是我们知道对于十万级、百万级的数量,不可能一次拉取到内存,此时分片功能就突现价值了。
ListSheet和ListMapSheet默认支持分片,我们只需要覆写protected List<T> more()方法即可。
下面代码将展示如何分页拉取学生数据,每次拉取1024条数据,这样内存中最多也就1024条数据,边写边拉取数据,直到返回空数组或者null。
new Workbook().addSheet(new ListSheet<Student>() {
private int pageNo = 0, limit = 1024;
@Override
protected List<Student> more() {
return service.getPageData(++pageNo, limit);
}
}).writeTo(defaultTestPath);得益于EEC的Worksheet默认分页,我们无需更多的处理,上面代码即可支持百万级、千万级数据导出
如下代码测试200w随机数字导出的示例
// 导出200w数据
final int loop = 2000;
new Workbook("200w").addSheet(new ListSheet<E>() {
int n = 0; // 页码
@Override
public List<E> more() {
return n++ < loop ? data() : null;
}
}).writeTo(Paths.get("d:/"));
// 生成测试数据
public List<E> data() {
List<E> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
E e = new E();
list.add(e);
e.nv = random.nextInt();
e.str = getRandomString();
}
return list;
}
// 测试对象
public static class E {
@ExcelColumn
private int nv;
@ExcelColumn
private String str;
}跑上面的测试代码共耗时11.5s,打开文件效果如下:
第一页共写入1048576行,这也是xlsx格式单页最大行数

写满第一页后自动新增一个worksheet并写入剩余数据951426,共计200w+2(2个表头)

对于自动分片数据,我们不需要一个sheet,一个sheet读取,而是直接使用Stream的flatMap功能将worksheet降维处理,如下代码统计200w数据中数字大于1w的个数
try (ExcelReader reader = ExcelReader.read(Paths.get("d:/200w.xlsx"))) {
long count = reader.sheets().flatMap(Sheet::dataRows).map(row -> row.too(E.class)).filter(e -> e.nv > 10000).count();
System.out.println("共计" + count + "个数大于1w");
}贴出DEBUG日志
- File type: XLSX
- Unzip file to:C:\Users\WANGGU~1\AppData\Local\Temp\eec+431216877215304835
- Finished decompress. start to check the file integrity.
- Size of SharedString: 0
- load C:\Users\WANGGU~1\AppData\Local\Temp\eec+431216877215304835\xl\worksheets\sheet1.xml
- Dimension-Range: A1:B1048576
- end of file.
- load C:\Users\WANGGU~1\AppData\Local\Temp\eec+431216877215304835\xl\worksheets\sheet2.xml
- Dimension-Range: A1:B951426
- end of file.
共计999601个数大于1w
- Count: 0, uniqueCount: 0, Repetition rate: 0.0%
- Forward: 0, Backward: 0, SST: 0, Hot: 0, Tester: {Resize: 0, Size: 0}
通过DEBUG日志可以看到使用flatMap解析完sheet1后接着解析sheet2,得出结果999601,与excel筛选出的结果一致

让JAVA操作excel更简单