1.配置文件yml (这里读取的是配置文件的发送邮箱账号,可以自行取值)
server:
port: 8888
servlet:
# # 项目contextPath
context-path: /mailserv
spring:
application:
name: mailserv
#设置静态资源路径,多个以逗号分隔
spring.resources.static-locations: classpath:static/,file:static/
# 日志配置
logging:
level:
mail: debug
org.springframework: WARN
org.spring.springboot.dao: debug
mail:
#发送方
from: xxxx@qq.com
#登录的公司邮箱
username: xxx@qq.com
#这里如果有独立密码的要用独立密码,没有的使用登录密码
password: xxxxxx
2.bean和Properties
package mail.bean;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class MailInfo implements Serializable {
private static final long serialVersionUID = 4280650483975256784L;
// 邮件发送者的标示
private String key;
// 邮件发送者的邮箱
private String from;
//登陆邮件发送服务器的用户名和密码(授权码)
private String mailAccount;
private String mailPassword;
//收件人名字
private String senderAlias;
// 邮件接收者的地址数组
private List<String> receiveAddressArray;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
// 邮件附件的文件名
private String[] attachFileNames;
//发送邮件用到的Excel相关信息和数据
private List<ExcelFile> excelFiles;
/**
* 发送邮件用到的Excel相关信息和数据
*/
@Data
public static class ExcelFile {
//文件名
private String fileName;
//字节数组
private byte[] byteArray;
//html格式内容
private String htmlContent;
}
}
// 读取配置文件中我们自定义的发送邮件的参数
@Data
@Configuration
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
//登录的公司邮箱
private String from;
//登录的公司邮箱
private String username;
//这里用客户端的密码,不是登录密码
private String password;
}
3.工具类
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.Authenticator;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.util.List;
import java.util.Properties;
/**
* 发送腾讯企业邮件工具类
*/
public class SendUtil {
// 腾讯企业邮箱的smtp服务器
public final static String HOST = "smtp.exmail.qq.com";
public final static String PORT = "465";
/**
* 发送邮件
*
* @param mailInfo 邮件相关参数配置和数据信息
* @throws Exception
*/
public static void send(MailInfo mailInfo) throws Exception {
//excel附件相关信息
List<ExcelFile> excelFiles = mailInfo.getExcelFiles();
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", HOST);
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.ssl.enable", "true");
//用户的公司邮箱
String username = mailInfo.getMailAccount();
//这里用客户端的密码,不是登录密码
String password = mailInfo.getMailPassword();
//发送方
String from = mailInfo.getFrom();
//接收方
List<String> recipients = mailInfo.getReceiveAddressArray();
//内容(前面位置)
String content = mailInfo.getContent();
//主题
String subJect = mailInfo.getSubject();
//认证
Authenticator smtpAuth = new PopupAuthenticator(from, password);
Session session = Session.getDefaultInstance(props, smtpAuth);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
//多个收件人
int num = recipients.size();
InternetAddress[] rece_addresses = new InternetAddress[recipients.size()];
for (int i = 0; i < num; i++) {
rece_addresses[i] = new InternetAddress(recipients.get(i));
}
message.setRecipients(Message.RecipientType.TO, rece_addresses);
/*附件*/
// 容器类 附件
MimeMultipart mimeMultipart = new MimeMultipart();
// 可以包装文本,图片,附件
MimeBodyPart mimeBodyPart = new MimeBodyPart();
// 设置内容
mimeBodyPart.setContent(content, "text/html; charset=UTF-8");
mimeMultipart.addBodyPart(mimeBodyPart);
/*读取excelFiles的信息并添加到邮件*/
if (CollectionUtils.isNotEmpty(excelFiles)) {
for (ExcelFile excelFile : excelFiles) {
byte[] byteArray = excelFile.getByteArray();
String fileName = excelFile.getFileName();
String htmlContent = excelFile.getHtmlContent();
//添加读取到的excel内容到邮件
if (StringUtils.isNotBlank(htmlContent)) {
MimeBodyPart mimeBodyPartExcelText = new MimeBodyPart();
mimeBodyPartExcelText.setContent(htmlContent, "text/html; charset=UTF-8");
mimeMultipart.addBodyPart(mimeBodyPartExcelText);
}
/*添加附件*/
if (byteArray != null) {
MimeBodyPart fileBody = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(byteArray, "application/msexcel");
fileBody.setDataHandler(new DataHandler(source));
if (StringUtils.isBlank(fileName)) {
fileName = "未命名文件";
}
// 中文乱码问题
fileBody.setFileName(MimeUtility.encodeText(fileName));
mimeMultipart.addBodyPart(fileBody);
}
}
}
message.setContent(mimeMultipart);
message.setSubject(subJect);
message.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(HOST, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
}
class PopupAuthenticator extends Authenticator {
String username = null;
String password = null;
public PopupAuthenticator() {
}
public PopupAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
PasswordAuthentication performCheck(String user, String pass) {
username = user;
password = pass;
return getPasswordAuthentication();
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
4.发送邮件的Service帮助类
/**
* 发送邮件的Service帮助类
*
* @author admin
*/
@Service
public class MailServiceHelper {
private static final Logger logger = LoggerFactory.getLogger(MailServiceHelper.class);
@Autowired
private MailProperties mailProperties;
/**
* 发送邮件,这里账号密码写到配置文件中
* @param mailInfo
*/
public void sendMail(MailInfo mailInfo) throws Exception {
//添加发送人,账号和密码
mailInfo.setFrom(mailProperties.getFrom());
mailInfo.setMailAccount(mailProperties.getUsername());
mailInfo.setMailPassword(mailProperties.getPassword());
SendUtil.send(mailInfo);
}
}
5.controller
@Controller
public class SendMailController {
private static final Logger logger = LoggerFactory.getLogger(SendMailController.class);
@Autowired
private MailServiceHelper mailServiceHelper;
/**
* 发送邮件
*
* @param mailInfo
* @return
*/
@ResponseBody
@RequestMapping(value = "sendMail", method = RequestMethod.POST)
public Map<String, Object> sendMail(@RequestBody MailInfo mailInfo) {
String msg = null;
logger.info("发送邮件开始");
if (mailInfo == null) {
msg = "发送邮件失败!原因:数据为空!!!";
logger.error(msg);
return RespUtils.badResponse(msg);
}
try {
//发送
mailServiceHelper.sendMail(mailInfo);
} catch (Exception e) {
logger.error("发送邮件失败!!", e);
return RespUtils.badResponse("发送邮件失败!!");
}
System.out.println("mailInfo :" + mailInfo);
return RespUtils.sucResp("发送成功!", null);
}
}
6. 测试
@Test
public void sendPostToAttach() throws Exception {
Properties props = new Properties();
String host = "smtp.exmail.qq.com"; // 腾讯企业邮箱的smtp服务器
String to = "611766xxx@qq.com"; // 邮件要发送到的邮箱地址
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", host);
String content = "hello";
String subJect = "这是一个好消息1";
//发送邮件VO
MailInfo mailInfo = new MailInfo();
mailInfo.setSubject( subJect);
mailInfo.setContent(content);
//收件人
List<String> receiveAddressArray = new ArrayList<>();
receiveAddressArray.add(to);
mailInfo.setReceiveAddressArray(receiveAddressArray);
//获取excel
MailInfo.ExcelFile excelFile = TestWrite.writeToMail();
ArrayList<MailInfo.ExcelFile> list = Lists.newArrayList();
list.add(excelFile);
mailInfo.setExcelFiles(list);
String json = JSONObject.toJSONString(mailInfo);
//远程调用接口 http://localhost:8888/mailserv/sendMail
String res = HttpJson.httpPostWithjson("http://localhost:8888/mailserv/sendMail", json);
System.out.println("res :" + res);
}
/**
* 使用byte数组写入excle发送邮件***重点是红色部分**这里使用eazyexcel
*
* @throws IOException
*/
public static MailInfo.ExcelFile writeToMail() {
//输出流放excel数据
ByteArrayOutputStream os = new ByteArrayOutputStream();
//获取头和内容的策略
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
//列宽的策略,宽度是小单位
Integer columnWidthArr[] = {3000, 6000};
List<Integer> columnWidths = Arrays.asList(columnWidthArr);
CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);
// 根据用户传入字段 假设我们只要导出 string date
String[] filds = {"string", "date"};
//获取模拟的实体数据集合
List<DemoData> demoDataList = getDemoDataList();
//创建工作簿到流中
//这里需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(os, DemoData.class)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(customSheetWriteHandler)
//这个是导出需要展示的列
.includeColumnFiledNames(Arrays.asList(filds))
.sheet("模板")
.doWrite(demoDataList);
//保存字节数组
MailInfo.ExcelFile excelFile = new MailInfo.ExcelFile();
excelFile.setByteArray(os.toByteArray());
return excelFile;
}