最近项目中是有个发送邮件的需求,但是需要在附件中携带excel附件,这里有两种实现方式,一种是先生成文件,然后发送附件, 一种是不借助文件直接通过流的形式发送附件,这博文主要介绍通过流的方式发送excel 附件:
1、发送邮件service
package com.jack.bid.email.service;
import java.io.ByteArrayInputStream;
import java.security.GeneralSecurityException;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.util.ByteArrayDataSource;
import com.sun.mail.util.MailSSLSocketFactory;
import com.jack.common.utils.PropertiesUtils;
import org.springframework.stereotype.Service;
@Service
public class BaseMail {
public static Properties email = PropertiesUtils.getProperties("email.properties");
public static String send_email_account = email.getProperty("send_email_account");
public static String send_email_pwd = email.getProperty("send_email_pwd");
public static String email_host = email.getProperty("email_host");
/**
* 发送邮件
*
* @param to 邮件收件人地址
* @param title 邮件标题
* @param text 内容
* @param text 附件标题
* @param
*/
public void sendMsgFileDs(String to, String title, String text,String affixName, ByteArrayInputStream inputstream) {
Session session = assembleSession();
Message msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(send_email_account));
msg.setSubject(title);
msg.setRecipients(RecipientType.TO, acceptAddressList(to));
MimeBodyPart contentPart = (MimeBodyPart) createContent(text, inputstream,affixName);//参数为正文内容和附件流
MimeMultipart mime = new MimeMultipart("mixed");
mime.addBodyPart(contentPart);
msg.setContent(mime);
Transport.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
public Address[] acceptAddressList(String acceptAddress) {
// 创建邮件的接收者地址,并设置到邮件消息中
Address[] tos = null;
try {
tos = new InternetAddress[1];
tos[0] = new InternetAddress(acceptAddress);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tos;
}
public Session assembleSession() {
Session session = null;
Properties props = new Properties();
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.host", email_host);//邮件服务器
//开启安全协议
MailSSLSocketFactory sf = null;
try {
sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
} catch (GeneralSecurityException e1) {
e1.printStackTrace();
}
props.put("mail.smtp.ssl.socketFactory", sf);
props.put("mail.smtp.ssl.enable", "true");
session = Session.getDefaultInstance(props, new MyAuthenricator(send_email_account, send_email_pwd));
return session;
}
static Part createContent(String content, ByteArrayInputStream inputstream, String affixName) {
MimeBodyPart contentPart = null;
try {
contentPart = new MimeBodyPart();
MimeMultipart contentMultipart = new MimeMultipart("related");
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(content, "text/html;charset=gbk");
contentMultipart.addBodyPart(htmlPart);
//附件部分
MimeBodyPart excelBodyPart = new MimeBodyPart();
DataSource dataSource = new ByteArrayDataSource(inputstream, "application/excel");
DataHandler dataHandler = new DataHandler(dataSource);
excelBodyPart.setDataHandler(dataHandler);
excelBodyPart.setFileName(MimeUtility.encodeText(affixName));
contentMultipart.addBodyPart(excelBodyPart);
contentPart.setContent(contentMultipart);
} catch (Exception e) {
e.printStackTrace();
}
return contentPart;
}
//用户名密码验证,需要实现抽象类Authenticator的抽象方法PasswordAuthentication
static class MyAuthenricator extends Authenticator {
String u = null;
String p = null;
public MyAuthenricator(String u, String p) {
this.u = u;
this.p = p;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(u, p);
}
}
}
2、相关配置
email_host = smtp.exmail.qq.com
send_email_account=*********
send_email_pwd=*******
利用ByteArrayOutputStream把excel文件输出到bytes[]中,然后由ByteArrayResource包装起来传递给邮件服务。;
3、我发送的内容就是我上篇博客中,导出的excel的内容,下面先写一个简单的测试类
@Test
public void sendMailWithExcel() throws IOException {
@Autowired
private BaseMail mailService;
String[] headers = {"col1","col2","col3"};
// 声明一个工作薄
HSSFWorkbook wb = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(headers[i]);
}
int rowIndex = 1;
for(int j=0; j<3; j++){
row = sheet.createRow(rowIndex);
rowIndex++;
HSSFCell cell1 = row.createCell(0);
cell1.setCellValue(j);
cell1 = row.createCell(1);
cell1.setCellValue(j+1);
cell1 = row.createCell(2);
cell1.setCellValue(j+2);
}
for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
}
ByteArrayOutputStream os = new ByteArrayOutputStream(1000);
wb.write(os);
wb.close();
ByteArrayInputStream iss = new ByteArrayInputStream(os.toByteArray());
os.close();
mailService.sendMsgFileDs("xjj@qq.com",
"attachmentMail subject",
"I have an attachment",
"attachment name",
iss);
注意:附件需要带后缀,例如上面例子,附件名称可以写 测试.xlsx
}
}
4、这样就可以 不生成中间文件直接 发送附件