java 发送附件邮件(完整代码)

需求:

        客户需要把查询出来的数据放到excel文档中,并且把附件发送到邮箱。

涉及思路:

        1、easypoi技术来写入excel文档;

        2、jakarta.mail技术来发送附件邮件;

使用的技术:

        poi-4.1.1.jar

        easypoi-base-4.3.0.jar

        easypoi-annotation-4.3.0.jar

        jakarta.mail-1.6.5.jar

代码实现:

      1、公共类:

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 导出Excel文档工具类
 */
public class PoiExcelUtil {
    
    
    /**
     * excel导出公共接口   支持一文档多sheet页
     * @param response
     * @param fileName    文件名  格式:测试.xls
     * @param sheetsList  sheet集合
     *    格式如下:
     *       每个sheet需要这样写:【Map的key是固定写死的,不用改】
     *      ExportParams exportParams = new ExportParams(null, "出国备案", ExcelType.HSSF);    title标题,sheet页名称,类型【固定就这样写】
     *         exportMap.put("title", exportParams);
     *         exportMap.put("entity", SearchRecordRespBean.class);  导出实体类【需要自己写一个】
     *         exportMap.put("data", recordList);              数据列表,必须是List集合。数组会报错
     *
     */
    public static void downExcel(HttpServletResponse response, String fileName, List<Map<String, Object>> sheetsList){
        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
        if("xlsx".equals(fileName.substring(fileName.indexOf("."),fileName.length()))){
            workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.XSSF);
        }
        //导出Excel
        try {
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    
    public static InputStream excelInputStream( String fileName, List<Map<String, Object>> sheetsList) throws IOException {
        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
        if("xlsx".equals(fileName.substring(fileName.indexOf("."),fileName.length()))){
            workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.XSSF);
        }
        // 将 Workbook 写入字节数组输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        return inputStream;
    }



    public static void responseWorkbook(HttpServletResponse response, String path, List<Map<String, Object>> list, String fileName) {
        // 获取模板数据
        TemplateExportParams params = new TemplateExportParams(path, 0);
        HashMap<String, Object> workbookNeedMap = new HashMap<>();
        workbookNeedMap.put("maps", list);
        try {
            // 导出,并获取工作簿
            Workbook workbook = ExcelExportUtil.exportExcel(params, workbookNeedMap);
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());

            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}


import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;

import java.io.Serializable;


@Data
public class DirectorExcelBean implements Serializable {
    /**
     *备案号
     */
    @Excel(name = "公司名称", needMerge = true, width = 60.0)
    private String company;
    
    /**
     * 单位名称
     */
    @Excel(name = "会议", needMerge = true, width = 100.0)
    private String meeting;
}
2、邮件封装类:


import lombok.Data;

import java.io.InputStream;
import java.util.List;

@Data
public class Mail {
    
    /**
     * 收件人
     */
    private List<String> to;
    /**
     * 发件人
     */
    private String from;
    /**
     * SMTP主机
     */
    private String host;
    /**
     * 发件人的用户名
     */
    private String username;
    /**
     * 发件人的密码
     */
    private String password;
    /**
     * 邮件主题
     */
    private String subject;
    /**
     * 邮件正文
     */
    private String content;
    
    private String attachmentName;
    
    private InputStream attachmentStream;
}
3、整体代码实现:
public void toSendEmailMessage() {
        //excel列表的数据
        List<DirectorExcelBean> recordList = new ArrayList<>(); 
        
        List<Map<String, Object>> sheetsList = Lists.newArrayList();
        Map<String, Object> exportMap = Maps.newHashMap();
        ExportParams exportParams = new ExportParams(null, "未开会公司", ExcelType.HSSF);
        exportMap.put("title", exportParams);
        exportMap.put("entity", DirectorExcelBean.class);
        exportMap.put("data", recordList);
        // 加入多sheet配置列表
        sheetsList.add(exportMap);
        try {
            //附件输入流
            InputStream inputStream = PoiExcelUtil.excelInputStream("董事会预警.xls", sheetsList);
            //给多人发送邮件
            List<String> ss = new ArrayList<>();
            ss.add("123@qq.com");
        //组装数据
            sendMail(ss,"邮件标题","邮件内容【有附件,请下载查看】",inputStream,"附件名字.xls");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        
    }


 public void sendMail(List<String> emails, String subject, String content, InputStream attachmentStream, String attachmentName) {
        Mail mail = new Mail(); 
        mail.setHost("smtp.163.com");  //发件人的邮箱的 SMTP 服务器地址
        mail.setUsername("ss@163.com"); // 设置发件人邮箱的用户名
        mail.setPassword("*"); // 设置发件人邮箱的密码,需将*号邮箱的授权码
        mail.setFrom("ss@163.com"); // 设置发件人的邮箱
        mail.setTo(emails); // 设置收件人的邮箱
        mail.setSubject(subject); // 设置邮件的主题
        mail.setContent(content); // 设置邮件的正文
        mail.setAttachmentName(attachmentName);
        mail.setAttachmentStream(attachmentStream);
        
        if (mailReady(mail)) { // 发送邮件
            System.out.println("发送成功!");
        } else {
            System.out.println("发送失败!");
        }
    }
    
    /**
     * 获取发送邮件信息
     *
     * @param mb
     */
    public boolean mailReady(Mail mb) {
        String host = mb.getHost();
        final String username = mb.getUsername();
        final String password = mb.getPassword();
        String from = mb.getFrom();
        List<String> toList = mb.getTo();
        String subject = mb.getSubject();
        String content = mb.getContent();
        InputStream attachmentStream = mb.getAttachmentStream(); // 获取附件流
        String attachmentName = mb.getAttachmentName(); // 获取附件名称
        
        Properties props = System.getProperties();
        props.put("mail.smtp.host", host); // 设置SMTP的主机
        props.put("mail.smtp.auth", "true"); // 需要经过验证
        Session session = Session.getInstance(props, new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);//接收邮件的用户名和密码
            }
        });
        try {
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(from));
            InternetAddress[] address = new InternetAddress().parse(String.join(",",toList));
            msg.setRecipients(Message.RecipientType.TO, address);
            try {
                msg.setSubject(MimeUtility.encodeWord(subject, "UTF-8", "Q"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 创建消息部分
            BodyPart messageBodyPart = new MimeBodyPart();
            // 填写邮件内容
            messageBodyPart.setContent(content, "text/html;charset=UTF-8");
            
            Multipart multipart = new MimeMultipart();
            // 添加邮件内容到multipart.
            multipart.addBodyPart(messageBodyPart);
            
            // 如果有附件,则添加附件
            if (attachmentStream != null && attachmentName != null && !attachmentName.isEmpty()) {
                messageBodyPart = new MimeBodyPart();
                DataSource source = new ByteArrayDataSource(attachmentStream, "application/octet-stream");
                messageBodyPart.setDataHandler(new DataHandler(source));
                messageBodyPart.setFileName(MimeUtility.encodeWord(attachmentName));
                multipart.addBodyPart(messageBodyPart);
            }
            msg.setContent(multipart);
            msg.setSentDate(new Date());
            Transport.send(msg);
            
        } catch (Exception me) {
            me.printStackTrace();
            return false;
        }
        return true;
    }

借鉴地址:https://blog.youkuaiyun.com/lovewebeye/article/details/107294042

报错解决方案:

javax.mail.AuthenticationFailedException: 535 Error: authentication failed解决办法【邮箱的授权码开启方式】:

点击跳转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值