采用Hutool工具类进行导出,分为单sheet和多sheet导出。
对于Excel写出封装,官方文档中提供了两种方法,分别为ExcelWriter和BigExcelWriter。
原理
1、Hutool将Excel写出封装为
ExcelWriter
,原理为包装了Workbook对象,每次调用merge
(合并单元格)或者write
(写出数据)方法后只是将数据写入到Workbook,并不写出文件,只有调用flush
或者close
方法后才会真正写出文件。由于机制原因,在写出结束后需要关闭
ExcelWriter
对象,调用close
方法即可关闭,此时才会释放Workbook对象资源,否则带有数据的Workbook一直会常驻内存。ExcelWriter writer = ExcelUtil.getWriter("d:/writeTest.xlsx");
2、对于大量数据输出,采用
ExcelWriter
容易引起内存溢出,因此有了BigExcelWriter
,使用方法与ExcelWriter
完全一致。BigExcelWriter writer= ExcelUtil.getBigWriter("e:/xxx.xlsx");
具体的使用和详细说明,以及其他的工具类,大家可以去官方文档中查看(https://hutool.cn/docs/),以下是自己整理出的一个简易demo,希望能够对大家有用。
package com.util;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created with IntelliJ IDEA.
*
* @Auther:
* @Date:
* @Description:
*/
@Slf4j
public class ExportDeliveryUtil {
/**
* @Description: exsl表头
* @Param: []
* @return: java.util.Map<java.lang.String,java.lang.String>
* @Author: mashuanglong
* @Date: 2021/6/5
*/
private Map<String, String> getHeaderMap(){
Map<String, String> header = Maps.newLinkedHashMap();
header.put("序号","row");
return header;
}
/**
*
* @Description: 表头 数据 响应 标题 文件名 合并数
* @Param: []
* @return: java.util.Map<java.lang.String,java.lang.String>
* @Author: mashuanglong
* @Date: 2021/6/3
*/
public static void exportMaterialList(Map<String, String> map, List<?> list, HttpServletResponse response
, String fileTitle, String fileName,Integer i){
log.info("开始导出错误日志----------");
boolean b = true;
// 导出获取的数据到excel
if (!list.isEmpty ()){
// 通过工具类创建writer,默认创建xls格式 true:创建xlsx格式
// 数据过大会出现内存溢出问题 ExcelWriter writer = ExcelUtil.getWriter(true);
//getBigWriter数据过大时使用
ExcelWriter writer = ExcelUtil.getBigWriter();
// 自定义excel标题和列名
Set set =map.entrySet();
Iterator it=set.iterator();
while(it.hasNext()){
Map.Entry<String, String> entry=(Map.Entry<String, String>) it.next();
writer.addHeaderAlias(entry.getValue(),entry.getKey());
}
// 参数为true时只导出有别名的
writer.setOnlyAlias(true);
// 为指定的sheet页重命名
writer.setSheet(0);
writer.renameSheet(0,fileTitle);
// 合并单元格后的标题行,使用默认标题样式
writer.merge(0,1,0,i, fileTitle,false);
// 一次性写出内容,使用默认样式,强制输出标题
//从第几行开始输出
writer.setCurrentRow(2);
writer.write (list,true);
// 设置所有列为自动宽度,不考虑合并单元格
writer.autoSizeColumnAll();
// response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", fileName);
// 将excel文件信息写入输出流,返回给调用者
ServletOutputStream excelOut = null;
try {
excelOut = response.getOutputStream();
writer.flush(excelOut,true);
log.info("导出成功----------");
} catch (Exception e) {
e.printStackTrace();
// 捕获异常
log.error("导出异常----------e:"+ ExceptionUtil.getMessage (e));
//自定义异常
}finally {
writer.close();
}
IoUtil.close(excelOut);
}
log.info("导出结束----------");
}
/**
*
* @Description: 表头 数据 标题 文件名 合并数 响应
* 每个集合的长度必须一致
* @Param: []
* @return: java.util.Map<java.lang.String,java.lang.String>
* @Author: mashuanglong
* @Date: 2021/6/3
*/
public static void exportMaterialListS( List<Map<String, String>> mapS,List<List<?>> listS,List<String> fileTitleS
,String fileName,List<Integer> integers, HttpServletResponse response ){
if ( mapS.size() == listS.size() && listS.size() == fileTitleS.size() && fileTitleS.size() == integers.size()){
// 通过工具类创建writer,默认创建xls格式 true:创建xlsx格式
// 数据过大会出现内存溢出问题 ExcelWriter writer = ExcelUtil.getWriter(true);
//getBigWriter数据过大时使用
ExcelWriter writer = ExcelUtil.getBigWriter();
// 自定义excel标题和列名
for (int j = 0; j < mapS.size() ; j++) {
Map<String, String> map = mapS.get(j);
List<?> list = listS.get(j);
String fileTitle = fileTitleS.get(j);
Integer i = integers.get(j);
Set set =map.entrySet();
Iterator it=set.iterator();
while(it.hasNext()){
Map.Entry<String, String> entry=(Map.Entry<String, String>) it.next();
writer.addHeaderAlias(entry.getValue(),entry.getKey());
}
// 参数为true时只导出有别名的
writer.setOnlyAlias(true);
// 为指定的sheet页重命名
writer.setSheet(j);
writer.renameSheet(j,fileTitle);
// 合并单元格后的标题行,使用默认标题样式
writer.merge(0,1,0,i, fileTitle,false);
// 一次性写出内容,使用默认样式,强制输出标题
//从第几行开始输出
writer.setCurrentRow(2);
writer.write (list,true);
// 设置所有列为自动宽度,不考虑合并单元格
writer.autoSizeColumnAll();
writer.reset();
writer.clearHeaderAlias();
}
// response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", fileName);
// 将excel文件信息写入输出流,返回给调用者
ServletOutputStream excelOut = null;
try {
excelOut = response.getOutputStream();
writer.flush(excelOut,true);
log.info("导出成功----------");
} catch (Exception e) {
e.printStackTrace();
// 捕获异常
log.error("导出异常----------e:"+ ExceptionUtil.getMessage (e));
//自定义异常
}finally {
writer.close();
}
IoUtil.close(excelOut);
} else {
//自定义异常
}
}
}