利用freemarker模板導出單個word及多word壓縮導出到瀏覽器下載

1、後端代碼

@RequestMapping(value = { "wordMultipleExport" }, method = {RequestMethod.POST})
	public Result createMultipleWord(@RequestBody Map<String, Object> params,HttpServletRequest request,HttpServletResponse response)throws Exception {
		String fileName = params.get("fileName").toString();
		List<Map<String, Object>> templateNameList = (List<Map<String, Object>>) params.get("templateNameList");
		Map<String, Object> data = (Map<String, Object>) params.get("data");
		String msg="";
		System.err.println(fileName+"111");
		System.err.println(templateNameList+"222");
		System.err.println(data+"333");
		if (templateNameList.size()>1) {
			//多文件生成zip壓縮包
			zipUtils.exportMillCertificateWordZip(request, response, templateNameList,data, fileName, "zip");
			
		}else {
			//單文件直接生成word文檔
			try {
				zipUtils.exportMillCertificateWord(request, response, data,templateNameList.get(0).get("fileName").toString(), templateNameList.get(0).get("templateName").toString());
				msg = "生成word完畢!";
			} catch (Exception e) {
				msg = "生成word失敗!";
				e.printStackTrace();
			}
		}
	    
		return Result.error(msg);
		
	}

2.前端代碼

//導出數據
				exportData () {
	
					var params = {
						data : {
							project_name : "測試項目", //項目名稱
							construction_unit : "測試建設單位", //建設單位
							edit_date : "2020年3月16日", //編制日期
							evaluate_unit : "評價單位" //評價單位
						},
						templateNameList : [
                            {fileName:"報告1.doc",templateName:"報告1.ftl"},
						    {fileName:"報告2.doc",templateName:"報告2.ftl"},
						    {fileName:"報告3.doc",templateName:"報告3.ftl"}
							], 
							/* templateNameList : [
							"1、報告表封面(建設單位公章)--6份.ftl"
							], */
						fileName : "全部報告"
					}
					return axios({
						method : 'post',
						url : baseURL + 'api/wordMultipleExport',
						data : params,
						responseType : 'blob'
					}).then((response) => {
						// 處理返回的文件流
						const data = new Blob([ response.data ], {
							type : "application/msword"
						}); //,{type: 'application/vnd.ms-excel;charset=utf-8'}
	
						let fileName = "全部報告.zip";
						if (params.templateNameList.length == 1) {
							fileName = "全部報告.doc";
						}
						if (typeof window.chrome !== 'undefined') {
							// Chrome version
							var link = document.createElement('a');
							link.href = window.URL.createObjectURL(data);
							link.download = fileName;
							link.click();
						} else if (typeof window.navigator.msSaveBlob !== 'undefined') {
							// IE version
							var blob = new Blob([ data ], {
								type : 'application/force-download'
							});
							window.navigator.msSaveBlob(blob, fileName);
						} else {
							// Firefox version
							var file = new File([ data ], fileName, {
								type : 'application/force-download'
							});
							window.open(URL.createObjectURL(file));
						}
	
	
					}
					);
	
	
				}

工具類:

/**
 * 
 */
package shqn.hbxt.modules.environment.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 freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * @author hxl
 * @date 2020年3月16日 zipUtil.java
 */
public class zipUtils {
	
	    private static Configuration configuration = null;
	    // 這裏注意的是利用WordUtils的類加載器動態獲得模板文件的位置
	    private static final String templateFolder = zipUtils.class.getClassLoader().getResource("templates/word/").getPath();
	    
	    static {
	        configuration = new Configuration();
	        configuration.setDefaultEncoding("utf-8");
	        try {
	            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }

	    private zipUtils() {
	        throw new AssertionError();
	    }

	    /**
	     * 下載單個word文件
	     * @param request 請求
	     * @param response 響應
	     * @param map word結果數據
	     * @param fileName 結果文件名稱(不需要帶後綴的)
	     * @param templateName word模板名稱
	     * @throws IOException
	     */
	    @SuppressWarnings({ "rawtypes", "unchecked" })
	    public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map<String, Object> dataMap,String fileName,String templateName)
	            throws IOException {
	        Template freemarkerTemplate = configuration.getTemplate(templateName);
	        File file = null;
	        InputStream fin = null;
	        ServletOutputStream out = null;
	        try {
	            // 調用工具類的createDoc方法生成Word文檔
	            file = createDoc(dataMap, 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 data 數據結果信息
	     * @param resultRarFileName 最終下載的壓縮文件名稱
	     * @param resultFileType 最終下載的壓縮文件格式
	     * @throws IOException
	     */
	    public static void exportMillCertificateWordZip(HttpServletRequest request, HttpServletResponse response, List<Map<String, Object>> mapList,Map<String, Object> data,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(Utils.isNotEmpty(templateName)) {
	                    File docFile = new File(templateFolder+UUID.randomUUID().toString()+".doc");
	                    // 創建 FileInputStream 對象
	                    String fileName = mapList.get(i).get("fileName").toString();
	                    // 調用工具類的createDoc方法生成Word文檔
	                    Template freemarkerTemplate = configuration.getTemplate(templateName);
	                    docFile = createZipDoc(data, 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();
	            }
	            
	            System.err.println(docTempleFiles.length+"__________________文件數量");
	            for(int i = 0; i < docTempleFiles.length; i++) {
	            	System.err.println("刪除第"+i+"個文件");
	            	if (docTempleFiles[i] != null) {
	            		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;
	    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章