使用FreeMarker自定义导出word

根据网上的资料和自己在实践过程中整理总结一下用freemarker自定义导出word模板

1. 首先准备好一个Word模板

如图所示,我定义了一个很简单的模板,然后将所需变量用${}副号定义,例:${username},如图所示

定义模板

说明:这里填写变量的时候需要按照顺序${username}来填写,如果先填写了${}再写username的话,word转成xml文件时会出现问题,如图所示

注意变量书写顺序

2.定义好变量以后将Word另存为XML文件

将word文档另存为xml文件,如图所示

转存XML

说明:网上有些人说选择Word XML文档时会有问题,还没验证过,所以这里选择的是Word 2003 XML

3.编辑打开XML文件

我这里选用Notepad++来打开的,如图所示

格式化后的文件

说明:刚转换完后,如果Notepad++没有安装XML格式化插件的话,打开的会是横着排列的一行,建议用Notepad++自带的插件浏览器下载XML插件,如图所示
下载方法:插件–>Plugin Manager–>Show Plugin Manager–>Available–>XML Tools–>Install
使用方法:插件–>XML Tools–>Pretty print(XML only - with line breaks)

未格式化的文件
下载格式化工具
使用方法

4.编辑XML文件,另存为ftl文件

如果需要遍历出多行数据,则需要在<w:tr>前加上list遍历,例:<#list newsList as listKey>这里的newsList只是一个变量名称,里面的变量则需要listKey.username,后台其实就是用的Map<String,List>,具体语法可参照
https://www.baidu.com/link?url=HsppryccH7jtBxyb-VOyQXOHAHlK0faxVuGUK8JBho2L6uKabgCltmsXXNTO_rahbx227tzAsfqu8m2PizwOsq&wd=&eqid=eb38bc4c000014650000000658ae53d5

这里的结构不难看出<w:tr>为一行,<w:tc>为一列,所以在<w:tr>前后对应的位置加上<#list>标签即可,编辑完后,将文件名称直接修改为.ftl文件即可,例如图所示

编辑XML文件

说明: 注意freemarker以及XML的语法结构

5.后台工具类编写

这里用的是java语言来编写的,附上源代码

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

import org.apache.log4j.Logger;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * @ClassName: WordUtil
 * @Description: word模板
 * @author sly.shuai
 * @date2017年2月22日 上午9:55:35
 * @version V1.0
 */
@SuppressWarnings("rawtypes")
public class WordUtil
{
    private final static Logger logger = Logger.getLogger(WordUtil.class);

    /**
     * @Title: createWord
     * @Description: 创建word
     * @param dataMap
     *        word中展示的动态数据,用Map存储
     * @param templatePath
     *        模板存储路径
     * @param templateName
     *        模板名字
     * @param filePath
     *        生成word文件路径
     * @param fileName
     *        生成word文件名字 void
     * @throws
     * @变更记录 2017年2月22日 上午10:13:25 sly.shuai 创建
     */
    public static void createWord(Map dataMap, String templatePath, String templateName, String filePath,
        String fileName) {
        Writer out = null;
        try {
            // 创建配置实例
            Configuration configuration = new Configuration();

            // 设置编码
            configuration.setDefaultEncoding("UTF-8");

            // ftl模板文件
            configuration.setDirectoryForTemplateLoading(new File(templatePath));

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

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

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

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

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

        } catch (Exception e) {
            logger.error("创建word出错:" + e);
            throw new RuntimeException("创建word出错");
        } finally {
            try {
                if (out != null) {
                    // 关闭流
                    out.flush();
                    out.close();
                }
            } catch (Exception e) {
                logger.error("创建word出错:" + e);
            }
        }
    }
}


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Ignore;
import org.junit.Test;

import com.yihuacomputer.yhcloud.service.util.WordPropertyUtil;
import com.yihuacomputer.yhcloud.service.util.WordUtil;

/**
 * @ClassName: WordTest
 * @Description: word导出测试
 * @author sly.shuai
 * @date2017年2月22日 上午10:35:32
 * @version V1.0
 */
public class WordTest extends BaseSpringJunit
{
    @Test
    public void createWord() {
        Map<String, Object> dataMap = new HashMap<String, Object>();

        List<Map<String, Object>> newsList = new ArrayList<Map<String, Object>>();
        for (int i = 1; i <= 10; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("username", "用户名" + i);
            map.put("password", "密码" + (i * 2));
            map.put("phone", "电话" + (i * 3));
            newsList.add(map);
        }
        dataMap.put("newsList", newsList);

        WordUtil.createWord(dataMap, "/word/templatePath/", "test.ftl", "/word/filePath/", "test.doc");
    }
}

运行结果

说明:这里只是提供了一个公用工具类,dataMap是传入的数据,用Map封装List,运行测试用例即可在相应的目录下找到对应的文件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值