springboot集成pagehelper以及easyExcel实现百万数据导出

1.编写excel常量类

package com.authorization.privilege.constant;
 
/**
 * @author qjwyss
 * @description EXCEL常量类
 */
public class ExcelConstant {
 
    /**
     * 每个sheet存储的记录数 100W
     */
    public static final Integer PER_SHEET_ROW_COUNT = 1000000;
 
    /**
     * 每次向EXCEL写入的记录数(查询每页数据大小) 20W
     */
    public static final Integer PER_WRITE_ROW_COUNT = 200000;
 
}
//注:为了书写方便,此处俩个必须要整除,可以省去很多不必要的判断。 另外如果自己测试,可以改为100,20。



2.根据数据量的不同,我们选择不同的导出方法

  • 数据量少的(20W以内吧):一个SHEET一次查询导出

@Override
public ResultVO exportSysSystemExcel(SysSystemVO sysSystemVO, HttpServletResponse response) throws Exception {
 
    ServletOutputStream out = null;
    try {
        out = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
 
        // 设置EXCEL名称
        String fileName = new String(("SystemExcel").getBytes(), "UTF-8");
 
        // 设置SHEET名称
        Sheet sheet = new Sheet(1, 0);
        sheet.setSheetName("系统列表sheet1");
 
        // 设置标题
        Table table = new Table(1);
        List> titles = new ArrayList>();
        titles.add(Arrays.asList("系统名称"));
        titles.add(Arrays.asList("系统标识"));
        titles.add(Arrays.asList("描述"));
        titles.add(Arrays.asList("状态"));
        titles.add(Arrays.asList("创建人"));
        titles.add(Arrays.asList("创建时间"));
        table.setHead(titles);
 
        // 查数据写EXCEL
        List> dataList = new ArrayList<>();
        List sysSystemVOList = this.sysSystemReadMapper.selectSysSystemVOList(sysSystemVO);
        if (!CollectionUtils.isEmpty(sysSystemVOList)) {
            sysSystemVOList.forEach(eachSysSystemVO -> {
                dataList.add(Arrays.asList(
                        eachSysSystemVO.getSystemName(),
                        eachSysSystemVO.getSystemKey(),
                        eachSysSystemVO.getDescription(),
                        eachSysSystemVO.getState().toString(),
                        eachSysSystemVO.getCreateUid(),
                        eachSysSystemVO.getCreateTime().toString()
                ));
            });
        }
        writer.write0(dataList, sheet, table);
 
        // 下载EXCEL
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes("gb2312"), "ISO-8859-1") + ".xls");
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        writer.finish();
        out.flush();
 
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    return ResultVO.getSuccess("导出系统列表EXCEL成功");
}
  • 数据量适中(100W以内):一个SHEET分批查询导出
