/**
* #description 参数校验
*
* @param fileName 文件名
* @param list 数据
* @param titleName 列名
* @param suffix 后缀
* @param exportDesc 到处目的地
* @param keys 数据map对应的key
* @return
*/
public static Map verificateParams(String fileName, List<Map> list,
String[] titleName, String suffix,
String exportDesc, String[] keys, HttpServletResponse response) {
Map map = new HashMap(2);
if (CollectionUtils.isEmpty(list)) {
System.out.println("数据不能为空");
return null;
}
if (keys.length != titleName.length) {
System.out.println("表头长度与字段长度不对应");//不烦导出数据与表头不对应,后台不会报错
return null;
}
if (keys.length > list.get(0).size()) {
System.out.println("数据导出字段数目小于keys数目");//即map的key小于keys 会抛出空指针异常
return null;
}
//1.创建工作簿对象
Workbook wb;
if (suffix.length() <= 0 || ".xls".equals(suffix) || StringUtils.isEmpty(suffix)) {
System.out.println("创建2003excel");//最大每个sheet36655行
suffix = ".xls";
wb = new HSSFWorkbook();
} else {
System.out.println("创建2007excel");
// wb= new XSSFWorkbook();//最大每个sheet1048576行
// SXSSF与XSSF的对比:
// a. 在一个时间点上,只可以访问一定数量的数据
// b. 不再支持Sheet.clone()
// c. 不再支持公式的求值
// d. 在使用Excel模板下载数据时将不能动态改变表头,因为这种方式已经提前把excel写到硬盘的了就不能再改了
suffix = ".xlsx";
wb = new SXSSFWorkbook(1000);//保证内存不会溢出。设置每1000行就保存到磁盘
}
if (null == response) {
if (exportDesc.length() <= 0 || exportDesc == null || exportDesc == "") {
System.out.println("导出到桌面");
File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory();
String absolutePath = homeDirectory.getAbsolutePath();
exportDesc = absolutePath + "\\" + fileName + suffix;
map.put("exportDesc", exportDesc);
} else {
exportDesc = exportDesc + "\\" + fileName + suffix;
}
map.put("exportDesc", exportDesc);
}
map.put("wb", wb);
return map;
}
缺点: 2003版本:超过36635会出现oom异常
2007版本:写入非常慢,耗内存也会发生oom
SXSSFWorkbook:写数据非常慢,非常耗内存,百万级也会发生oom
优点:
2003版本过程写入缓存,不操作磁盘,最后一次像写入,速度快
2007版本:可以写较大数据量十几二十万条写入
SXSSFWorkbook大文件写入:数据量大几十万条写入
HSSFWorkbook :每个sheet36655行 对应版本2003 文件后缀:.xls
XSSFWorkbook:每个sheet1048576行 对应版本2007 文件后缀:.xlsx
SXSSFWorkbook:保证内存不会溢出《SXSSFWorkbook(1000)》默认每100行就会保存到磁盘中(会有临时文件注意清除)
下面介绍关键代码
逻辑思路:
1.创建工作薄 Workbook
2.创建table工作表(sheet) Sheet sheet = wb.createSheet
3.创建行 row sheet.createRow(0);
4.列 cell = row.createCell(i)
/**
* @param fileName 文件名称
* @param sheetName 工作表
* @param list 要导出的数据 (里面每个map都是一行数据)
* @param columName 列名
* @param keys 列对应的key
* @param exportDesc 导出目的地
*/
public static void ExportExcelWithholdsOrXls(String fileName, String sheetName,
List<Map> list, String[] columName,
String[] keys, String suffix,
String exportDesc) {
//1.创建工作薄
Map map = verificateParams(fileName, list, columName, suffix, exportDesc, keys);
if (CollectionUtils.isEmpty(map)) {
return;
}
exportDesc = (String) map.get("exportDesc");
Workbook wb = (Workbook) map.get("wb");
//总数据条数
int totalSize = list.size();
//sheetSize 多少个工作表sheet
int i = totalSize % 100000;//默认每个sheet10W行
//有多少个sheet就有多少个表头sheetSize==rowSize
int sheetSize = i == 0 ? totalSize/100000 : totalSize/100000 + 1;
int constant = 100000;
for (int j = 0; j < sheetSize; j++) {
//2.创建table工作表(sheet)
Sheet sheet = wb.createSheet(sheetName+j);
CellStyle borderStyle = wb.createCellStyle();
CellStyle style = wb.createCellStyle();
// sheet.setColumnWidth(0, 3766); //第一个参数代表列id(从0开始),第2个参数代表宽度值
setStyle(wb, sheet, style, borderStyle);
//3.创建第一行 每个sheet都是从row==0开始
Row row = sheet.createRow(0);
//表头,即各个列的列名独占一行 第一行从索引0开始
row.setHeight((short) 400); //目的是想把行高设置成25px
setRow(columName, borderStyle, row);
//4.列
// 表格内容填充
//每个sheet数据需要由总数截取存放 所以这里每个sheet吸入1W条
if(j+1==sheetSize){
List<Map> maps = list.subList(constant * j, totalSize);
setCell(maps, keys, sheet, style);
}else{
List<Map> maps = list.subList(constant * j, constant * j+constant);
setCell(maps, keys, sheet, style);
}
}
try {
OutputStream fileOut = new FileOutputStream(exportDesc);
wb.write(fileOut);
fileOut.flush();
fileOut.close();
//清楚临时文件
if (wb instanceof SXSSFWorkbook) {
((SXSSFWorkbook) wb).dispose();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 二维数组导出
*?代表你有多少列
*【0】【?】第一行都是列名
*【1】【?】第二行都是数据
*/
public static void Export(Object[][] data) {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("table"); //创建table工作薄
Object[][] datas = {
{"区域", "总销售额(万元)", "总利润(万元)简单的表格"},
{"江苏省", 9045, 2256}, {"广东省", 3000, 690}
};
HSSFRow row;
HSSFCell cell;
//行循环
for (int i = 0; i < datas.length; i++) {
row = sheet.createRow(i);//创建表格行
//列循环
for (int j = 0; j < datas[i].length; j++) {
cell = row.createCell(j);//根据表格行创建单元格
cell.setCellValue(String.valueOf(datas[i][j]));
}
}
try {
File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory();
String absolutePath = homeDirectory.getAbsolutePath();
String path = absolutePath + "sd.xls";
wb.write(new FileOutputStream(path));
} catch (IOException e) {
e.printStackTrace();
}
}