java环境使用SXSSFSheet实现导出大量数据时,解决内存溢出问题

 
SXSSFSheet,主要用于操作Excel 2007及更高版本(扩展名为.xlsx),支持的最大行数为1048576行,最大列数为16384列‌。
通过维护一个有限大小的工作表缓存(默认100行),当缓存满时,会将最旧的行数据写入硬盘并从内存中移除,从而减少内存消耗,适用于处理大数据量的情况‌

测试发现当数据量超过50w时,会报内存溢出的问题。

这里选择分页查询数据写入excel中的方法解决,实测有效。

分页查询数据,每页查询10w数据

    public void exportExcelByPage(GetDataSetTableDataDTO dto, HttpServletResponse response) {
        // 创建一个HSSFWorkbook,对应一个Excel文件
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        //记录创建的sheet数量
        int sheetIndex = 1;
        final int dataSize = 100000;

        LinkedHashMap<String, String> title = new LinkedHashMap();
        if (ValidateUtil.isNotEmpty(dto.getColumns())) {
            dto.getColumns().forEach(item -> {
                if (ValidateUtil.isNotEmpty(getObjectString(item.get(IndexConstants.TITLE)))) {
                    title.put(getObjectString(item.get(IndexConstants.TITLE)), getObjectString(item.get(IndexConstants.TITLE)));
                }
            });
        }
        //分页获取数据
        List<Map<String, Object>> dataList;
        PageParam pageParam = new PageParam();
        pageParam.setPageSize(dataSize);
        do {
            pageParam.setPageNumber(sheetIndex);
            Page<Map<String, Object>> pageData = tDjpsCountIndexTaskReadService.getDataSetTableDataByPage(dto, pageParam);
            dataList = pageData.getList();
            //excel写数据
            ExcelUtils.getBigDataSheet(title, dataList, workbook, sheetIndex);
            sheetIndex++;
        } while (dataList.size()==dataSize) ;

        response.setContentType("application/octet-stream; charset=utf-8");//以流的形式对文件进行下载
        response.setHeader("Content-Disposition", "attachment;");
        try {
            workbook.write(response.getOutputStream());
            response.getOutputStream().close();

        } catch (Exception e) {
            log.error("导出文件失败=======================", e);
        }

    }
SXSSFSheet处理excel数据,保证每页都有标题列
    public static void getBigDataSheet(LinkedHashMap<String, String> title, List<Map<String, Object>> dataList,SXSSFWorkbook workbook,int sheetIndex){
        if(ValidateUtil.isEmpty(dataList)){
            return;
        }
        // 在workbook中添加一个sheet,对应Excel文件中的sheet
        SXSSFSheet sheet = workbook.createSheet("sheet" + sheetIndex);
        // 在sheet中添加表头第0行
        SXSSFRow row = sheet.createRow(0);
        // 创建单元格,并设置值表头 设置表头居中
        CellStyle cellStyle = workbook.createCellStyle();
        DataFormat dataFormat = workbook.createDataFormat();
        cellStyle.setDataFormat(dataFormat.getFormat("@"));
        // 声明列对象
        Cell headCell;
        // 创建标题
        int rowKey = 0;
        if(!ValidateUtil.isEmpty(title)){
            for (Map.Entry entry : title.entrySet()) {
                headCell=  row.createCell(rowKey);
                headCell.setCellValue(entry.getValue().toString());
                headCell.setCellStyle(cellStyle);
                rowKey++;
            }
        }


        // 创建内容
        Cell rowCell;
            for (int i = 0; i < dataList.size(); i++) {
                row = sheet.createRow(i + 1);
                Map<String, Object> data = dataList.get(i);
                int j = 0;
                    for (Map.Entry entry : title.entrySet()) {
                        rowCell = row.createCell(j);
                        rowCell.setCellValue(data.get(String.valueOf(entry.getKey()).toUpperCase().replaceAll("-", "_")) == null ? "" : data.get(String.valueOf(entry.getKey()).toUpperCase().replaceAll("-", "_")).toString());
                        rowCell.setCellStyle(cellStyle);
                        j++;
                    }
            }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值