使用freemarker导出word文档

通过freemarker,以及JAVA,导出word文档。

共分为三步:

  第一步:创建模板文件

  第二步:通过JAVA创建返回值。

  第三步:执行

分别介绍如下:

第一步:

首先创建word文档,按照想要的格式写好模板,需要替换的位置,使用 ${}  占位,其{}中放入名称,以便执行代码时使用。

例子如下

分享图片

这个模板只要是报告的格式,包括报告名称,报告时间,报告人。下边的是编号和标题,以及内容。因为标题和内容方面可能存在多个,在后边可以循环输出。

制作完成之后,将该文档另存为xml格式。(注意:尽量选择2003版本的xml,否则可能出现文档太大打不开的问题。)

另存为xml之后,需要对其做简单的修改以便于循环输出。

我使用的结果为Map嵌套的,所以输出的循环语句为

<#assign num= 0>
<#list kejis?keys as key>  //kejis为接收map的键。
<#assign num = num+1>

  ${num}${kejis[key].title}    //在这需要找到文档中中对应位置做相应修改。

</#list>

也可以使用list集合输出。

修改完成之后将文件后缀修改为ftl格式。备用

第二步:

1.首先准备工具类,导出用,类中的方法共四个参数,按顺序为   传递的值(Map类型),模板文件,生成word存储路径,生成文件名

package Util;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.Locale;
import java.util.Map;
public class WordUtil {
    public static void createWord(Map dataMap, String templateName, String filePath, String fileName){
        try {
            //创建配置实例
            Configuration configuration = new Configuration();

            //设置编码
            configuration.setDefaultEncoding("UTF-8");
            configuration.setEncoding(Locale.getDefault(), "utf-8");
            //ftl模板文件统一放至 com.lun.template 包下面
            configuration.setClassForTemplateLoading(WordUtil.class,"/");

            //获取模板
            Template template = configuration.getTemplate(templateName);

            //输出文件
            File outFile = new File(filePath+File.separator+fileName);

            //如果输出目标文件夹不存在,则创建
            if (!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
            }

            //将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));


            //生成文件
            template.process(dataMap, out);

            //关闭流
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

2.准备返回值及调用

public static void main(String[] args) {
        Map<String, Object> map = new HashMap<String, Object>(); 
        map.put("time", "2019-4-1");
        map.put("name", "报告名称");
        map.put("bgname", "wys");
        Map<String, Object> kejis=new HashMap<String, Object>(); 
        for(int i=0;i<10;i++) {
            Wordout wordout=new Wordout();
            wordout.setTitle("标题"+i);
            wordout.setContent("内容"+i);
            kejis.put(""+i, wordout);  //注意此处的第一个参数应保持每次put都是不同的
        }
        map.put("kejis", kejis);
        String filePath = "D:\\policy\\" ;
        String filename = "bk.doc";
        WordUtil.createWord(map, "bk.ftl", filePath, filename);    
        
    }

第三步:执行上边代用主函数的代码生成word成功,结果如下

分享图片

 

以上便完成了word文档导出。

总结:

  经过多次尝试,导出的word文档大小和xml文件的大小成正比的,所以在xml文件加循环的时候,应该尽量减少循环中的内容,以减小文件的大小,否则,生成的文件会太大导致打开太慢,或者无法打开的问题。

  并且另存为xml文件的时候,选择2003版本为宜,因为经过测试,相同的word模板,另存为两种不同xml大小不同,2003版本的较小,所以选择该版本。

  假如想入输出带有格式的word,只需要将占位符修改为相应格式即可。字体格式,大小,颜色等属性都会继承过去。

附:

  这是经常用到的freemarker的语法

  1.if语句(判断是否为空)  

  <#if      target?? >  

    此处为if为true的内容

  </#if>

  2.list循环(map循环上文使用过了)

  <#list list as t>

    ${t.title}

  </#list>

  如果想实现多层嵌套,只需要将返回值也嵌套进去,xml文件也相应的嵌套即可。

这是我首次使用freemarker的过程,如有错误,望指正,我及时修改
相关文章
相关标签/搜索