背景
最近公司一个项目,需要将系统里面的用户相关的数据导出到Excel,随着用户数据不断增长,现在已经有200多万的数据了。原来的导出方式,导致系统频繁出现内存溢出,迫不得已必须进行改造。
调优过程
以前的代码
String fileName = URLEncoder.encode("志愿者数据" + DateUtil.today(), "UTF-8");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
ServletOutputStream outputStream = response.getOutputStream();
//根据条件查询符合条件的全部数据,作为系统管理员的时候,可以导出数据库中的全部数据。
List<VolunteerUserVo> result = volunteerUserService.searchAll(x, null, null, null, volunteerName, labelName, phoneNumber, areaCode, StatusEnum.AUDIT.getValue() + "",
i, EXCEL_EXPORT_THRESHOLD, null, getSessionUser(token)).getResult();
EasyExcel.write(outputStream).sheet("sheet").doWrite(result);
重构第一版
/**
* 导出Excel时,单次查询返回数量的阈值50W
* 如果需导出的数量超过该阈值,分批次查询数据
* 这里这个阈值的设定,根据各位机器的实际情况而定
*/
private static final Integer EXCEL_EXPORT_THRESHOLD = 500000;
//查询符合条件的志愿者数量
Long count = volunteerUserService.searchCount(sex, areaCode, volunteerName, phoneNumber, labelName, getSessionUser(token));
long page = 1;
if (count > EXCEL_EXPORT_THRESHOLD) {
if (count % EXCEL_EXPORT_THRESHOLD == 0) {
page = count / EXCEL_EXPORT_THRESHOLD;
} else {
page = count / EXCEL_EXPORT_THRESHOLD + 1