Java-Freemarker替换模板文件.ftl中的变量,生成Word文档(docx,xls)

一、前言

前有java-poi替换模板文件word文档中的变量,生成Word文档,后有Java-Freemarker替换模板文件.ftl中的变量,生成Word文档。

Freemarker是如今最流行的文档处理组件,poi已经相对过时了。

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据,简单点就是替换模板中的变量, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

相关jar包、以及maven配置、或者gradle配置等等都可以去这个网站找到:mvn仓库

 

二、使用

1、根据需求创建word文档,下图是我想要的word,但是一些值是用了${变量名} 来代替。

2、把word另存为xml,不要直接修改尾缀,用word的另存为:

选择xml格式:

保存成xml之后,直接修改模板文件尾缀,把 xml 修改为 ftl 。然后便是检查变量名是否被word的一些标签隔离开了,如果${变量名}不是完整的,就要把那些多余的标签的删掉,并不会影响最后文档显示的格式,不然会报找不到对应的变量exception,如下图:

3、模板已经制作完毕,我把模板放在了  C:\image\freemarker.ftl   路径。然后便是java部分了:

package demo.freemarker_demo;
 
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
 
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
/**
 * @author
 * @description freemarker工具
 * @date 2021-01-14
 */
public class FreemarkerDemo {
 
    public static void test(String path){
        Map<String,Object> dataMap = new HashMap<>();
        try {
            dataMap.put("name", "张三");
            dataMap.put("idnumber", "411322199308302019");
            dataMap.put("result1", "□");
            dataMap.put("result2", (char)8730);// (char)8730 对号
            dataMap.put("result3", "□");
            dataMap.put("result4", "□");
            dataMap.put("result5", "□");
            dataMap.put("date", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
            dataMap.put("ipAddress", "110.0.0.1");
            dataMap.put("confirmedBy", "xch");
            dataMap.put("ipAddress", "110.0.0.1");
            dataMap.put("datetime", new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()));
 
            Configuration configuration = new Configuration(new Version("2.3.0"));
            configuration.setDefaultEncoding("utf-8");
 
            //.ftl配置文件所在路径
            //第一种使用相对一个java文件的相对路径
//          configuration.setClassForTemplateLoading(new FreemarkerDemo().getClass(), "/doc/");
 
            //第二种使用绝对路径
            configuration.setDirectoryForTemplateLoading(new File("c:/image/"));
 
            //第三种使用web项目的ServletContext路径
//          configuration.setServletContextForTemplateLoading(null, "/doc/");
 
            //以utf-8的编码读取ftl模板文件
            Template template = configuration.getTemplate("freemarker.ftl", "utf-8");
 
            //输出文档路径及名称
            File outFile = new File(path);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), 
                    "utf-8"), 10240);
            template.process(dataMap, out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        String path = "C:\\image\\doc\\"+System.currentTimeMillis()+".doc";
        test(path);
 
    }
}


是不是很简单,关键代码只有两处,找到模板.ftl,然后用模板template的方法process(),把入参map和输出文件解析出来。map的key就是模板中的${变量值},匹配之后便是替换,然后便是生成最终的文档:

 

注意三点,我使用时遇到的注意点:

1:上面的红字,在由word转到ftl的过程中,一定要核对${变量名} 是否被一些标签拆分开了,那么便会报解析异常:

freemarker.core.ParseException: Syntax error in template "freemarker.ftl"

2:我如果最终导出的word文件尾缀.doc,改为.docx,程序无异常,但是最终的文件就是报:无法打开......:

3:(char)8730 是java中的对勾/对号,别看这个对号,我再网上找了好久。

 

 

注意问题:freemaker模板位置ClassTemplateLoader的绝对路径相对路径设置方法

在freemarker中加载模板有两种方式

FileTemplateLoader和ClassTemplateLoader
FileTemplateLoader用于加载文件目录的模板

ClassTemplateLoader用于加载工程目录内的模板

加载resources下面的模板需要用ClassTemplateLoader

注意:ClassTemplateLoader(FreemarkerDemo.class,"/templates/") 这种是绝对路径。

ClassTemplateLoader(FreemarkerDemo.class,"templates/") 这种是相对路径,会以该类所在目录位置开始找模板
 

下面代码使用的是绝对路径

package com.saoft.fastdemo.gen;
 
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());
    }
}

 

目录结构


 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeMarker 是一个Java模板引擎,它可以帮助我们根据模板生成各种文件,包括 Word 文档。下面是一个简单的示例,演示如何使用 FreeMarker 创建一个根据 FTL 模板生成 Word 文档的过程: 1. 创建一个 FreeMarker 的配置对象,并设置模板文件所在的目录: ``` Configuration cfg = new Configuration(Configuration.VERSION_2_3_30); cfg.setDirectoryForTemplateLoading(new File("path/to/ftl/templates")); ``` 2. 从配置对象获取模板对象: ``` Template template = cfg.getTemplate("template.ftl"); ``` 3. 准备数据模型,可以是一个 JavaBean、Map 或者其他类型的对象: ``` Map<String, Object> data = new HashMap<>(); data.put("title", "Hello, World!"); data.put("content", "This is a test document created by FreeMarker."); ``` 4. 创建一个 Writer 对象,用于输出生成的 Word 文档: ``` Writer out = new FileWriter(new File("path/to/output/doc.docx")); ``` 5. 将数据模型和 Writer 对象传递给模板对象,生成 Word 文档: ``` template.process(data, out); ``` 完整的示例代码如下: ``` import freemarker.template.Configuration; import freemarker.template.Template; import java.io.File; import java.io.FileWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; public class FreeMarkerDemo { public static void main(String[] args) throws Exception { // 创建 Configuration 对象 Configuration cfg = new Configuration(Configuration.VERSION_2_3_30); cfg.setDirectoryForTemplateLoading(new File("path/to/ftl/templates")); // 获取模板对象 Template template = cfg.getTemplate("template.ftl"); // 准备数据模型 Map<String, Object> data = new HashMap<>(); data.put("title", "Hello, World!"); data.put("content", "This is a test document created by FreeMarker."); // 创建输出流 Writer out = new FileWriter(new File("path/to/output/doc.docx")); // 生成 Word 文档 template.process(data, out); // 关闭输出流 out.close(); } } ``` 注意,上面的示例代码使用的模板文件FTL 格式,如果要生成 Word 文档,还需要将模板文件转换成 docx 或者其他 Word 文档格式。常见的工具包括 Apache POI 和 Docx4j 等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值