html文件放在src\main\resources\templates\parseHtml.html下,html需要动态更换值的地方用el表达式取值 ${key}
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Document
</title>
<style type="text/css">
.body{color: #5E5E5E}
</style>
</head>
<body>
<div>
<br>
</div>
<div>
<div style="font:Verdana normal 14px;color:#000;">
<div style="position:relative;">
<div>
<div style="font:Verdana normal 14px;color:#000;">
<div>
</div>
<div style="position:relative;">
<div id="tmpcontent_res"></div>
<table width="704px" style="margin: 0 auto;border: 1px #ECECEC solid;border-collapse: collapse;">
<tbody>
<tr style="min-height: 234px;width: 100%;">
<td style="min-height: 182px;width: 852px;margin: 0 auto;padding: 26px 46px;position: relative;">
<p style="margin: 0;padding: 0;font-size: 16px;font-weight: 700;" th:text="'尊敬的用户 : 您好!'"></p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 20px;line-height: 30px;">
<span style="font-weight: 700;" th:text="'CIIP合作伙伴 '+${inviter}+' 邀请您'"></span>
<a style="text-decoration: none;color: #11a9e8;font-size: 24px;font-weight: 700;" th:href="${str}">加入CIIP平台</a>
<span th:text="',请点击链接,并使用'+${beInviter}+'注册/登录后,完成个人实名认证,并关联CIIP合作伙伴成为其客户。'"></span>
</p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 40px;">
<span>如有疑问,请联系合作伙伴联系人:</span>
</p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 20px;" th:text="'联系人姓名 :'+${contactName}"></p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 20px;" th:text="'联系人电话 :'+${contactPhone}"></p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 60px;font-weight: 900;">
感谢您对CIIP建筑产业工业互联网平台的支持!
</p>
<p style="width: 100%;height: 1px;background: #dcdfe6;"></p>
<p style="margin: 0;padding: 0;font-size: 16px;margin-top: 20px;color: #afafaf;">
本邮件由系统自动发送,请勿直接回复!
</p>
</td>
</tr>
<tr>
<td>
<p style="margin: 0;padding: 0;font-size: 16px;margin-left: 40px;"></p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
pom文件
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.6.6</version>
</dependency>
编写java代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private TemplateEngine templateEngine;
@Test
void contextLoads() {
Context context = new Context(); //Context是给thymeleaf模版提供变量的。
context.setVariable("inviter","111");
context.setVariable("beInviter","222");
context.setVariable("contactName","333");
context.setVariable("contactPhone","444");
context.setVariable("str","55555");
//读取html文件,并动态赋值
String emailContent = templateEngine.process("parseHtml", context);
System.out.println(emailContent);
}
}
运行输出字符串
总结: 写法和普通web开发一样, 唯一不同的是,web开发,前端如果用el表达式取值,咱们后端用requerst.setAttribute(key,value)方法, 这里用的context.setVariable(key,value)
工作中遇到的问题以及解决方案:
问题1. 项目运行后访问不了html文件: 报如下错误
解决方案:设置引擎使用resolver
-
html 中如何循环渲染表格,能否像jsp中c:forEach一样循环:
-
如何判断后端传递的数组长度,以及如何动态控制标签的显示隐藏?使用th:if 即可
-
如何对数值进行格式化,比如金额每三个数字前加个逗号,或者扩大100倍拼接百分号:
使用#numbers.formatDecimal实现:
目前只涉及到这些语法:thymeleaf 一个服务器成熟的模板引擎框架,有成熟的方法以及逻辑控制语法。需要的时候再去详细的查询一下
-
当取了对象中没有的属性,会抛出SpringEL表达式的错误。我们只需要将
${item.xxx}
改成${item.get('xxx')}
即可,这时当没有该属性时,会以空代替,并不会报错,也可以用三目运算进行自定义返回值的使用。
如图
解决:
-
图片如何渲染: 我们需要根据java 获取到图片的绝对路径,然后以参数的形式传给html 模版引擎,
ClassPathResource classPathResource = new ClassPathResource("static/images/title1.png");
contextMap.put("path", classPathResource.getFile().getPath());
<div style="border:1px solid red">
<img th:src="${path}" style="width:100px; hight:100px; border: 1px solid black;" alt="My Image">
</div>
完整版: thymeleaf 进行封装使用
我们发送邮件时,无非只需要thymeleaf 渲染后的字符串, 我们将公共的代码封装成util类,这样每次我们使用起来便相当的简单
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
HtmlToStringUtil 类
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import java.util.Map;
/**
* 通过thymeleaf
* 针对html静态文件做动态渲染,并返回渲染后的html字符串,
* 用作渲染复杂的html邮件正文
* @auth T011921
* @date 2023/5/23
* @time 9:24
*/
@Component
public class HtmlToStringUtil {
/**
* 服务端动态渲染html文件,并返回渲染后的html字符串
* @param path 需要渲染的html文件路径 如:"template/xxx/html/ProductAlertMailBody.html"
* @param params 要传递的参数
* @return
*/
public String getHtmlBody(String path, Map<String,Object> params) {
TemplateEngine templateEngine = new SpringTemplateEngine();
// 1.读取磁盘中的模板文件,设置引擎使用resolver
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
templateEngine.setTemplateResolver(resolver);
// 2. 设置映射数据
// 1. 利用thymeleaf中Context对象,存储模板中所用到的值
Context context = new Context();
context.setVariables(params);
//3.使用thymeleaf 向html文件内赋值,并获取渲染后的html代码
String content = templateEngine.process(path,context);
return content;
}
}
业务中调用,获取到渲染后的字符串,传给邮件程序
Map<String, Object> contextMap = new HashMap<>();
contextMap.put("data1", list);
String content = htmlToStringUtil.getHtmlBody("template/xxx/xxxxBody.html", contextMap);
html代码
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
</title>
<style type="text/css">
table {
border-collapse: collapse;
width: 1200px;
}
table,table tr th, table tr td {
border: 1px solid black;
}
table tr th{
background: #f8f8f9
}
</style>
</head>
<body>
<div th:if="${data1.size()}> 0">
<div style="padding-left: 20px;">
<table>
<tr>
<th width="10%">DATA_TYPE</th>
<th width="20%">TABLENAME</th>
<th>RESULT</th>
<th width="10%">SYS_CODE</th>
<th width="10%">RECEIVER</th>
</tr>
<tr th:each="item:${data1}">
<td align="center" th:utext="${item.get('DATA_TYPE')}"></td>
<td align="center" th:utext="${item.get('TABLENAME')}"></td>
<td align="left" th:utext="${item.get('RESULT')}"></td>
<td align="center" th:utext="${item.get('SYS_CODE')}"></td>
<td align="center" th:utext="${item.get('RECEIVER')}"></td>
</tr>
</table>
</div>
</div>
</body>
</html>