问题背景
业务方需要下载一批数据,并导出成Excel。由于数据量过大,防止服务器挂掉。采取的是每50w条数据放入一个sheet中,每次查5w数据转成Exceldata类。
代码大致如下:
pubic void writeExcel(Param param){
List<ExcelData> excelDatas = dataService.queryExcelList(param)
loops = excelDatas.size()/500000;
if(loops%500000!=0) loops = loops+1;
for(int i=0;i<loops;i++){
//用easyExcel将data转换成文件
}
}
public List<ExcelData> queryExcelList(Param param){
List<ExcelData> result = new ArrayList<>();
List<Data> datas = dataMapper.queryList(param);
result.addAll(datas.parallelStream().map(e->{
ExcelData ed = new ExcelData();
ed.setXX(e.getXX());
……
return ed;
}).collect(Collectors.toList()))
return result;
}
报错
在线上进行测试的时候,出现文件生成失败,具体报错如下
java. lang. I1legalArgumentException: Class of bean unknown
at net.sf.cglib beans.BeanMap$ Generator.create( BeanMap . java:120)
at net.sf.cglib.beans.BeanMap.create(BeanMap. java:58)
at com.alibaba.excel.write.Exce1BuilderImpl.addJava0bjectToExcel(ExcelBulderImpl .java:196)
at com. alibaba. excel . write. ExcelBuilder Impl. addOneRowOfDataToExcel(Exce1uilderImpl.java:123)
at com.alibaba.excel.write.Exce1BuilderImpl.doAddContent (ExcelBuilderImp.java:79)
at com. alibaba. excel . write . Exce1BuilderImpl . addContent(ExcelBuilderImpl.ava:93)
……
光看报错原因,还以为是bean类写错了,但是核对了半天发现并没有改动这一块的内容。于是就去看了一下EasyExcel的源码
报错的地方是
public BeanMap create(){
if (this.beanClass == null){
throw new IllegalArgumentException("Class of bean unknown")
}
……
}
那么就可以发现,是我们传入EasyExcel中的List,中间有空对象。
目前推论是parallelStream 是多线程执行的,由于result是ArrayList,造成组合的时候出现的空对象,导致生成Excel失败