Java使用FreeMarker模板引擎动态生成html页面
因一个功能需要动态生成HTML文件,所以接触了下FreeMarker模板引擎。一般可以使用该模板引擎来生成月报,日报,单据报表等等。我们都知道预先生成静态HTML文件,当访问时可以提高效率的。
Freemarker简单介绍
Freemarker是一款模板引擎,基于模板用来生成文本(任何来自HTML格式的文本用来生成源代码)的通用工具。FreeMarker实际上是被设计生成HTML页面的,尤其是通过实现了基于MVC模式的Java Servlet应用程序。
Freemarker生成静态页面的原理
首先使用自己定义的模板页面,这个模板页面可以是普通的html,也可以是嵌套Freemarker中的取值表达式,标签等,后台读取这个模板页面,解析里面的标签完成相对应的操作,后采用键值对的方式传递参数替换模板中的的取值表达式,做完之后根据配置的路径生成一个HTML页面,达到静态化访问的目的。
FreeMarker指令示例
尽管FreeMarker有很多指令,不过一般最常用的三个指令分别是if指令、list指令、include指令
if指令 当a等于user时,将会打印:"用户"
<# if a=="user">
用户.
</#if>
list指令:用列表遍历集合的内容
<#list user as users >
<tr>
<th>${users.id}</th>
<th>${users.name}</th>
</tr>
</#list>
include指令:在当前模板中插入其他文件的内容
<body>
<include "/test.html">
</body>
Freemarker jar包以及文档下载(已打包好)
https://pan.baidu.com/s/1jLJWU1dBZcay6dhXRas52w
Freemarker的使用
首先导入jar包,(struts2里面自带这个包)
根据自己的需求创建一个Freemarker模板,后缀为.ftl,我这里在WEB-INF下创建了一个文件夹用于存放Freemarker模板
Template1.ftl部分代码
<table id="tableid" class="table-condensed layui-table table-hover" data-toggle="table" style="font-size: 12px;">
省略了非关键代码
<thead>
<tr>
<th>商品名称</th> <th>商品编号</th><th>规格</th>
<th>单位</th><th>数量</th><th>单价</th>
</tr>
</thead> <tbody>
<#list list as stu>
<tr>
<th>${stu.designation}</th>
<th>${stu.serialNumber}</th>
<th>${stu.specification}</th>
<th>${stu.unit}</th>
<th>${stu.quantity}</th>
<th>${stu.unitPrice}</th>
<th>${stu.grossAmount}</th>
</tr>
</#list></tbody>
</table>
<td style="font-size:12px;text-align: left;font-family: Arial,'微软雅黑','宋体';line-height: 200%;"
class="borderRNone" width="80">
<span>其他费用(元):</span>
</td>
<td width="100">
<span style="color:red">¥</span><span id="spanFaReceAmt" style="font-size:12px;color:red" class="money">${info.restExpenses}</span>
</td>
</tr>
上面代码大部分跟普通HTML代码差不多,主要是使用list指令遍历生成了table,嵌套了Freemarker的表达式,使用了一些Freemarker的标签。
Servlet代码
public void testFreeMarker(HttpServletRequest request, HttpServletResponse response) throws IOException, TemplateException{
//创建一个模板文件
//创建一个Configuration对象
Configuration configuration = new Configuration(Configuration.getVersion());
String file = request.getServletContext().getRealPath("WEB-INF/freemarkertemplate");
//设置模板文件保存的目录
configuration.setDirectoryForTemplateLoading(new File(file));
//设置模板文件的编码格式
configuration.setDefaultEncoding("UTF-8");
//加载一个模板文件,创建一个模板对象
String html = request.getServletContext().getRealPath("promotion");
File htmlFile = new File(html,"test.html");
System.out.println(htmlFile);
Template template = configuration.getTemplate("temp2.ftl");
//创建一个数据集可以是pojo,也可以是map,一般使用map
Map<String, Object> maps=new HashMap<String, Object>();
//将项目名称存进map中
maps.put("ctv", request.getContextPath());
List<CommodityList> list = null;
//获取id
int commodityStockOrderID = Integer.parseInt(request.getParameter("commodityStockOrderID")) ; StockCommodityBean StockCommodity = new StockCommodityBean();
// 调用servic层的方法查询出需要的数据
StockCommodity= dao.selectDetails(commodityStockOrderID);
//获取到list集合
list = StockCommodity.getCommList();
//将list保存进去
maps.put("list", list);
maps.put("info",StockCommodity);
//生成静态页面
template.process(maps, new FileWriter(htmlFile));
//关闭流
//out.close();
}
从上面代码可以看出首先创建一个Configuration对象,设置模板文件的格式,再加载模板文件从而创建一个模板对象,其中将需要传过去的数据装进map中,从而生成需要的静态页面。
效果
总结:使用Freemarker引擎模板的优点:可以分离表现层和业务层逻辑,可以提高开发效率。缺点:如果修改模板后,没有及时更新生成HTML页面,那生成的是过期的数据。使用Freemarker模板中的变量都需要赋值,否则会抛异常,这样就需要增加if语句进行判断,从而增加了工作量。