美文网首页
后台根据freemarker模板生成word文档

后台根据freemarker模板生成word文档

作者: 帅气滴糟老头 | 来源:发表于2019-06-27 15:02 被阅读0次

项目中做到了一个动态生成word文档的需求,在这简单做下记录。


首先准备好要生成的world模板,设计好排版和内容,如下


将需要动态替换的内容用占位符代替,图片暂不处理,如下


然后将该word文档另存为Word 2003 XML 文档(*.xml),如下


然后用编辑器打开wordTemplate.xml,建议用现代编辑器如Sublime,方便对xml内容进行格式化,我是直接将其放入idea的springboot项目的resources目录下的template文件夹下进行编辑
可以看到原先word文档中的图片转为xml后变成了base64编码的字符串,如下


我们将base64字符串用占位符${picture}替换,如下

然后我们检查其他占位符显示是否正常,如下面这种情况就是不正常的,需要将{}中多余的东西删除

编辑完成后将wordTemplate.xml改名为wordTemplate.ftl

模板有了,最后要做的就是生成word文档的代码实现,
首先需要在pom.xml文件中引入freemarker的依赖,如下

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.20</version>
</dependency>

下面是详细的代码实现

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 根据ftl模板生成word文档工具类
 * @Author along
 * @Date 2019/6/21 13:32
 */
public class ExportDocUtil {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private Configuration configuration;
    private String encoding;
    private Map<String, Object> dataMap;

    /**
     * 构造函数
     * @param dataMap 填充数据
     * @param encoding 编码
     * @param ftlPath ftl模板文件路径
     */
    public ExportDocUtil(Map<String, Object> dataMap, String encoding, String ftlPath) {
        this.dataMap = dataMap;
        this.encoding = encoding;
        configuration = new Configuration();
        configuration.setDefaultEncoding(encoding);
        configuration.setClassForTemplateLoading(this.getClass(), ftlPath);
    }

    private Template getTemplate(String ftlName) throws Exception {
        return configuration.getTemplate(ftlName);
    }

    private static String getImageStr(String image) throws IOException {
        InputStream is = new FileInputStream(image);
        BASE64Encoder encoder = new BASE64Encoder();
        byte[] data = new byte[is.available()];
        is.read(data);
        is.close();
        return encoder.encode(data);
    }

    private static Map<String, Object> getDataMap() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("title", "world标题");
        dataMap.put("name", "along");
        dataMap.put("age", "12");
        dataMap.put("address", "地球");
        try {
            dataMap.put("picture", getImageStr("D:\\图片1.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataMap;
    }

    /**
     * 执行方法
     * @param doc 生成word文件保存路径,包括文件名
     * @param ftlName ftl模板文件名
     * @return
     * @throws Exception
     */
    public boolean exportDoc(String doc, String ftlName) throws Exception {
        Writer writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(doc), encoding));
            getTemplate(ftlName).process(dataMap, writer);
            logger.info("word创建完成>>>>>>>>>>");
            return true;
        } catch (Exception e) {
            logger.error("", e);
        }
        if (writer != null) {
            writer.flush();
            writer.close();
        }

        return false;

    }

    // 测试
    public static void main(String[] args) throws Exception {
        ExportDocUtil maker = new ExportDocUtil(getDataMap(), "UTF-8", "/template");
        String orderId = getDataMap().get("title").toString();
        maker.exportDoc("D:\\" + orderId + ".doc", "wordTemplate.ftl");
    }
}

执行main方法,在对应的D:\目录下找到world标题.doc,打开内容如下

参考文章:
https://www.cnblogs.com/lichmama/p/6652161.html

相关文章

网友评论

      本文标题:后台根据freemarker模板生成word文档

      本文链接:https://www.haomeiwen.com/subject/yktrcctx.html