freemarker模板导出带表格word详细教程

发布于:2023-04-27 ⋅ 阅读:(486) ⋅ 点赞:(0)

           前言:另外一篇是手机端的word导出,需要兼容性,不然在安卓手机会乱码

freemarker模板导出word循环图片表格详细教程_Java大表哥的博客-CSDN博客  并且另存为模版格式不同数据绑定方式不同

           一。整体环境:

                             开发环境:java,eclipse

           部署环境:tomcat7/jar包两种方式

二。功能需求:(数据需要导出成以下格式)

  1.简单一点的文本类:

2.复杂一点的

三。准备工作:

先准备好Freemarker模版:步骤如下:

1.我们需要做的就是把需要导出到word的数据 使用${}替换下(这就相当于占位符)如图;

把需要导出的内容用占位符替换下

2.表格的:

3.改好之后把word另存为xml,然后通过在线的xml格式化通过notepad++打开,修改好格式:

(1).普通文本

这里截取一小部分

(2).表格的话需要在<w:tbl>标签内<w:tr>加上list标签,用来接收后面后端的数据:

加入list标签

list结束标签

 序号并不是写死的,直接用<w:t>${zjl_index+1}</w:t>替换,(因为默认为0,所以加1)

 最后把后缀改成.ftl就好了,过程:.word>.xml>.ftl。

四。开始后端编码

人狠话不多,直接贴编码:

1.controller层编码:

    加载模版方法freemarker加载模板目录的方法_Java大表哥的博客-CSDN博客

@RequestMapping(value = { "wordExportBySb" }, method = { RequestMethod.GET, RequestMethod.POST })
    @ResponseBody
    public void wordExportBySb(HttpServletRequest req, HttpServletResponse resp, String bgId) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
        /** 初始化配置文件 **/
        @SuppressWarnings("deprecation")
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        /** 加载模板 **/
        //这个方法在eclipse跑是OK 的 打jar包部署获取不到模版
        /*File file = ResourceUtils.getFile("classpath:templates");
        configuration.setDirectoryForTemplateLoading(file);*/
        
        //      这个方法在eclipse跑和打jar包部署都可以获取到模版
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
        Template template = configuration.getTemplate("研判报告上报模板.ftl");
        XsCp xsCp = xsCpService.selectByPrimaryKey(bgId);//这里是我获取的业务对象
        Map<String, Object> dataMap = new HashMap<>();

    // ** 在ftl文件中有${bt}这个标签**//*
 
   // Freemarder 数据必须不能为null
            dataMap.put("bt", xsCp.getBt());   
            dataMap.put("sjdw", xsCp.getCjdw() == null ? "" : exportWordUtils.convertSjdw(xsCp.getCjdw()));
            dataMap.put("cpms", xsCp.getBgms() == null ? "" : xsCp.getBgms());
            dataMap.put("jyaq", xsCp.getJyaq() == null ? "" : xsCp.getJyaq());
            //资金流转换
            String ypZjl = xsCp.getYpZjl();
             List<WordStreamVoBean> disposeZjlList = exportWordUtils.disposeZjl(ypZjl);//获取到list
             if(disposeZjlList != null){

//循环获取到所有的数据
                    for (int i = 0; i < disposeZjlList.size(); i++) {
                        if ((disposeZjlList.get(i)).getBh() == null) {
                            disposeZjlList.get(i).setBh("");
                        }
                        if (disposeZjlList.get(i).getData() == null) {
                            disposeZjlList.get(i).setData("");
                        }    
                    } 
             }

 //添加资金流list:
            dataMap.put("ypZjl", disposeZjlList);
            
            //网络流转换
            String ypWll= xsCp.getYpWll();
             List<?> disposeWllList = exportWordUtils.disposeWll(ypWll);
             if(disposeWllList != null){
                    for (int i = 0; i < disposeZjlList.size(); i++) {
                        if ((disposeZjlList.get(i)).getBh() == null) {
                            disposeZjlList.get(i).setBh("");
                        }
                        if (disposeZjlList.get(i).getData() == null) {
                            disposeZjlList.get(i).setData("");
                        }    
                    } 
             }
            dataMap.put("ypWll", disposeWllList);
            
            //通讯流转换
            String ypTxl= xsCp.getYpTxl();
             List<WordStreamVoBean> disposeTxlList= exportWordUtils.disposeZjl(ypTxl);
             if(disposeTxlList != null){
                    for (int i = 0; i < disposeTxlList.size(); i++) {
                        if ((disposeTxlList.get(i)).getBh() == null) {
                            disposeTxlList.get(i).setBh("");
                        }
                        if (disposeTxlList.get(i).getData() == null) {
                            disposeTxlList.get(i).setData("");
                        }    
                    } 
             }
            dataMap.put("ypTxl", disposeTxlList);
            dataMap.put("ryList", ryList);
//..........其他业务和字段
            dataMap.put("xybgz", xsCp.getXybgz() == null ? "" : xsCp.getXybgz());

//开始word导出:导出我没有写死导出到什么磁盘,是通过浏览器输出随意存放修改。
            ServletOutputStream out = null;
            String fileName = bt + ".doc";
            try {

//utils里创建word的方法:后面会给出代码
                File wordFile = ExportWordUtils.createDoc(dataMap, template);
                fin = new FileInputStream(wordFile);
                resp.setCharacterEncoding("utf-8");
                resp.setContentType("application/msword");
                resp.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
                out = resp.getOutputStream();

                byte[] buffer = new byte[1024];// 缓冲区
                int bytesToRead = -1;
                // 通过循环将读入的Word文件的内容输出到浏览器中
                while ((bytesToRead = fin.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (fin != null)
                    fin.close();
                if (out != null)
                    out.close();
         }

2.utils类方法:

  public static File createDoc(Map<?,?> dataMap,Template template){
                 File f = new File("");
                 try{
                     //这个地方不能使用FileWriter因为需要指定编码类型否则生成的word文档会因为有无法识别的编码而无法打开
                     Writer w = new OutputStreamWriter(new FileOutputStream(f),"utf-8");
                     template.process(dataMap,w);
                     w.close();
                 }catch(Exception e){
                     e.printStackTrace();
                     throw new RuntimeException(e);
                 }
                     return f;
            }

大功告成,打完收工,尼玛,花了我一周时间搞定,特别是改模版真烦人,一丢丢的样式都要改。

五。总结:

需要注意的细节挺多的,刚开始做的时候肯定很多坑,数据不能为空,初始化模版方法,数据转换等。

六:案例demo程序下载

freemarker模板导出word循环图片表格源码和详细教程-Java文档类资源-CSDN下载

请看使用必看


网站公告

今日签到

点亮在社区的每一天
去签到