文章目录
一.定义
模版引擎是一种用于生成动态内容的类库/框架,将预先定义的模板与特定数据合并,来生成最终的输出内容.
二.优点
1.使用模板引擎有很多的优点,首先就是提供现成的模板文件语法和解析能力。开发者只要按照特定要求去编写模板文件,比如使用 ${参数} 语法,模板引擎就能自动将参数注入到模板中,得到完整文件,不用再自己编写解析逻辑了。
2.模板引擎可以将数据和模板分离,让不同的开发人员独立工作。比如后端专心开发业务逻辑提供数据,前端专心写模板等,让系统更易于维护。此外,模板引擎可能还具有一些安全特性,比如防止跨站脚本攻击等。所以强烈大家掌握至少一种模板引警的用法
三.作用
模板引擎的作用就是接收模板和java对象,对它们进行处理,输出完整的内容。
四.核心概念
1.模板
模板文件由 4 个核心部分组成
1.1.文本
固定的内容,会按原样输出
1.2.插值
用${...}语法来占位,括号中的内容在经过计算和替换后,才会输出。
1.3.FTL 指令
有点像 HTML 的标签语法,通过<#xxx ...>来实现各种特殊功能。比如 <#list elements as element> 实现循环输出
1,4.注释
和 HTML注释类似,使用 <#-- ... --> 语法,注释中的内容不会输出
模拟的模版文件
2.数据模型
我们把为模板准备的所有数据整体统称为数据模型,在 FreeMarker中,数据模型一般是树形结构,可以是复杂的 Java 对象、也可以是HashMap 等更通用的结构。
五、应用场景
1.生成复杂格式的Excel文件
1.定义Excel文件模版
2. 将Excel文件另存为xml格式的数据
3.通过idea或者其他工具打开xml文件,进行FTL指令编写,并格式化
比如遍历列表
4.修改行的扩展值,一般用于遍历回显列表的场景下,大于预估的列表行数,或者设置变量
<Table ss:ExpandedColumnCount="4"ss:ExpandedRowCount="2"x:FullColumns=“1”
5.将xml格式文件重命名为freemarker模板文件:xx.ftl,保存到resources目录下
6.定义数据模型
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InvoiceItem {
// 编号
private String itemNumber;
// 名称及规格
private String itemNameAndSpecs;
// 单位
private String unit;
// 数量
private int quantity;
// 单价
private BigDecimal unitPrice;
// 金额
private BigDecimal amount;
// 备注
private String comments;
}
7. 组合并输出内容
package com.example.demo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
public class FreeMarkerTest {
public static void main(String[] args) throws Exception {
// 1. FreeMarker 初始化配置
Configuration configuration = new Configuration(Configuration.VERSION_2_3_26);
configuration.setDefaultEncoding("UTF-8");
configuration.setClassForTemplateLoading(FreeMarkerTest.class, "/templates/");
// 2. 获取模板
Template template = configuration.getTemplate("myReport.ftl");
// 3. 准备模板数据
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("invoice", obj);
// 4. 导出文件
File outFile = new File("C:/Users/Desktop/test.xml");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
template.process(dataMap, writer);
writer.flush();
writer.close();
System.out.println("导出文件完毕...");
}
}
2.生成PDF文档
方法同上
3.生成通用代码-entity、dao、service
- 定义实体类模版
<#-- Java 实体模板 -->
import lombok.Data;
/**
* ${classComment}
*/
@Data
public class ${className} implements Serializable {
<#-- 序列化 -->
private static final long serialVersionUID = 1L;
<#-- 循环生成字段 ---------->
<#list fieldList as field>
<#if field.comment!?length gt 0>
/**
* ${field.comment}
*/
</#if>
private ${field.javaType} ${field.fieldName};
</#list>
}
- 定义数据模型
package com.yupi.sqlfather.core.model.dto;
import java.util.List;
import lombok.Data;
/**
* Java 实体生成封装类
*
* @author wzh
*/
@Data
public class JavaEntityGenerateDTO {
/**
* 类名
*/
private String className;
/**
* 类注释
*/
private String classComment;
/**
* 列信息列表
*/
private List<FieldDTO> fieldList;
/**
* 列信息
*/
@Data
public static class FieldDTO {
/**
* 字段名
*/
private String fieldName;
/**
* Java 类型
*/
private String javaType;
/**
* 注释(字段中文名)
*/
private String comment;
}
}
- 为数据模型赋值
JavaEntityGenerateDTO javaEntityGenerateDTO = new JavaEntityGenerateDTO();
javaEntityGenerateDTO.setClassName("Test");
javaEntityGenerateDTO.setClassComment("测试");
List<FieldDTO> fieldList = new ArrayList<>();
FieldDTO field = new FieldDTO();
field.setComment("字段注释");
field.setJavaType("String");
field.setFieldName("testFieldName");
fieldList.add(field);
javaEntityGenerateDTO.setFieldList(fieldList);
- 组装模版与模型,输出最终内容
Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);
cfg.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
cfg.setDefaultEncoding("UTF-8");
StringWriter stringWriter = new StringWriter();
Template temp = cfg.getTemplate("java_entity.ftl");
temp.process(javaEntityGenerateDTO, stringWriter);
System.out.println(stringWriter);
// 输出实体类
import lombok.Data;
/**
* 测试
*/
@Data
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 字段注释
*/
private String testFieldName;
}