Freemaker基於word模板動態導出壓縮文件彙總整理html
Freemaker基於word模板動態導出單個文件思路和代碼詳情見鏈接:java
https://www.cnblogs.com/lsy-blogs/p/9243281.html數組
核心思路以下:瀏覽器
一、service中寫方法,查詢須要導出的結果list集合數據;app
二、控制層中調用service方法獲取結果集合數據,調用freemaker獲取對應的word文件到臨時目錄下;dom
三、利用流處理,將臨時目錄下導出的每個word寫入到壓縮文件中去,利用流輸出到瀏覽器中,實現壓縮文件下載;工具
四、最終將各類流關閉,並將產生的臨時word文件刪除;編碼
核心是工具類和控制層的調用,核心代碼以下:spa
控制層代碼:.net
@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; } }