POI操作EXCEL对象
HSSF:操作Excel 97(.xls)格式
XSSF:操作Excel 2007 OOXML (.xlsx)格式,操作EXCEL内存占用高于HSSF
SXSSF:从POI3.8 beta3开始支持,基于XSSF,低内存占用。
使用POI的HSSF对象,生成Excel 97(.xls)格式,生成的EXCEL不经过压缩直接导出。
线上问题:负载服务器转发请求到应用服务器阻塞,以及内存溢出 。
如果系统存在大数据量报表导出,则考虑使用POI的SXSSF进行EXCEL操作。
HSSF生成的Excel 97(.xls)格式本身就有每个sheet页不能超过65536条的限制。
XSSF生成Excel 2007 OOXML (.xlsx)格式,条数增加了,但是导出过程中,内存占用率却高于HSSF.
SXSSF是自3.8-beta3版本后,基于XSSF提供的低内存占用的操作EXCEL对象。其原理是可以设置或者手动将内存中的EXCEL行写到硬盘中,这样内存中只保存了少量的EXCEL行进行操作。
EXCEL的压缩率特别高,能达到80%,12M的文件压缩后才2M左右。 如果未经过压缩、不仅会占用用户带宽,且会导致负载服务器(apache)和应用服务器之间,长时间占用连接(二进制流转发),导致负载服务器请求阻塞,不能提供服务。
一定要注意文件流的关闭
防止前台(页面)连续触发导出EXCEL
一、导出Excel 97(.xls)格式 ,少量数据, 65535 条数据以下
//存储最大列宽,宽度自适应需要使用
Map<Integer,Integer> maxWidth = new HashMap<Integer,Integer>();
// 声明一个工作薄
HSSFWorkbook wb=new HSSFWorkbook();
// 生成一个(带标题)表格
HSSFSheet sheet = wb.createSheet();
//第一行
HSSFRow row=sheet.createRow(0);
//循环设置第一行的标题
for(int i=0;i<list.size();i++){
String cm = list.get(i).getName();
//获取列
HSSFCell cell = row.createCell(i);
//设置内容
cell.setCellValue(cm);
maxWidth.put(i,cell.getStringCellValue().getBytes().length * 256 + 200);
}
//填充数据
HSSFRow row = null;
int index=1;
for(int i=0;i<总条数.size();i++){
row = sheet.createRow(index++);
for(int j=0;j<数据.size();j++){
HSSFCell cel = row.createCell(j);
cel.setCellValue("值");
//取列的最大宽度
int length = cel.getStringCellValue().getBytes().length * 256 + 200;
if ( maxWidth.containsKey(c) && maxWidth.get(c)<length ){
maxWidth.put(c,length);
}
}
}
//设置列宽
for(int i=0;i<列总数.size();i++){
sheet.setColumnWidth(i, maxWidth.get(i));
}
二、导出Excel 2007 OOXML (.xlsx)格式 1024*1024 = 1048576 条数据
//存储最大列宽,宽度自适应需要使用
Map<Integer,Integer> maxWidth = new HashMap<Integer,Integer>();
// 声明一个工作薄
Workbook wb=new SXSSFWorkbook();
// 生成一个(带标题)表格
Sheet sheet = wb.createSheet();
//第一行
Row row = sheet.createRow(0);
//循环设置第一行的标题
for(int i=0;i<list.size();i++){
String cm = list.get(i).getName();
//获取列
Cell cell = row.createCell(i);
//设置内容
cell.setCellValue(cm);
maxWidth.put(i,cell.getStringCellValue().getBytes().length * 256 + 200);
}
//填充数据
Row row = null;
int index=1;
for(int i=0;i<总条数.size();i++){
row = sheet.createRow(index++);
for(int j=0;j<数据.size();j++){
Cell cel = row.createCell(j);
cel.setCellValue("值");
//取列的最大宽度
int length = cel.getStringCellValue().getBytes().length * 256 + 200;
if ( maxWidth.containsKey(c) && maxWidth.get(c)<length ){
maxWidth.put(c,length);
}
}
}
//设置列宽
for(int i=0;i<列总数.size();i++){
sheet.setColumnWidth(i, maxWidth.get(i));
}