zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    Java包装类
    Java锁机制ReentrantLock
    Java内部类介绍
    JAVA多线程学习六-守护线程
    JAVA多线程学习五:线程范围内共享变量&ThreadLocal
    JAVA多线程学习四
    Maven之阿里云镜像仓库配置
    JAVA多线程学习- 三:volatile关键字
    ansible学习(二)- 清单配置详解
    Java多线程学习(二)
  • 原文地址:https://www.cnblogs.com/lsy-blogs/p/10173904.html
Copyright © 2011-2022 走看看