利用freemarker模板导出单个word及多word压缩导出到浏览器下载

1、后端代码

@RequestMapping(value = { "wordMultipleExport" }, method = {RequestMethod.POST})
	public Result createMultipleWord(@RequestBody Map params,HttpServletRequest request,HttpServletResponse response)throws Exception {
		String fileName = params.get("fileName").toString();
		List> templateNameList = (List>) params.get("templateNameList");
		Map data = (Map) 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 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> mapList,Map 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 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 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;
	    }
}

 

你可能感兴趣的:(前端js,开发笔记,java)