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++;
}
}
}