java 发邮件带excel附件,以流的形式发送附件,不生成excel文件

欧阳狐若
2023-12-01

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

 类似资料: