springboot发送邮件,内容使用thymeleaf模板引擎排版

springboot发送邮件,内容使用thymeleaf模板引擎排版

      • 1、导入jar包
      • 2、yml设置
      • 3、收件人以及收件信息设置
      • 4、发邮件service
      • 5、模版页面
      • 6、controller

1、导入jar包

<!--发送邮件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
<!--使用thymeleaf 形式--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

2、yml设置

发件邮箱信息设置:


spring:mail:host: smtp.xx.cnport: 465username: 你的邮箱password: 你的密码
#    default-encoding: UTF-8protocol: smtpproperties: # 配置以SSL的方式发送, 这个需要使用这种方式并且端口是465mail:smtp:auth: truessl:enable: truesocketFactory:class: com.sun.mail.util.MailSSLSocketFactoryfallback: falsedebug: true

3、收件人以及收件信息设置

@Getter
@Setter
public class AcceptMailParam {//标题private String title;//接收人邮件地址private String receiveEmail[];//抄送人邮件地址private String chaoSongPersonEmail[];//附件,value 文件的绝对地址/动态模板数据private Map<String, Object> attachment;//thymeleaf模版引擎页面对象数据:邮件排版内存List<OperateDataResultInfoView> pageViewList;
}页面对象数据展示
@Setter
@Getter
public class OperateDataResultInfoView {private Long id;/*** 存储当前年月,eg:202301*/private Integer curMonth;/*** 库名*/private String dbName;/*** 表名*/private String tableName;/*** 计划生成数据量*/private Long planGenDataCnt;/*** 实际生成数据量*/private Long actualGenDataCnt;/*** 备注*/private String remark;private String gmtCreate;private String gmtModified;/* ** 剩余待生成数据量*/private Long remainToGenCnt;/* ** 生成数据成功率(实际生成数量/计划生成数量),单位%*/private BigDecimal genDataSuccessRate;/**模拟生成数据*/public OperateDataResultInfoView() {this.id = ThreadLocalRandom.current().nextLong(100L, 999L);this.curMonth = DateUtil.getPreMonth();String[] dbAndTableName = ("dbName" + id + ".tableName" + id).split("\\.");this.dbName = dbAndTableName[0];this.tableName = dbAndTableName[1];this.planGenDataCnt = id + ThreadLocalRandom.current().nextLong(10L, 99L);this.actualGenDataCnt = id;this.remark = null;this.gmtCreate = DateUtil.getNowStr();this.gmtModified = DateUtil.getNowStr();this.remainToGenCnt = (planGenDataCnt - actualGenDataCnt) >= 0 ? (planGenDataCnt - actualGenDataCnt) : 0;BigDecimal rate = new BigDecimal(actualGenDataCnt).divide(new BigDecimal(planGenDataCnt), 4, BigDecimal.ROUND_HALF_UP);this.genDataSuccessRate = rate.compareTo(new BigDecimal("1")) >= 0 ? new BigDecimal("100") : rate.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);}
}

4、发邮件service

