Springboot导出大数据量excel(二)-分页查询数据List<Map>

目录

一、简介

二、测试

1导出100万行数据测试

2exportExcel堆内存

3exportBigExcel堆内存

 三、关键代码

controller

ExcelUtil

源码地址


一、简介

        在上篇文章《Springboot导出大数据量excel》说道查询数据量过大的时候还没到导出的时候就会导致内存溢出(或者占用服务较大内存)的问题。本文内容主要就是解决这个问题。

注意:excel的有最大支持数据行数1048576(2的20次方),超出会报异常:

{"code":500,"msg":"fail","data":"Invalid row number (1048576) outside allowable range (0..1048575)"}

解决方案:

方案一:

根据实际情况拆分成多个excel的压缩包。

方案二:

使用csv(使用wps打开只能看到1048576数据,使用文本工具打开能看到全部数据)。

参考:《Springboot导出大数据量excel(三)-导出csv到压缩包》

二、测试

使用poi框架实现大数量导出测试:

1导出100万行数据测试

jdk 1.8

easypoi 4.4.0

springboot 2.3.0

jvm -Xms128m -Xmx256m

api结果耗时文件大小
ExcelUtil.exportBigExcel
内存溢出62s31.3M
ExcelUtil.exportExcel
内存溢出-

2exportExcel堆内存

内存溢出

3exportBigExcel堆内存

 三、关键代码

controller

@RequestMapping(value = "export3", method = RequestMethod.GET)
    @ApiOperation(value = "导出大量数据(Map)", notes = "SXSSFWorkbook")
    @ApiImplicitParams({})
    public void export3(HttpServletResponse response, HttpServletRequest request) throws Exception {

        Workbook workbook = null;
        Date start = new Date();
        Map<String, Object> params = new HashMap<>();
        params.put("pageSize", 5000);
        workbook = ExcelUtil.exportBigExcel(params, (param, page) -> {
            param.put("pageNum", page);
            //模拟分页查询数据
            List<Map<String, Object>> list = getPageData2(param);
            return list;
        });
        downLoadExcel("test" + System.currentTimeMillis() + ".xlsx", response, workbook);
        System.out.println(new Date().getTime() - start.getTime());
        workbook.close();
    }

ExcelUtil

    public static SXSSFWorkbook exportBigExcel(Map<String, Object> queryParams, MyExcelExportServer server) {
        //这样表示SXSSFWorkbook只会保留100条数据在内存中,其它的数据都会写到磁盘里,这样的话占用的内存就会很少
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);
        //创建Excel的sheet
        SXSSFSheet sheet = workbook.createSheet("sheet1");
        //从list取第一行到最后一行的内容并放到对应的Excel里,若记录里某字段值没有会有问题
        int rowNum = 0;//行数
        int page = 1;
        int var6 = page + 1;

        for (List<Map<String, Object>> list = server.selectListForExcelExport(queryParams, page); list != null && list.size() > 0; list = server.selectListForExcelExport(queryParams, var6++)) {
            if (rowNum == 0) {
                //设置表头
                int n = 0;//列数
                Map<String, Object> map = list.get(0);
                SXSSFRow first = sheet.createRow(0);//创建sheet的第一行
                for (String key : map.keySet()) {
                    //创建单元格并赋值
                    first.createCell(n).setCellValue(key);
                    n++;
                }
                rowNum++;
            }
            for (Map<String, Object> data : list) {
                SXSSFRow row = sheet.createRow(rowNum);//创建sheet的第rownum+1行
                int n = 0;//列数
                for (String key : data.keySet()) {
                    row.createCell(n).setCellValue(data.get(key) != null ? data.get(key).toString() : "");
                    n++;
                }
                rowNum++;
            }
        }
        return workbook;
    }

源码地址

POI大数据量导出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值