最近项目中是有个发送邮件的需求,但是需要在附件中携带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、这样就可以 不生成中间文件直接 发送附件