Freemaker基于word模板动态导出压缩文件汇总整理
Freemaker基于word模板动态导出压缩文件汇总整理
Freemaker基于word模板动态导出单个文件思路和代码详情见连接:
https://www.cnblogs.com/lsy-blogs/p/9243281.html
核心思路如下:
1、service中写方法,查询需要导出的结果list集合数据;
2、控制层中调用service方法获取结果集合数据,调用freemaker获取对应的word文件到临时目录下;
3、利用流处理,将临时目录下导出的每一个word写入到压缩文件中去,利用流输出到浏览器中,实现压缩文件下载;
4、最终将各种流关闭,并将产生的临时word文件删除;
核心是工具类和控制层的调用,核心代码如下:
控制层代码:
@RequestMapping(params = "exportBatchResultScoreWordZip") public void exportBatchResultScoreWordZip(String ids, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid, ModelMap modelMap) { //获取要批量导出的result_score表的主键id数组 String[] resultScoreIds = ids.split(","); // 调用service中的方法,获取批量导出word导出需要的目录主表、字段表信息结果集合 List<ProvinceCityResultOneVO> resultOneVOList = tBAssessResultScoreService.getWrodResultListByResultScoreIds(resultScoreIds); List<Map<String, Object>> wordResultDataMapList = new ArrayList<Map<String, Object>>(); String departLevel = ""; String resultRarFileName = ""; for(int i = 0; i < resultOneVOList.size(); i++) { ProvinceCityResultOneVO resultOneVO = resultOneVOList.get(i); String appraiseYear = resultOneVO.getAppraiseYear(); String departName = resultOneVO.getDepartName(); String departType = resultOneVO.getDepartType(); String fileName = appraiseYear+"年"+departName+"结果"; Map<String, Object> assessResultMap = new HashMap<String, Object>(); assessResultMap.put("assessResul", resultOneVO); assessResultMap.put("fileName", fileName); String templateName = ""; if("1".equals(departType)) { templateName = "provinceResultScoreBatchWordRar.xml"; }else if("2".equals(departType)) { templateName = "cityResultScoreBatchWordRar.xml"; } if(i==0) { departLevel = departType; } assessResultMap.put("templateName", templateName); wordResultDataMapList.add(assessResultMap); } if(StringUtil.isNotEmpty(departLevel)) { Date nowDate = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String nowDateStr = simpleDateFormat.format(nowDate); if("1".equals(departLevel)) { //省批量导出压缩文件名称赋值 resultRarFileName = "结果_"+nowDateStr; }else if("2".equals(departLevel)) { //市批量导出压缩文件名称赋值 resultRarFileName = "结果_"+nowDateStr; } } String resultFileType = "zip"; try { WordUtils.exportMillCertificateWordZip(request, response, wordResultDataMapList,resultRarFileName,resultFileType); } catch (IOException e) { e.printStackTrace(); } }
word导出工具类代码:
package com.jeecg.assessResultScore.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URLEncoder; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jeecgframework.core.util.StringUtil; import com.jeecg.assessResultScore.vo.ProvinceCityResultOneVO; import freemarker.template.Configuration; import freemarker.template.Template; public class WordUtils { // 配置信息,代码本身写的还是很可读的,就不过多注解了 private static Configuration configuration = null; // 这里注意的是利用WordUtils的类加载器动态获得模板文件的位置 private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "export/template/"; static { configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); try { configuration.setDirectoryForTemplateLoading(new File(templateFolder)); } catch (IOException e) { e.printStackTrace(); } } private WordUtils() { throw new AssertionError(); } /** * 下载单个word文件 * @param request 请求 * @param response 响应 * @param map word结果数据 * @param fileName 结果文件名称(不需要带后缀的) * @param wordXmlName word模板名称 * @throws IOException */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,String fileName,String wordXmlName) throws IOException { Template freemarkerTemplate = configuration.getTemplate(wordXmlName); File file = null; InputStream fin = null; ServletOutputStream out = null; try { // 调用工具类的createDoc方法生成Word文档 file = createDoc(map, freemarkerTemplate); fin = new FileInputStream(file); //根据不同浏览器,对fileName进行不同的编码 String userAgent = request.getHeader("user-agent").toLowerCase(); if (userAgent.contains("msie") || userAgent.contains("like gecko") ) { // win10 ie edge 浏览器 和其他系统的ie fileName = URLEncoder.encode(fileName, "UTF-8"); } else { // fe fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1"); } response.setCharacterEncoding("utf-8"); response.setContentType("application/msword"); // 设置浏览器以下载的方式处理该文件名 fileName = fileName+".doc"; response.setHeader("Content-Disposition", "attachment;filename="+fileName); out = response.getOutputStream(); byte[] buffer = new byte[512]; // 缓冲区 int bytesToRead = -1; // 通过循环将读入的Word文件的内容输出到浏览器中 while ((bytesToRead = fin.read(buffer)) != -1) { out.write(buffer, 0, bytesToRead); } } finally { if (fin != null) { fin.close(); } if (out != null) { out.flush(); out.close(); } if (file != null) { file.delete(); // 删除临时文件 } } } /** * 下载批量word文件到一个rar压缩文件中去 * @param request 请求 * @param response 响应 * @param mapList 存放多个word文件的信息:fileName:文件名(不需要带后缀的)、templateName:模板名称、assessResul:数据结果信息的集合 * @param resultRarFileName 最终下载的压缩文件名称 * @param resultFileType 最终下载的压缩文件格式 * @throws IOException */ public static void exportMillCertificateWordZip(HttpServletRequest request, HttpServletResponse response, List<Map<String, Object>> mapList,String resultRarFileName,String resultFileType) throws IOException { File[] docTempleFiles = new File[mapList.size()]; String[] docTempleFileName = new String[mapList.size()]; ZipOutputStream zipOutputStream = null; try { //遍历结果数据集合,将word模板生成的文件保存在临时文件夹中,文件记录在数组中; for(int i = 0; i < mapList.size(); i++) { String templateName = mapList.get(i).get("templateName").toString(); if(StringUtil.isNotEmpty(templateName)) { File docFile = new File(templateFolder+UUID.randomUUID().toString()+".doc"); // 创建 FileInputStream 对象 String fileName = mapList.get(i).get("fileName").toString(); ProvinceCityResultOneVO resultOneVO = (ProvinceCityResultOneVO)mapList.get(i).get("assessResul"); Map<String, Object> resultOneVOMap = new HashMap<String, Object>(); resultOneVOMap.put("assessResul", resultOneVO); // 调用工具类的createDoc方法生成Word文档 Template freemarkerTemplate = configuration.getTemplate(templateName); docFile = createZipDoc(resultOneVOMap, freemarkerTemplate,docFile); //将doc文件放到数组中去 docTempleFiles[i] = docFile; //将doc文件中文名称放到文件名数组中去 docTempleFileName[i] = fileName; } } //根据不同浏览器,对fileName进行不同的编码 String userAgent = request.getHeader("user-agent").toLowerCase(); if (userAgent.contains("msie") || userAgent.contains("like gecko") ) { // win10 ie edge 浏览器 和其他系统的ie resultRarFileName = URLEncoder.encode(resultRarFileName, "UTF-8"); } else { // fe resultRarFileName = new String(resultRarFileName.getBytes("utf-8"), "iso-8859-1"); } response.setCharacterEncoding("utf-8"); response.setContentType("application/octet-stream"); // 设置浏览器以下载的方式处理该文件名 resultRarFileName = resultRarFileName+"."+resultFileType; response.setHeader("Content-Disposition", "attachment;filename="+resultRarFileName); zipOutputStream = new ZipOutputStream(response.getOutputStream()); //遍历文件数组,将文件压缩到zip格式的压缩文件中去, for(int i = 0; i < docTempleFiles.length; i++) { File docFile = docTempleFiles[i]; FileInputStream fileInputStream = new FileInputStream(docFile); ZipEntry entry = new ZipEntry(docTempleFileName[i]+".doc"); zipOutputStream.putNextEntry(entry); int len = -1; byte[] buffer = new byte[1024]; while ((len = fileInputStream.read(buffer)) != -1) { zipOutputStream.write(buffer, 0, len); } zipOutputStream.closeEntry(); fileInputStream.close(); } zipOutputStream.flush(); } finally { if (zipOutputStream != null) { zipOutputStream.flush(); zipOutputStream.close(); } for(int i = 0; i < docTempleFiles.length; i++) { docTempleFiles[i].delete();//删除临时doc文件 } } } private static File createDoc(Map<String, Object> dataMap, Template template) { String name = "test.doc"; File f = new File(name); Template t = template; try { // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); t.process(dataMap, w); w.close(); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } return f; } private static File createZipDoc(Map<String, Object> dataMap, Template template,File f) { Template t = template; try { // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); t.process(dataMap, w); w.close(); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } return f; } }