@Override
public ResultVO exportSysSystemExcel(SysSystemVO sysSystemVO, HttpServletResponse response) throws Exception {
 
    ServletOutputStream out = null;
    try {
        out = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
 
        // 设置EXCEL名称
        String fileName = new String(("SystemExcel").getBytes(), "UTF-8");
 
        // 设置SHEET名称
        Sheet sheet = new Sheet(1, 0);
        sheet.setSheetName("系统列表sheet1");
 
        // 设置标题
        Table table = new Table(1);
        List> titles = new ArrayList>();
        titles.add(Arrays.asList("系统名称"));
        titles.add(Arrays.asList("系统标识"));
        titles.add(Arrays.asList("描述"));
        titles.add(Arrays.asList("状态"));
        titles.add(Arrays.asList("创建人"));
        titles.add(Arrays.asList("创建时间"));
        table.setHead(titles);
 
        // 查询总数并 【封装相关变量 这块直接拷贝就行 不要改动】
        Integer totalRowCount = this.sysSystemReadMapper.selectCountSysSystemVOList(sysSystemVO);
        Integer pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
        Integer writeCount = totalRowCount % pageSize == 0 ? (totalRowCount / pageSize) : (totalRowCount / pageSize + 1);
 
        // 写数据 这个i的最大值直接拷贝就行了 不要改
        for (int i = 0; i < writeCount; i++) {
            List> dataList = new ArrayList<>();
 
            // 此处查询并封装数据即可 currentPage, pageSize这个变量封装好的 不要改动
            PageHelper.startPage(i + 1, pageSize);
            List sysSystemVOList = this.sysSystemReadMapper.selectSysSystemVOList(sysSystemVO);
            if (!CollectionUtils.isEmpty(sysSystemVOList)) {
                sysSystemVOList.forEach(eachSysSystemVO -> {
                    dataList.add(Arrays.asList(
                            eachSysSystemVO.getSystemName(),
                            eachSysSystemVO.getSystemKey(),
                            eachSysSystemVO.getDescription(),
                            eachSysSystemVO.getState().toString(),
                            eachSysSystemVO.getCreateUid(),
                            eachSysSystemVO.getCreateTime().toString()
                    ));
                });
            }
            writer.write0(dataList, sheet, table);
        }
 
        // 下载EXCEL
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes("gb2312"), "ISO-8859-1") + ".xls");
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        writer.finish();
        out.flush();
 
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    return ResultVO.getSuccess("导出系统列表EXCEL成功");
}
  •  数据里很大(几百万都行):多个SHEET分批查询导出
    @Override
    public ResultVO exportSysSystemExcel(SysSystemVO sysSystemVO, HttpServletResponse response) throws Exception {
     
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
     
            // 设置EXCEL名称
            String fileName = new String(("SystemExcel").getBytes(), "UTF-8");
     
            // 设置SHEET名称
            String sheetName = "系统列表sheet";
     
            // 设置标题
            Table table = new Table(1);
            List> titles = new ArrayList>();
            titles.add(Arrays.asList("系统名称"));
            titles.add(Arrays.asList("系统标识"));
            titles.add(Arrays.asList("描述"));
            titles.add(Arrays.asList("状态"));
            titles.add(Arrays.asList("创建人"));
            titles.add(Arrays.asList("创建时间"));
            table.setHead(titles);
     
            // 查询总数并封装相关变量(这块直接拷贝就行了不要改)
            Integer totalRowCount = this.sysSystemReadMapper.selectCountSysSystemVOList(sysSystemVO);
            Integer perSheetRowCount = ExcelConstant.PER_SHEET_ROW_COUNT;
            Integer pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
            Integer sheetCount = totalRowCount % perSheetRowCount == 0 ? (totalRowCount / perSheetRowCount) : (totalRowCount / perSheetRowCount + 1);
            Integer previousSheetWriteCount = perSheetRowCount / pageSize;
            Integer lastSheetWriteCount = totalRowCount % perSheetRowCount == 0 ?
                    previousSheetWriteCount :
                    (totalRowCount % perSheetRowCount % pageSize == 0 ? totalRowCount % perSheetRowCount / pageSize : (totalRowCount % perSheetRowCount / pageSize + 1));
     
     
            for (int i = 0; i < sheetCount; i++) {
     
                // 创建SHEET
                Sheet sheet = new Sheet(i, 0);
                sheet.setSheetName(sheetName + i);
     
                // 写数据 这个j的最大值判断直接拷贝就行了,不要改动
                for (int j = 0; j < (i != sheetCount - 1 ? previousSheetWriteCount : lastSheetWriteCount); j++) {
                    List> dataList = new ArrayList<>();
     
                    // 此处查询并封装数据即可 currentPage, pageSize这俩个变量封装好的 不要改动
                    PageHelper.startPage(j + 1 + previousSheetWriteCount * i, pageSize);
                    List sysSystemVOList = this.sysSystemReadMapper.selectSysSystemVOList(sysSystemVO);
                    if (!CollectionUtils.isEmpty(sysSystemVOList)) {
                        sysSystemVOList.forEach(eachSysSystemVO -> {
                            dataList.add(Arrays.asList(
                                    eachSysSystemVO.getSystemName(),
                                    eachSysSystemVO.getSystemKey(),
                                    eachSysSystemVO.getDescription(),
                                    eachSysSystemVO.getState().toString(),
                                    eachSysSystemVO.getCreateUid(),
                                    eachSysSystemVO.getCreateTime().toString()
                            ));
                        });
                    }
                    writer.write0(dataList, sheet, table);
                }
            }
     
            // 下载EXCEL
            response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes("gb2312"), "ISO-8859-1") + ".xls");
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            writer.finish();
            out.flush();
     
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
     
        return ResultVO.getSuccess("导出系统列表EXCEL成功");
    }

总结:

少执行sql,优化分页速度,才能更快的导出文件

你可能感兴趣的:(java,spring,boot,excel,后端)