public interface SendMailService {/*** 邮件内容排版调试*/AcceptMailParam getMailContentAndSendMail(Integer curMonth);
}/*** 获取指定月份的邮件【邮件内容:生成数据的结果集 信息】* 次月1日8点 发送*/@Overridepublic AcceptMailParam getMailContentAndSendMail(Integer curMonth) {AcceptMailParam acceptMailParam = new AcceptMailParam();List<OperateDataResultInfoView> pageViewList = new ArrayList<>();for (int i = 0; i < 10; i++) {pageViewList.add(new OperateDataResultInfoView());}Collections.sort(pageViewList, Comparator.comparing(OperateDataResultInfoView::getId).reversed());acceptMailParam.setPageViewList(pageViewList);String[] emails = {"xxx1@qq.com"};String[] chaoSongPerson = {"xx2@qq.com"};//收件人,支持多人acceptMailParam.setReceiveEmail(emails);//抄送人,支持多人acceptMailParam.setChaoSongPersonEmail(chaoSongPerson);acceptMailParam.setTitle("统计业务表生成数据结果");//添加附件Map<String, Object> map = new HashMap<>();//key为邮件附件文件名称,路径改为你的服务器路径即可,可添加不同类型文件map.put("1-test1.zip", "/Users/gina/xx/data/test2.zip");map.put("2-test2.xlsx", "/Users/gina/xx/data/test1.xlsx");acceptMailParam.setAttachment(map);//调试邮件内容排版时,此处可注释掉。//this.sendTemplateMail(acceptMailParam,"/mail/list");return acceptMailParam;}

5、模版页面

在resources下,在路径templates/mail/下添加文件list.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><style>tr.odd td {background-color: #f0faaa;}td.number {text-align: right;}table {width: 100%;border: 1px solid #000;border-collapse: collapse;}table > tbody > tr > td, table > thead > tr > th {padding: 2px 10px;border-left: 1px dotted #000000;vertical-align: top;line-height: 20px;}table > tbody > tr, table > thead > tr {border-bottom: 1px solid #000000;}table th {background-color: #99cc33;}table > tbody > tr > td > a, table > tbody > tr > td > a:hover {text-decoration: none;font-weight: bold;background-color: #352726;padding: 2px 10px;color: #f0faaa;margin-left: 10px;text-transform: uppercase;border: 0px;}</style><head><title>统计业务表生成数据结果</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body><h1>统计业务表生成数据结果</h1><table><tr><th>生成月份</th><th>库名</th><th>表名</th><th>计划生成()</th><th>实际生成()</th><th>成功率%</th><th>未生成()</th><th>创建时间</th><th>更新时间</th><th>备注</th></tr><tr th:each="o : ${pageViewList}" th:class="${o.id % 2 == 0}? 'odd'" ><td th:text="${o.curMonth}"   ></td><td th:text="${o.dbName}" ></td><td th:text="${o.tableName}" ></td><td th:text="${o.planGenDataCnt}" ></td><td th:text="${o.actualGenDataCnt}"></td><td th:text="${o.genDataSuccessRate}"></td><td th:text="${o.remainToGenCnt}"></td><td th:text="${o.gmtCreate}"></td><td th:text="${o.gmtModified}"></td><td th:text="${o.remark}"></td></tr></table></body>
</html>

6、controller

@Controller
@Slf4j
public class SendMailController {/*** 调试生成的页面样式,不发邮件* 数据处理结果集view*/@Resourceprivate SendMailService sendMailService;/** 点此可直接访问* http://localhost:8081/sendMail?curMonth=202311*/@RequestMapping("sendMail")public String sendMail(Model model, @RequestParam(name = "curMonth") Integer curMonth) {try {AcceptMailParam acceptMailParam = sendMailService.getMailContentAndSendMail(curMonth);model.addAttribute("title", acceptMailParam.getTitle());model.addAttribute("pageViewList", acceptMailParam.getPageViewList());} catch (Exception e) {log.error("sendMail fail ,msg={}", e.getMessage());}return "mail/list";}
}

7、启动服务后,访问页面展示:
在这里插入图片描述

邮箱内容样式为:
在这里插入图片描述

有对thymeleaf感兴趣的同学可通过中文官网去了解:thymeleaf中文官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/277754.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十五 动手学深度学习v2计算机视觉 ——全连接神经网络FCN

文章目录 FCN FCN 全卷积网络先使用卷积神经网络抽取图像特征&#xff0c;然后通过卷积层将通道数变换为类别个数&#xff0c;最后通过转置卷积层将特征图的高和宽变换为输入图像的尺寸。 因此&#xff0c;模型输出与输入图像的高和宽相同&#xff0c;且最终输出通道包含了该空…

虚幻学习笔记17—C++委托(单播)

一、前言 相比“代理”这个名词我更喜欢叫“委托”&#xff0c;虚幻的委托分为三类&#xff0c;分别为单播、多播和动态多播。单播顾名思义就是一次只能绑定一个函数的委托&#xff0c;多播能一次性绑定多个&#xff0c;动态多播即可以在蓝图中进行动态的绑定且可以绑定多个。 …

jmeter,动态参数之随机数、随机日期

通过函数助手&#xff0c;执行以下配置&#xff1a; 执行后的结果树&#xff1a; 数据库中也成功添加了数据&#xff0c;对应字段是随机值&#xff1a;

[C++]——学习模板

了解模板——初阶 前言&#xff1a;一、模板1.1 什么是模板1.2 模板的概念1.3 模板可以做什么1.4 泛型模板 二、函数模板2.1 函数模板概念和格式2.2 函数模板原理2.3 函数模板实例化2.3.1 隐式实例化2.3.2 显式实例化 2.4 模板参数的匹配原则2.5 函数模板声明定义分离 三、类模…

克隆虚拟环境

conda虚拟环境 克隆clone 在服务器上想要使用别人搭好的环境&#xff0c;但是又怕自己对环境的修改更新会影响他人的使用&#xff0c;这个时候可以使用conda命令进行复制环境。 首先假设已经安装了Anaconda。 根据已有环境名复制生成新的环境 1、假设已有环境名为A&#xff0c…

Vue 子传父 组件传参 defineEmits

defineEmits 属性&#xff1a;用于创建自定义事件&#xff0c;接收子组件传递过来的数据。 注意&#xff1a;如果自定义事件的名称&#xff0c;和原生事件的名称一样&#xff0c;那么只会触发自定义事件。 defineEmits 仅适用于 setup 语法糖&#xff0c;其它写法请见&#x…

issue unit

The Issue Unit issue queue用来hold住&#xff0c;已经dispatched&#xff0c;但是还没有执行的uops&#xff1b; 当一条uop的所有的operands已经ready之后&#xff0c;request请求会被拉起来&#xff1b;然后issue select logic将会从request bit 1的slot中&#xff0c;选择…

【Spring】05 生命周期之初始化回调

文章目录 1. 回调是什么2. 初始化回调2.1 实现 InitializingBean 接口2.2 配置 init-method 3. 执行顺序4.优势及应用总结 在 Spring 框架中&#xff0c;生命周期回调&#xff08;Lifecycle Callbacks&#xff09;是一种强大的机制&#xff0c;它允许我们在 Spring 容器中的 Be…

十几个软件测试实战项目【外卖/医药/银行/电商/金融】

项目一&#xff1a;ShopNC商城 项目概况&#xff1a; ShopNC商城是一个电子商务B2C电商平台系统&#xff0c;功能强大&#xff0c;安全便捷。适合企业及个人快速构建个性化网上商城。 包含PCIOS客户端Adroid客户端微商城&#xff0c;系统PC后台是基于ThinkPHP MVC构架开发的跨…

焊盘:十字连接VS全覆盖 铺铜

在铺铜规则中&#xff0c;焊盘连接方式有两种&#xff1a; 十字连接 优点&#xff1a;较好焊接&#xff1a;因铺铜面积减少&#xff0c;温度下降速度降低&#xff0c;较好焊接&#xff0c;不易虚焊。 缺点&#xff1a;载流能力较弱&#xff1a;铺铜面积↓ → 载流能力↓全连接…

Flink 数据集类型

现实世界中&#xff0c;所有的数据都是以流式的形态产生的&#xff0c;不管是哪里产生的数据&#xff0c;在产生的过程中都是一条条地生成&#xff0c;最后经过了存储和转换处理&#xff0c;形成了各种类型的数据集。如下图所示&#xff0c;根据现实的数据产生方式和数据产生是…

面对同行恶意排挤,佳卫苗灭杀病毒HPV向市场发出灵魂五问

近期&#xff0c;抗HPV市场因为一款名叫“佳卫苗灭杀病毒HPV”的产品诞生而风起云涌。上市之初&#xff0c;产品方便表示&#xff0c;佳卫苗灭杀病毒HPV的诞生&#xff0c;不仅是为了造福患者&#xff0c;更是为了优化市场、刺激行业升级&#xff0c;以“机理更科学、材料更先进…