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;
    }
}

 

posted @ 2018-12-25 14:52  lsyBlog  阅读(...)  评论(...编辑  收藏