一、需求
前端表格数据选择多条记录,填写收件人邮箱地址实现数据的邮件发送。
下面例子为QQ邮箱->收件人邮箱
二、先看实现结果
三、代码实现
1. 代码结构
2. pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version> <!-- lookup parent from repository -->
</parent>
<groupId>com.email</groupId>
<artifactId>email-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>email-test</name>
<description>email-test</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 邮箱发送需要的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!-- thymeleaf模板渲染需要的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. applation.yml文件
spring:
mail:
host: smtp.qq.com #SMTP 主机地址,指定邮件发送服务器的地址,这里设置为 QQ 邮箱的 SMTP 服务器地址
port: 587 #SMTP 端口号,指定 SMTP 服务器的端口号,这里设置为 QQ 邮箱的 SMTP 服务器端口号。
username: 1144@qq.com #SMTP 用户名,指定用于 SMTP 认证的用户名,这里设置为 QQ 邮箱的用户名。
password: waiegkddemlgjcie #SMTP 密码,指定用于 SMTP 认证的密码,这里设置为 QQ 邮箱的授权码。 不是QQ邮箱密码是授权码切记 没有的你启动会报错,点击报错的链接注册一个授权码就可以了
properties:
mail:
smtp:
starttls:
enable: true #SMTP 的 STARTTLS 加密协议开关,启用 TLS 安全连接,防止邮件传输过程中被窃听或篡改。
thymeleaf:
prefix: classpath:/templates/ #Thymeleaf 模板引擎的前缀路径,指定 Thymeleaf 模板文件所在的路径,这里设置为 classpath:/templates/,表示模板文件位于项目的 classpath 下的 templates 目录中。
4. EmailVO代码
package com.email.vo;
import lombok.Data;
@Data
public class EmailVO {
// 序号
private String id;
// 到货日期
private String deliveryDate;
// 物料编码
private String partCode;
// 物料名称
private String partName;
// 规格型号
private String spec;
// 状态
private String status;
// 费用科目
private String expenseAccountName;
// 单位
private String uom;
// 数量
private String number;
// 成本中心
private String costCenterName;
// 采购订单号
private String aribaPo;
// 采购
private String purchaser;
// 部门
private String deptName;
// 供应商
private String supplier;
// 日报截取时间
private String dailyTime;
// 规定D
private String regulation;
// 入库D
private String inStore;
// 差异D
private String difference;
// 备注
private String remarks;
// 是否制造
private String validFlag;
// 负责人
private String responsiblePerson;
// 部门leader
private String deptLeader;
// 其他
private String other;
// 原因
private String reason;
// 签字入库
private String signedBy;
}
5. Controller代码
package com.email.controller;
import com.email.service.EmailService;
import com.email.vo.EmailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.mail.MessagingException;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/email")
public class EmailController {
@Autowired
private EmailService emailService;
@RequestMapping(value = "/send", method = RequestMethod.POST)
public void send(@RequestBody List<EmailVO> emailVO, String to) throws MessagingException {
emailService.sendEmail(emailVO, to);
}
}
6. Service代码
package com.email.service;
import com.email.vo.EmailVO;
import java.util.List;
public interface EmailService {
void sendEmail(List<EmailVO> emailVO, String to);
}
7. Serviceimpl代码
package com.email.service.impl;
import com.email.service.EmailService;
import com.email.vo.EmailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.List;
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private SpringTemplateEngine templateEngine;
@Override
public void sendEmail(List<EmailVO> emailVO, String to) {
try {
// 正文内容
String text = null;
Context context = new Context();
context.setVariable("emailVO", emailVO);
// 使用Thymeleaf引擎解析模板,并将数据填充到模板中
text = templateEngine.process("abc", context);
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = null;
helper = new MimeMessageHelper(message, true);
// 前收件人邮箱->前端传递
helper.setTo(to);
// 主题自定义
helper.setSubject("物料报废");
helper.setText(text, true);
// 发件人的地址应该与 SMTP 服务器上的认证用户名一致,否则可能会导致 SMTP 服务器返回认证失败的错误信息
message.setFrom("1144@qq.com");
// 邮件发送
javaMailSender.send(message);
log.info("邮件发送成功,已发送到邮箱" + to);
} catch (MessagingException e) {
log.error("测试发送失败," + e);
}
}
}
8. 模板代码abc.html
<table align="center" width="100%" xmlns:th="http://www.thymeleaf.org">
<tr>
<th style="border: 1px solid black;" align="center" valign="middle">序号</th>
<th style="border: 1px solid black;" align="center" valign="middle">到货日期</th>
<th style="border: 1px solid black;" align="center" valign="middle">物料编码</th>
<th style="border: 1px solid black;" align="center" valign="middle">物料名称</th>
<th style="border: 1px solid black;" align="center" valign="middle">规格型号</th>
<th style="border: 1px solid black;" align="center" valign="middle">状态</th>
<th style="border: 1px solid black;" align="center" valign="middle">费用科目</th>
<th style="border: 1px solid black;" align="center" valign="middle">单位</th>
<th style="border: 1px solid black;" align="center" valign="middle">数量</th>
<th style="border: 1px solid black;" align="center" valign="middle">成本中心</th>
<th style="border: 1px solid black;" align="center" valign="middle">采购订单号</th>
<th style="border: 1px solid black;" align="center" valign="middle">采购</th>
<th style="border: 1px solid black;" align="center" valign="middle">部门</th>
<th style="border: 1px solid black;" align="center" valign="middle">供应商</th>
<th style="border: 1px solid black;" align="center" valign="middle">日报截取时间</th>
<th style="border: 1px solid black;" align="center" valign="middle">规定D</th>
<th style="border: 1px solid black;" align="center" valign="middle">入库D</th>
<th style="border: 1px solid black;" align="center" valign="middle">差异D</th>
<th style="border: 1px solid black;" align="center" valign="middle">备注</th>
<th style="border: 1px solid black;" align="center" valign="middle">是否制造</th>
<th style="border: 1px solid black;" align="center" valign="middle">负责人</th>
<th style="border: 1px solid black;" align="center" valign="middle">部门leader</th>
<th style="border: 1px solid black;" align="center" valign="middle">其他</th>
<th style="border: 1px solid black;" align="center" valign="middle">原因</th>
<th style="border: 1px solid black;" align="center" valign="middle">签字入库</th>
</tr>
<!-- 遍历emailVO列表,并在表格中添加每一行数据 -->
<tbody>
<tr th:each="vo : ${emailVO}">
<td style="border: 1px solid black;" th:text="${vo.id}"></td>
<td style="border: 1px solid black;" th:text="${vo.deliveryDate}"></td>
<td style="border: 1px solid black;" th:text="${vo.partCode}"></td>
<td style="border: 1px solid black;" th:text="${vo.partName}"></td>
<td style="border: 1px solid black;" th:text="${vo.spec}"></td>
<td style="border: 1px solid black;" th:text="${vo.status}"></td>
<td style="border: 1px solid black;" th:text="${vo.expenseAccountName}"></td>
<td style="border: 1px solid black;" th:text="${vo.uom}"></td>
<td style="border: 1px solid black;" th:text="${vo.number}"></td>
<td style="border: 1px solid black;" th:text="${vo.costCenterName}"></td>
<td style="border: 1px solid black;" th:text="${vo.aribaPo}"></td>
<td style="border: 1px solid black;" th:text="${vo.purchaser}"></td>
<td style="border: 1px solid black;" th:text="${vo.deptName}"></td>
<td style="border: 1px solid black;" th:text="${vo.supplier}"></td>
<td style="border: 1px solid black;" th:text="${vo.dailyTime}"></td>
<td style="border: 1px solid black;" th:text="${vo.regulation}"></td>
<td style="border: 1px solid black;" th:text="${vo.inStore}"></td>
<td style="border: 1px solid black;" th:text="${vo.difference}"></td>
<td style="border: 1px solid black;" th:text="${vo.remarks}"></td>
<td style="border: 1px solid black;" th:text="${vo.validFlag}"></td>
<td style="border: 1px solid black;" th:text="${vo.responsiblePerson}"></td>
<td style="border: 1px solid black;" th:text="${vo.deptLeader}"></td>
<td style="border: 1px solid black;" th:text="${vo.other}"></td>
<td style="border: 1px solid black;" th:text="${vo.reason}"></td>
<td style="border: 1px solid black;" th:text="${vo.signedBy}"></td>
</tr>
</tbody>
</table>
这里面的样式可以根据自己需求,我的这个样式效果在最上面。
9. 测试数据
[
{
"id": "123",
"deliveryDate": "123",
"partCode": "123",
"partName": "123",
"spec": "123",
"status": "123",
"expenseAccountName": "123",
"uom": "123",
"number": "123",
"costCenterName": "123",
"aribaPo": "123",
"purchaser": "123",
"deptName": "123",
"supplier": "123",
"dailyTime": "123",
"regulation": "123",
"inStore": "321",
"difference": "123",
"remarks": "123",
"validFlag": "123",
"responsiblePerson": "123",
"deptLeader": "123",
"other": "123",
"reason": "123",
"signedBy": "123"
},
{
"id": "456",
"deliveryDate": "456",
"partCode": "456",
"partName": "456",
"spec": "456",
"status": "456",
"expenseAccountName": "456",
"uom": "456",
"number": "456",
"costCenterName": "456",
"aribaPo": "456",
"purchaser": "456",
"deptName": "456",
"supplier": "456",
"dailyTime": "456",
"regulation": "456",
"inStore": "456",
"difference": "456",
"remarks": "456",
"validFlag": "456",
"responsiblePerson": "456",
"deptLeader": "456",
"other": "456",
"reason": "456",
"signedBy": "456"
}
]
测试数据都准备好了够意思吧。去跑着玩玩吧。