业务场景
公司有一个特殊数据购买板块。他用户可以在页面上选择指定需要的数据,并且选择一些过滤的条件,比如说年龄啊,地区等等,然后的话我就会发一个异步请求,去检索数据库返回相关的数据有多少条,最后他他输入他想要购买的条数,然后我后台就把这些数据提取相对应的条数装进一个Excel里面,然后发送一个邮件给对方的邮箱,Excel作为附件
实现步骤
导入依赖
<!--邮件发送-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>${springboot.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
配置工具类
excel读写工具类
public class ExcelUtil {
/**
* 封装Excel中的数据到指定的实体类中
* @param typeClass 指定的实体类的字节码类别
* @param readPath Excel的文件路径
* @return 指定的实体类对象的集合(每个对象代表每一条数据)
*/
public static List<T> getDataFromExcel(Class<T> typeClass , String readPath){
List<T> list = new LinkedList<>();
EasyExcel.read(readPath)
.head(typeClass)
.sheet()
.registerReadListener(new AnalysisEventListener<T>() {
@Override
public void invoke(T excelData, AnalysisContext analysisContext) {
list.add(excelData);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("数据读取完毕");
}
}).doRead();
return list;
}
/**
* 将封装好的数据写入Excel中
* @param list 写入的数据集合
* @param writePath 写入的Excel文件的路径
* @param sheet excel表中生成的sheet表名
* @param excelType 插入的excel的类别,有xls、xlsx两种
*/
public static <T> void saveDataToExcel(List<T> list, String writePath, String sheet, ExcelTypeEnum excelType, Class<T> clazz, List<String> includeColumnFiledNames) {
// 写入Excel文件
EasyExcel.write(writePath)
.head(clazz)
.excelType(excelType)
.includeColumnFiledNames(includeColumnFiledNames)
.sheet(sheet)
.doWrite(list);
}
}
邮箱发送工具类
public class PostEmailUtil {
/**
* 发送电子邮件不带附件
*/
public static Boolean sendMail(SendVO sendVO , EmailVO emailVO){
try {
Transport.send(getMimeMessage(sendVO, emailVO));
return true;
} catch (MessagingException e) {
e.printStackTrace();
return false;
}
}
/**
* 发送电子邮件带附件
*/
public static Boolean sendMailAndAttach(SendVO sendVO,EmailVO emailVO){
MimeMessage message = getMimeMessage(sendVO, emailVO);
MimeMultipart multipart = new MimeMultipart();
//正文对象
MimeBodyPart bodyPart = new MimeBodyPart();
try {
bodyPart.setContent(emailVO.getText(), emailVO.getTextEncoder());
multipart.addBodyPart(bodyPart);
//附件对象
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setFileName(emailVO.getAttachName());
imagePart.setDataHandler(new DataHandler(new ByteArrayDataSource(new BufferedInputStream(Files.newInputStream(Paths.get(emailVO.getAttachUrl()))), "application/octet-stream")));
multipart.addBodyPart(imagePart);
message.setContent(multipart);
Transport.send(message);
} catch (MessagingException | IOException e) {
e.printStackTrace();
return false;
}
return true;
}
private static MimeMessage getMimeMessage(SendVO sendVO, EmailVO emailVO) {
try {
// 连接到SMTP服务器587端口:
Properties properties = new Properties();
properties.put(EmailConstants.MAIL_SMTP_HOST, sendVO.getSmtp());
//使用SMTPS协议端口
properties.put(EmailConstants.MAIL_SMTP_PORT, EmailConstants.SMTP_PORT);
//SMTPS协议
properties.put(EmailConstants.SMTP_SOCKET_FACTORY_CLASS, EmailConstants.SSL_SOCKET_FACTORY);
//启用用户认证
properties.put(EmailConstants.MAIL_SMTP_AUTH, "true");
//启用TLS加密
properties.put(EmailConstants.MAIL_SMTP_STARTTLS_ENABLE, "true");
// 获取Session实例:
Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(sendVO.getUserName(), sendVO.getKey());
}
});
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(sendVO.getUserName()));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(sendVO.getAccept()));
message.setSubject(emailVO.getTitle(), emailVO.getTitleEncoder());
// 邮件正文
message.setText(emailVO.getText(), emailVO.getTextEncoder());
return message;
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
配置常量类记录一些通用配置
public class EmailConstants {
public static final String MAIL_SMTP_HOST = "mail.smtp.host";
/**
使用SMTPS协议端口
*/
public static final String MAIL_SMTP_PORT = "mail.smtp.port";
public static final String SMTP_PORT = "465";
/**
SMTPS协议
*/
public static final String SMTP_SOCKET_FACTORY_CLASS = "mail.smtp.socketFactory.class";
public static final String SSL_SOCKET_FACTORY = "javax.net.ssl.SSLSocketFactory";
/**
* 启用用户认证
*/
public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
/**
* 启用TLS加密
*/
public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
/**
* 发送服务器的域名(以QQ邮件为例)
*/
public static final String EMAIL_SMTP = "smtp.qq.com";
/**
发件人账号(以QQ邮件为例)
*/
public static final String EMAIL_USERNAME = "[email protected]";
/**
发件人密钥(以QQ邮件为例,这个邮件发送密钥可以在网上找个教程获取到)
*/
public static final String EMAIL_KEY = "xxxx";
/**
* 邮件主题
*/
public static final String TITLE = "邮件主题";
/**
* 主题的编码格式
*/
public static final String TITLE_ENCODER = "unicode";
/**
* 邮件正文
*/
public static final String TEXT = "您购买的数据已经打包好放置在本邮件的附件位置";
/**
* 正文的编码格式
*/
public static final String TEXT_ENCODER = "text/html;charset=utf-8";
/**
* 附件的名字
*/
public static final String ATTACH_NAME = "附件的名字";
}
发送步骤
// 生成一个excel文档存放到目标文件夹中
/* 参数1:数据列表 参数2:输出的目标路径 参数3:excel中的网页名称 参数4:excel的类型
参数5:封装类的类别 参数6:封装类中指定要输出的属性字段*/
ExcelUtil.saveDataToExcel(cardInfoList, absolution, SHEET
, ExcelTypeEnum.XLSX, CardInfo.class, includeColumnFiledNames);
// 配置邮件发送的相关数据 sendEmail——收件人的邮箱
SendVO sendVO = new SendVO(EmailConstants.EMAIL_SMTP, EmailConstants.EMAIL_USERNAME, sendEmail, EmailConstants.EMAIL_KEY);
// 发送的邮件的附件文件的路径——absolution
EmailVO emailVO = new EmailVO(EmailConstants.TITLE, EmailConstants.TITLE_ENCODER, EmailConstants.TEXT
, EmailConstants.TEXT_ENCODER, EmailConstants.ATTACH_NAME, absolution);
// 发送邮件
PostEmailUtil.sendMailAndAttach(sendVO, emailVO);