poi实现列表导出多sheet模板excel文件
1.背景介绍
要求导出一个List<Map<String,Object>>,其中每个Map的内容以模板的形式导出为excel的一个sheet页;List的长度即sheet页的页数,总共保存为一个excel文件
2.整体思路
1)建立一个excel模板
2)后台获取泛型是Map<String,Object>的数据列表
3)循环遍历列表,为每个Map创建一个工作簿对象,并合并至之前的workbook,end!
关键点:3)的每次循环都要进行的操作就是读取1)写好的模板,并且把map的值合并到模板,这个操作可以写一个新的方法进行调用。
3.实现
1)首先自己建一个excel单sheet导出模板
说明:这个单sheet模板一页对应着你的list集合的一个map,map的键名字需要匹配以上模板中{{}}中的名字,这样建对应的值即可绑定到对应位置~
2)后台
①主方法
public void export(HttpServletResponse response){
try {
XSSFWorkbook finalExportExcel = new XSSFWorkbook();
//查询数据
List<Map<String,Object>> userList = (List<Map<String, Object>>) userService.getUserList();
//多个workbook合并
for(int i = 0;i < userList.size();i ++){
userList.get(i).put("sum", userList.size());
userList.get(i).put("num", i+1);
// 获取workbook对象
Workbook fromworkbook = exportSheetByTemplate(userList.get(i)) ;
XSSFSheet oldSheet = (XSSFSheet) fromworkbook.getSheetAt(0);
XSSFSheet newSheet = finalExportExcel.createSheet("sheet"+(i+1));
ExportUtil.copySheet(finalExportExcel, oldSheet, newSheet);
}
// 导出配置
// 设置excel的文件名称
String excelName = "excel" ;
// 重置响应对象
response.reset();
// 当前日期,用于导出文件名称
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String dateStr = "["+excelName+"-"+sdf.format(new Date())+"]";
// 指定下载的文件名--设置响应头
response.setHeader("Content-Disposition", "attachment;filename=" +dateStr+".xls");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 写出数据输出流到页面
OutputStream output = response.getOutputStream();
BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
finalExportExcel .write(bufferedOutPut);
bufferedOutPut.flush();
bufferedOutPut.close();
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
②调用方法
public Workbook exportSheetByTemplate(Map<String, Object> map){
try {
//获取之前写好的模板
String path =this.getRequest().getSession().getServletContext().getRealPath("downloadFile")+System.getProperty("file.separator")+"template.xlsx";
TemplateExportParams params = new TemplateExportParams(path,true);
// 执行方法
return ExcelExportUtil.exportExcel(params, map);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
4.心得
1)对workbook(接口),HSSFworkbook,XSSFworkbook(接口实现)的操作要熟悉
2)响应头设置:
① response.setHeader("Content-Disposition", "attachment;filename=" +dateStr+".xls");
这一句中的“Content-Disposition”**文件下载框,“attachment”提示用户进行下载
② response.setContentType("application/vnd.ms-excel;charset=UTF-8");
设置响应类型:excel
③ response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
强制清除缓存,强制过期,如果不设置的话,浏览器的缓存机制可能导致你用相同的url访问时返回之前的文件!
3)规范:导出文件名称最好加一段时间以供区分
4)逻辑:之前尝试过用easypoi进行多sheet页模板导出,但是始终没有成功(单sheet模板or多sheet非模板都成功了),easypoi是别人写好的轮子,我对他除了翻翻网上的资料以外没有仔细研究,但是直接用poi的话,试想就是导出单个模板页面,只不过我每次把他合并到一个新的工作部里就可以了~