thymeleaf服务器模板引擎,实现动态html,用于java发送邮件的html正文

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>
                        &nbsp;
                    </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
在这里插入图片描述

  1. html 中如何循环渲染表格,能否像jsp中c:forEach一样循环:
    在这里插入图片描述

  2. 如何判断后端传递的数组长度,以及如何动态控制标签的显示隐藏?使用th:if 即可
    在这里插入图片描述

  3. 如何对数值进行格式化,比如金额每三个数字前加个逗号,或者扩大100倍拼接百分号:
    使用#numbers.formatDecimal实现:

在这里插入图片描述
目前只涉及到这些语法:thymeleaf 一个服务器成熟的模板引擎框架,有成熟的方法以及逻辑控制语法。需要的时候再去详细的查询一下

  1. 当取了对象中没有的属性,会抛出SpringEL表达式的错误。我们只需要将${item.xxx}改成${item.get('xxx')}即可,这时当没有该属性时,会以空代替,并不会报错,也可以用三目运算进行自定义返回值的使用。
    如图
    解决:
    在这里插入图片描述

  2. 图片如何渲染: 我们需要根据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>
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值