问题出现
项目中有一个功能是管理消费券的领取记录,原本的导出方案是使用的POI实现,但是如果数据量过大,POI会存在内存溢出和请求超时问题。比如我这里数据大约5万条,请求下载时会报504,为了解决大数据量导出Excel问题,我这里使用EasyExcel来解决。
解决步骤
1. 导入依赖
由于项目中已经引用了POI的依赖,而新的EasyExcel依赖里面是包含POI依赖的,所以会造成版本冲突,因此我们这里需要将EasyExcel的POI依赖排除掉
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
</exclusions>
</dependency>
2. EasyExcel导出
首先设置下载信息
// 设置下载信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = "cardRecord";
response.setHeader("Content-Disposition", "attachment;filename="+ fileName +".xlsx");
再调用write方法导出
try {
EasyExcel.write(response.getOutputStream(), CardRecordExcel.class).sheet("cardRecord").doWrite(list);
} catch (IOException e) {
e.printStackTrace();
}
最后!也是最关键的一步!由于我们使用axios的请求方式,只能接受json格式的返回数据,没办法接受二进制流,所以这里的返回数据是一堆乱码,并且是没办法在浏览器下载的,所以我们这里在前端需要将数据转换成Blob对象,然后再后续设置下载
.then(function (res) {
const link = document.createElement('a');
const blob = new Blob([res], { type: 'application/vnd.ms-excel' });
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
link.setAttribute('download','cardRecord.xlsx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
至此,搞定!