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导出模板

 

poi实现列表导出多sheet模板excel文件

说明:这个单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的话,试想就是导出单个模板页面,只不过我每次把他合并到一个新的工作部里就可以了~