springboot中thymeleaf渲染html模板
有时候我们会遇到这样的一个需求:
通过前端传入的数据渲染一个现成的打印模板出来,最后返回一个html格式的文本给前端,模板是有一个现成的,但是每次传入进来的数据是不同的,所以需要后端经过渲染出来返回渲染好的html内容给前端,这个时候我们就可以用thymeleaf来实现这个功能。
我们先建造一个模板:
<div id="print_main_full_box">
<style>
#print_main_full_box {
width: 100%;
}
#print_main_full_box > * {
margin: 0;
padding: 0;
}
#print_main_full_box > table, td, th {
margin: 0;
padding: 0;
border: 1px solid black;
border-collapse: collapse
}
.yiban {
width: 49%;
text-align: left;
display: inline-block;
/*border-left: 1px solid black;*/
}
.jiachu {
font-weight:bold;
}
td {
font-size: 14px;
}
.center {
text-align: center;
}
</style>
<table width="100%">
<tbody>
<tr class="jiachu">
<td colspan="8" class="center" style="font-size: 16px">
<div th:text = ${company}>公司</div>
<div th:text = ${title}>出货单</div>
</td>
</tr>
<tr>
<td colspan="8" class="center">
<span th:text = ${address}>地址</span>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">客户名称:<span th:text = ${cursumerName}>客户名称</span></span>
</div>
<div class="yiban">
<span class="jiachu">订单号:</span><span th:text = ${orderNo}>订单号</span>
</div>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">送货地址:<span th:text = ${deliveryAddr}>送货地址</span></span>
</div>
<div class="yiban">
<span class="jiachu">送货日期:</span><span th:text = ${actualDeliveryDate}>送货日期</span>
</div>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">联系电话:<span th:text = ${phone}>联系电话</span></span>
</div>
<div class="yiban">
<span class="jiachu">送货单号:</span><span th:text = ${invoiceNo}>送货单号</span>
</div>
</td>
</tr>
<tr class="center">
<td colspan="8" class="jiachu">
<div>机器名称:<span th:text = ${machineName}></span></div>
</td>
</tr>
<tr class="jiachu">
<td width="5%" align="center">序号</td>
<td width="5%" align="center">内部序号</td>
<td width="25%" align="center">图号</td>
<td width="5%" align="center">单位</td>
<td width="5%" align="center">数量</td>
<td width="5%" align="center">单价</td>
<td width="5%" align="center">总价</td>
<td width="10%" align="center">备注</td>
</tr>
<tr th:each = "prod : ${prods}" data-line="5">
<td align="center"><div data-item-index style="overflow: hidden;max-height: 40px;line-height: 20px;">序号</div></td>
<td align="center"><div th:text = ${prod.selfNumber} style="overflow: hidden;max-height: 40px;line-height: 20px;">内部序号</div></td>
<td align="center"><div th:text = ${prod.chartNo} style="overflow: hidden;max-height: 40px;line-height: 20px;">图号</div></td>
<td align="center"><div th:text = ${prod.company} style="overflow: hidden;max-height: 40px;line-height: 20px;">单位</div></td>
<td align="center"><div th:text = ${prod.invoiceNumber} style="overflow: hidden;max-height: 40px;line-height: 20px;">数量</div></td>
<td align="center"><div th:text = ${prod.unitPrice} style="overflow: hidden;max-height: 40px;line-height: 20px;">单价</div></td>
<td align="center"><div th:text = ${prod.totalPrice} style="overflow: hidden;max-height: 40px;line-height: 20px;">总价</div></td>
<td align="center"><div th:text = ${prod.remarks} style="overflow: hidden;max-height: 40px;line-height: 20px;">哦呵呵</div></td>
</tr>
<tr>
<td colspan="4" align="right">总计:</td>
<td align="right"><span th:text = ${invoiceNumber}>3</span></td>
<td align="right"></td>
<td align="right"><span th:text = ${totalPrice}>3</span></td>
<td align="right"></td>
</tr>
<tr>
<td colspan="4">送货单位签章:</td>
<td colspan="4">收货单位签章:</td>
</tr>
</tbody>
</table>
</div>
这个里面是一个含有thymeleaf语法的模板,现在我们要通过传入的参数不同渲染出不一样的数据出来。
例如前端传入这样的数据:
{
"company":"csdner",
"title":"出货单",
"address":"中国",
"cursumerName":"客户",
"orderNo":"2432523234234234",
"deliveryAddr":"工业园",
"actualDeliveryDate":"20210526",
"phone":"18888888888",
"invoiceNo":"1567894",
"machineName":"25661615",
"prods":[
{
"selfNumber":"5555",
"chartNo":"6666",
"company":"csdner",
"invoiceNumber":"2222",
"unitPrice":"55",
"totalPrice":"555",
"remarks":"哈哈哈哈"
}
],
"invoiceNumber":"22",
"totalPrice":"102"
}
后端要渲染出渲染好之后的html文档给前端:
<div id="print_main_full_box">
<style>
#print_main_full_box {
width: 100%;
}
#print_main_full_box > * {
margin: 0;
padding: 0;
}
#print_main_full_box > table, td, th {
margin: 0;
padding: 0;
border: 1px solid black;
border-collapse: collapse
}
.yiban {
width: 49%;
text-align: left;
display: inline-block;
/*border-left: 1px solid black;*/
}
.jiachu {
font-weight:bold;
}
td {
font-size: 14px;
}
.center {
text-align: center;
}
</style>
<table width="100%">
<tbody>
<tr class="jiachu">
<td colspan="8" class="center" style="font-size: 16px">
<div>csdner</div>
<div>出货单</div>
</td>
</tr>
<tr>
<td colspan="8" class="center">
<span>中国</span>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">客户名称:<span>客户</span></span>
</div>
<div class="yiban">
<span class="jiachu">订单号:</span><span>2432523234234234</span>
</div>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">送货地址:<span>工业园</span></span>
</div>
<div class="yiban">
<span class="jiachu">送货日期:</span><span>20210526</span>
</div>
</td>
</tr>
<tr>
<td colspan="8">
<div class="yiban">
<span class="jiachu">联系电话:<span>18888888888</span></span>
</div>
<div class="yiban">
<span class="jiachu">送货单号:</span><span>1567894</span>
</div>
</td>
</tr>
<tr class="center">
<td colspan="8" class="jiachu">
<div>机器名称:<span>25661615</span></div>
</td>
</tr>
<tr class="jiachu">
<td width="5%" align="center">序号</td>
<td width="5%" align="center">内部序号</td>
<td width="25%" align="center">图号</td>
<td width="5%" align="center">单位</td>
<td width="5%" align="center">数量</td>
<td width="5%" align="center">单价</td>
<td width="5%" align="center">总价</td>
<td width="10%" align="center">备注</td>
</tr>
<tr data-line="5">
<td align="center"><div data-item-index style="overflow: hidden;max-height: 40px;line-height: 20px;">序号</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">5555</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">6666</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">csdner</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">2222</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">55</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">555</div></td>
<td align="center"><div style="overflow: hidden;max-height: 40px;line-height: 20px;">哈哈哈哈</div></td>
</tr>
<tr>
<td colspan="4" align="right">总计:</td>
<td align="right"><span>22</span></td>
<td align="right"></td>
<td align="right"><span>102</span></td>
<td align="right"></td>
</tr>
<tr>
<td colspan="4">送货单位签章:</td>
<td colspan="4">收货单位签章:</td>
</tr>
</tbody>
</table>
</div>
好了,需求说完,开始实战:
首先第一步我们是需要一个thymeleaf的模板,让在项目中引入一个工具类:
添加依赖:
<!-- Thymeleaf 模板引擎 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.1.12</version>
</dependency>
第二步,创建一个工具类:
public class HTMLTemplateUtils {
private final static TemplateEngine templateEngine = new TemplateEngine();
/**
* 使用 Thymeleaf 渲染 HTML
* @param template HTML模板
* @param params 参数
* @return 渲染后的HTML
*/
public static String render(String template, Map<String, Object> params){
Context context = new Context();
context.setVariables(params);
return templateEngine.process(template, context);
}
}
第三步:传入参数:
String output = HTMLTemplateUtils.render(content, map);
content为模板,map为前端传入的json数据
第四步,返回output,这个时候output就是我们已经渲染好的模板了