说明:FreeMake可以通过设置一个模板,使用一些语法规则,可根据返回的VO数据填充到这个模板中,生成一个静态。这个技术,在项目中可以实现如预览页面的功能,将查询完成的VO数据按照这个模板填充,生成一个静态页面返回给前端就可以了。
官网说明如下:
Apache FreeMarker™ is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data. Templates are written in the FreeMarker Template Language (FTL), which is a simple, specialized language (not a full-blown programming language like PHP). Usually, a general-purpose programming language (like Java) is used to prepare the data (issue database queries, do business calculations). Then, Apache FreeMarker displays that prepared data using templates. In the template you are focusing on how to present the data, and outside the template you are focusing on what data to present.(官方语)
翻译如下:
Apache FreeMarker™ 是一个模板引擎:一个Java库,用于根据模板和不断变化的数据生成文本输出(HTML网页、电子邮件、配置文件、源代码等)。模板是用FreeMarker模板语言(FTL)编写的,这是一种简单、专业的语言(不是像PHP这样成熟的编程语言)。通常,通用编程语言(如Java)用于准备数据(发布数据库查询、进行业务计算)。然后,Apache FreeMarker使用模板显示准备好的数据。在模板中,您关注的是如何呈现数据,而在模板之外,您则关注的是要呈现什么数据。
FreeMarker简单语法
FreeMarker中常用的语法和表达式如下:
(1)插值表达式
java代码
Map map = new HashMap();
map.put("name", "张三");
map.put("message", "hello freemarker!!!");
map.put("linkman", "小王");
FreeMarker模板
<#--1.插值表达式-->
我是:${name}
你好,${message}
<br>
<hr>
联系人:${linkman}
<br>
页面效果
(2)assign指令
assign指令可以选择本地声明,即在模板中写,也可使用数据模式中的数据;
java代码
User user = new User();
user.setUsername("小明");
user.setPassword("123456");
map.put("user", user);
FreeMarker模板
<#--2.assign指令:本地声明-->
<#assign info={"mobile":"12345678910","address":'杭州市'}>
电话:${info.mobile} 地址:${info.address}
<br>
<#--2.assign指令:数据模型-->
用户名:${user.username}
密码:${user.password}
页面效果
(3)if指令
java代码
map.put("success", true);
FreeMarker模板
<#--3.if指令-1-->
<#assign success=false>
<#if success>
你已通过实名认证
<#else>
你未通过实名认证
</#if>
<br>
<hr>
<#--3.if指令-2-->
<#assign number1 = 10>
<#assign number2 = 5>
<#if number1 + number2 gte 20 || number1 - number2 lt 2>
number1 * number2 : ${number1 * number2}
<#else>
number1 / number2 : ${number1 / number2}
</#if>
<br>
<hr>
<#--3.if指令-3-->
<#assign var = 999>
<#if var == 999>
var = 999
<#elseif var == 888>
var = 888
<#else >
var = 111
</#if>
<br>
<hr>
页面效果
(4)集合遍历
可在Map作为对象,也可使用实体类作为对象;
java代码
List goodsList = new ArrayList();
Map goods1 = new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2 = new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3 = new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);
User user1 = new User();
user1.setUsername("小强");
user1.setPassword("123456");
User user2 = new User();
user2.setUsername("小红");
user2.setPassword("123456");
ArrayList<User> users = new ArrayList<User>();
users.add(user1);
users.add(user2);
map.put("users", users);
FreeMarker模板
<#--4.集合遍历-1-->
<#list goodsList as goods>
商品名称: ${goods.name} 价格:${goods.price} 索引:${goods_index + 1}<br>
</#list>
<br>
<#list users as user >
用户名:${user.username}====密码:${user.password}<br>
</#list>
<br>
<#--4.集合遍历-2-->
<#list ["winter", "spring", "summer", "autumn"] as x>
${x}<br>
</#list>
<br>
<hr>
页面效果
(5)字符串输出
FreeMarker模板
<#--5.字符串输出,支持以下四种方式
(1)通过变量直接输出
(2)通过字符串常量输出
(3)通过表达式输出
(4)通过字符串拼接输出
-->
<#assign name="zhangsan"/>
<br><br>
hello ${name} <br>
${"hello"}${name}<br>
${"Hello ${name} !"} <br>
${"Hello " + name + " !"}<br>
<br>
<hr>
页面效果
(6)字符串常量
FreeMarker模板
<#--6.声明一个字符串常量,加r表示原始字符串-->
<#assign cname=r"特殊字符完成输出(http:\\www.baidu.com)">
${cname}
<br>
<hr>
页面效果
(7)字符串截取
FreeMarker模板
<#--7.字符串截取
通过下标直接获取下标对应的字母
起点下标..结尾下标截取字符串
-->
字符串截取 :<br>
通过下标直接获取下标对应的字母:${name[2]}<br>
起点下标..结尾下标截取字符串:${name[0..5]}
<br>
<hr>
页面效果
(8)运算符
FreeMarker模板
<#--8.运算符,注意运算符不要写在大括号外面-->
<#assign number1 = 10>
<#assign number2 = 5>
算数运算:<br>
"+" : ${number1 + number2}<br>
"-" : ${number1 - number2}<br>
"*" : ${number1 * number2}<br>
"/" : ${number1 / number2}<br>
"%" : ${number1 % number2}<br>
<br>
<hr>
页面效果
(9)函数
java代码
map.put("dTime", new Date());
FreeMarker模板
<#--9.函数
语法:${变量名?内联函数名称}
具体函数名称参考官方文档:https://freemarker.apache.org/docs/ref_builtins_string.html
-->
内建/内建函数:<br>
<#assign data = "abcd1234">
第一个字母大写:${data?cap_first}
所有字母小写:${data?lower_case}
所有字母大写:${data?upper_case}
<br>
<hr>
<#assign floatData = 12.84><br>
数值取整数:${floatData?int}<br>
获取集合的长度:${goodsList?size}<br>
时间格式化:<br>
<#--${dTime} 如果我们的模型是日期类型 必须要指定日期格式 -->
${dTime?date}<br>
${dTime?time}<br>
${dTime?datetime}<br>
${dTime?string("yyyy/MM/dd")}
<br>
<hr>
页面效果
(10)自定义函数
java代码
map.put("nullList", null);
FreeMarker模板
<#--10.自定义函数:判断是否为空或者为null
固定写法:模型数据名称??
-->
判断是否为空或者为null:<br>
<#if nullList??>
<#list nullList as null >
${null.name} - ${null.price}<br>
</#list>
<#else>
集合为空
</#if>
页面效果
使用
第一步:添加依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
第二步:创建模板
创建一个模板,后缀名是.ftl
如下,我在resource文件夹下创建了一个模板(mode.ftl),
内容如下
<html>
<head>
<meta charset="utf-8">
<title>Freemarker使用</title>
</head>
<body>
<#--1.插值表达式-->
我是:${name}
你好,${message}
<br>
<hr>
联系人:${linkman}
<br>
<#--2.assign指令:本地声明-->
<#assign info={"mobile":"12345678910","address":'杭州市'}>
电话:${info.mobile} 地址:${info.address}
<br>
<#--2.assign指令:数据模型-->
用户名:${user.username}
密码:${user.password}
<hr>
<#--3.if指令-1-->
<#assign success=false>
<#if success>
你已通过实名认证
<#else>
你未通过实名认证
</#if>
<br>
<hr>
<#--3.if指令-2-->
<#assign number1 = 10>
<#assign number2 = 5>
<#if number1 + number2 gte 20 || number1 - number2 lt 2>
number1 * number2 : ${number1 * number2}
<#else>
number1 / number2 : ${number1 / number2}
</#if>
<br>
<hr>
<#--3.if指令-3-->
<#assign var = 999>
<#if var == 999>
var = 999
<#elseif var == 888>
var = 888
<#else >
var = 111
</#if>
<br>
<hr>
<#--4.集合遍历-1-->
<#list goodsList as goods>
商品名称: ${goods.name} 价格:${goods.price} 索引:${goods_index + 1}<br>
</#list>
<br>
<#list users as user >
用户名:${user.username}====密码:${user.password}<br>
</#list>
<br>
<#--4.集合遍历-2-->
<#list ["winter", "spring", "summer", "autumn"] as x>
${x}<br>
</#list>
<br>
<hr>
<#--5.字符串输出,支持以下四种方式
(1)通过变量直接输出
(2)通过字符串常量输出
(3)通过表达式输出
(4)通过字符串拼接输出
-->
<#assign name="zhangsan"/>
<br><br>
hello ${name} <br>
${"hello"}${name}<br>
${"Hello ${name} !"} <br>
${"Hello " + name + " !"}<br>
<br>
<hr>
<#--6.声明一个字符串常量,加r表示原始字符串-->
<#assign cname=r"特殊字符完成输出(http:\\www.baidu.com)">
${cname}
<br>
<hr>
<#--7.字符串截取
通过下标直接获取下标对应的字母
起点下标..结尾下标截取字符串
-->
字符串截取 :<br>
通过下标直接获取下标对应的字母:${name[2]}<br>
起点下标..结尾下标截取字符串:${name[0..5]}
<br>
<hr>
<#--8.运算符,注意运算符不要写在大括号外面-->
<#assign number1 = 10>
<#assign number2 = 5>
算数运算:<br>
"+" : ${number1 + number2}<br>
"-" : ${number1 - number2}<br>
"*" : ${number1 * number2}<br>
"/" : ${number1 / number2}<br>
"%" : ${number1 % number2}<br>
<br>
<hr>
<#--9.函数
语法:${变量名?内联函数名称}
具体函数名称参考官方文档:https://freemarker.apache.org/docs/ref_builtins_string.html
-->
内建/内建函数:<br>
<#assign data = "abcd1234">
第一个字母大写:${data?cap_first}
所有字母小写:${data?lower_case}
所有字母大写:${data?upper_case}
<br>
<hr>
<#assign floatData = 12.84><br>
数值取整数:${floatData?int}<br>
获取集合的长度:${goodsList?size}<br>
时间格式化:<br>
<#--${dTime} 如果我们的模型是日期类型 必须要指定日期格式 -->
${dTime?date}<br>
${dTime?time}<br>
${dTime?datetime}<br>
${dTime?string("yyyy/MM/dd")}
<br>
<hr>
<#--10.自定义函数:判断是否为空或者为null
固定写法:模型数据名称??
-->
判断是否为空或者为null:<br>
<#if nullList??>
<#list nullList as null >
${null.name} - ${null.price}<br>
</#list>
<#else>
集合为空
</#if>
</body>
</html>
第三步:编写测试类
在项目中创建一个测试类,里面读取FreeMarker模板,设置数据模型,并输出为html页面;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.example.pojo.User;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
@SpringBootTest
public class MyTest {
public static void main(String[] args) throws IOException, TemplateException {
//创建freemarker的配置对象
Configuration configuration = new Configuration(Configuration.getVersion());
//设置模板文件所在目录,如C:\Users\10765\Desktop\XXX\freemarker_essay\freemarker_essay\src\main\resources
configuration.setDirectoryForTemplateLoading(new File("模板所在的目录"));
//设置字符集
configuration.setDefaultEncoding("utf-8");
//加载模板文件,模板文件名,如mode.ftl
Template template = configuration.getTemplate("模板文件");
// 准备模板文件中所需要的数据,通常是通过Map进行构造
Map map = new HashMap();
map.put("name", "张三");
map.put("message", "hello freemarker!!!");
map.put("linkman", "小王");
map.put("success", true);
User user = new User();
user.setUsername("小明");
user.setPassword("123456");
map.put("user", user);
List goodsList = new ArrayList();
Map goods1 = new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2 = new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3 = new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);
User user1 = new User();
user1.setUsername("小强");
user1.setPassword("123456");
User user2 = new User();
user2.setUsername("小红");
user2.setPassword("123456");
ArrayList<User> users = new ArrayList<User>();
users.add(user1);
users.add(user2);
map.put("users", users);
map.put("dTime", new Date());
map.put("nullList", null);
//准备输出流对象,用于输出静态文件
Writer writer = new FileWriter("test.html");
//输出 freemarker的数据模型的类型只能是map或是JavaBean对象
template.process(map, writer);
//关闭流
writer.close();
}
}
第四步:启动测试
执行程序,可以在项目的根目录下找到test.html文件,打开后就是数据按照模板填充的效果;
总结
类似于EasyExcel