freemarker生成word模板

一、引入依赖

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

二、工具类

注意:Configuration configuration的属性,在某些情况下会出现文件文法打开的情况就是因为参数不对。

package com.dameng.util;

import com.dameng.domain.FreemarkerDemo;
import freemarker.cache.ClassTemplateLoader;
import freemarker.core.XMLOutputFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.Map;

/**
 * Word文档工具类
 */
public class WordUtil {

    /**
     * 使用FreeMarker自动生成Word文档
     * @param dataMap   生成Word文档所需要的数据
     * @param fileName  生成Word文档的全路径名称
     */
    public static void generateWord(Map<String, Object> dataMap, String fileName) throws Exception {
        // 设置FreeMarker的版本和编码格式
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_27);
        configuration.setEncoding(Locale.getDefault(),"UTF-8");
        configuration.setDefaultEncoding("UTF-8");
        configuration.setOutputFormat(XMLOutputFormat.INSTANCE);

        //设置异常处理器 这样的话 即使没有属性也不会出错 如:${list.name}...不会报错
        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
//        // 设置FreeMarker生成Word文档所需要的模板的路径
        configuration.setTemplateLoader(new ClassTemplateLoader(FreemarkerDemo.class,"/templates/"));
        // 设置FreeMarker生成Word文档所需要的模板
        ///Template t = configuration.getTemplate("check_freework202202262238.ftl");
        Template t = configuration.getTemplate("check_freework202203061.ftl");
        // 创建一个Word文档的输出流
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(fileName)), "UTF-8"));
        //FreeMarker使用Word模板和数据生成Word文档

        t.process(dataMap, out);
        out.flush();
        out.close();
    }

}

三、实体类

package com.dameng.domain;
 
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
 
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
 
public class FreemarkerDemo {
 
    public static void main(String[] args) throws IOException, TemplateException {
        /*初始化freemarker模板*/
        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        configuration.setDefaultEncoding(Charset.forName("UTF-8").name());
 
        //这里的ClassTemplateLoader 的basePackagePath  如果是 / 开头就是绝对路径。如果不是/ 开头就是相对于
        //com.saoft.fastdemo.gen.FreemarkerDemo.java 这个类的相对路径,会以com.saoft.fastdemo.gen这个目录开始找
        //FileTemplateLoader
        configuration.setTemplateLoader(new ClassTemplateLoader(FreemarkerDemo.class,"/templates/"));
 
        //获取模板
        Template template = configuration.getTemplate("ssm/demo.ftl");
 
        //需要注入的数据
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("testKey", "This is key");
 
        //输出位置 这里用字符串输出,如果要输出文件自行替换
        StringWriter writer = new StringWriter();
        template.process(dataMap, writer);
 
        System.out.println(writer.getBuffer());
    }
}

四、main方法

public static void main(String[] args)  {
                 Map<String, Object> wordDataMap = getWordData(dataSource,systemInfo);
                //输出概述的信息
                wordDataMap.put("systemInfo",systemInfo);
                wordDataMap.put("dbSummaryInfo",dbSummaryInfo);
                WordUtil.generateWord(wordDataMap,generateFileName);
 }

注意:FreemarkerDemo 类有指定模板的位置。

freemarker模板制作 freemarker word模板_数据库

五、docx文档的选项

freemarker模板制作 freemarker word模板_java_02

六、踩坑

6.1 特殊符号

使用FreeMarker模板生成Word文档时,如果填充的数据字符串中含有特殊字符< 、>、&,那么生成的Word文档是无法打开的。因为这些字符在生成Word文档时被认为是FreeMarker模板的标签,如果这些字符不经过处理就直接用于生成Word文档,使用Word打开生成的文档就会报错,但以xml的方式打开,却会发现所有内容都是完整的,唯独上面三个特殊字符出问题。因此,在处理数据时需要对这三个特殊字符进行处理。

6.2 换行符

使用FreeMarker模板生成Word文档时,如果填充的数据字符串过长且当中使用"\n"进行换行,则生成的Word文档中并没有起到换行的作用。需要先将"\n"全部替换成"<w:p></w:p>",然后使用替换后的字符串数据生成Word文档,才能达到换行的效果。

6.3 内容是xml格式

使用本文方法生成的Word文档的内容实质上是xml格式的,因此,生成的Word文档即可以使用Word打开,也可以使用xml文档工具打开。如果使用Java程序去读取生成的Word文档的内容,则读出来的也是xml格式的内容。如果想要将内容转换成Word格式,则可以使用Word打开生成的文档然后另存为Word文档格式。

6.4 后缀是.doc

使用本文方法生成的Word文档的后缀必须是.doc格式,而不能是.docx格式,否则生成的Word文档无法打开。如果想要将后缀转换成.docx格式,则可以使用Word打开生成的文档然后另存为Word文档格式。

6.5生成xml打开加密格式

这是因为notepad++缺少xml的插件,所以打开就是加密的。使用记事本打开或者放到IDEA中打开

freemarker模板制作 freemarker word模板_java_03

资料