Java搭建邮件服务器并发送Excel附件

1.配置文件yml (这里读取的是配置文件的发送邮箱账号,可以自行取值)

server:
  port: 8888
  servlet:
    #    # 项目contextPath
    context-path: /mailserv

spring:
  application:
    name: mailserv



#设置静态资源路径,多个以逗号分隔
spring.resources.static-locations: classpath:static/,file:static/

# 日志配置
logging:
  level:
    mail: debug
    org.springframework: WARN
    org.spring.springboot.dao: debug

mail:
  #发送方
  from: xxxx@qq.com
  #登录的公司邮箱
  username: xxx@qq.com
  #这里如果有独立密码的要用独立密码,没有的使用登录密码
  password: xxxxxx

 

2.bean和Properties

package mail.bean;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class MailInfo implements Serializable {

    private static final long serialVersionUID = 4280650483975256784L;
    // 邮件发送者的标示
    private String key;
    // 邮件发送者的邮箱
    private String from;
    //登陆邮件发送服务器的用户名和密码(授权码)
    private String mailAccount;
    private String mailPassword;
    //收件人名字
    private String senderAlias;
    // 邮件接收者的地址数组
    private List<String> receiveAddressArray;
    // 邮件主题
    private String subject;
    // 邮件的文本内容
    private String content;
    // 邮件附件的文件名
    private String[] attachFileNames;
    //发送邮件用到的Excel相关信息和数据
    private List<ExcelFile> excelFiles;


    /**
     * 发送邮件用到的Excel相关信息和数据
     */
    @Data
    public  static class ExcelFile {
        //文件名
        private String fileName;
        //字节数组
        private byte[] byteArray;
        //html格式内容
        private String htmlContent;

    }

}
// 读取配置文件中我们自定义的发送邮件的参数
@Data
@Configuration
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
    //登录的公司邮箱
    private String from;
    //登录的公司邮箱
    private String username;
    //这里用客户端的密码,不是登录密码
    private String password;

}

 

3.工具类

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.Authenticator;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.util.List;
import java.util.Properties;


/**
 * 发送腾讯企业邮件工具类
 */
public class SendUtil {
    // 腾讯企业邮箱的smtp服务器
    public final static String HOST = "smtp.exmail.qq.com";
    public final static String PORT = "465";

    /**
     * 发送邮件
     *
     * @param mailInfo 邮件相关参数配置和数据信息
     * @throws Exception
     */
    public static void send(MailInfo mailInfo) throws Exception {
        //excel附件相关信息
        List<ExcelFile> excelFiles = mailInfo.getExcelFiles();

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", HOST);
        props.put("mail.smtp.port", PORT);
        props.put("mail.smtp.ssl.enable", "true");

        //用户的公司邮箱
        String username = mailInfo.getMailAccount();
        //这里用客户端的密码,不是登录密码
        String password = mailInfo.getMailPassword();
        //发送方
        String from = mailInfo.getFrom();
        //接收方
        List<String> recipients = mailInfo.getReceiveAddressArray();
        //内容(前面位置)
        String content = mailInfo.getContent();
        //主题
        String subJect = mailInfo.getSubject();

        //认证
        Authenticator smtpAuth = new PopupAuthenticator(from, password);

        Session session = Session.getDefaultInstance(props, smtpAuth);
        session.setDebug(true);
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));

        //多个收件人
        int num = recipients.size();
        InternetAddress[] rece_addresses = new InternetAddress[recipients.size()];
        for (int i = 0; i < num; i++) {
            rece_addresses[i] = new InternetAddress(recipients.get(i));
        }
        message.setRecipients(Message.RecipientType.TO, rece_addresses);

        /*附件*/
        // 容器类 附件
        MimeMultipart mimeMultipart = new MimeMultipart();
        // 可以包装文本,图片,附件
        MimeBodyPart mimeBodyPart = new MimeBodyPart();
        // 设置内容
        mimeBodyPart.setContent(content, "text/html; charset=UTF-8");
        mimeMultipart.addBodyPart(mimeBodyPart);

        /*读取excelFiles的信息并添加到邮件*/
        if (CollectionUtils.isNotEmpty(excelFiles)) {

            for (ExcelFile excelFile : excelFiles) {
                byte[] byteArray = excelFile.getByteArray();
                String fileName = excelFile.getFileName();
                String htmlContent = excelFile.getHtmlContent();

                //添加读取到的excel内容到邮件
                if (StringUtils.isNotBlank(htmlContent)) {
                    MimeBodyPart mimeBodyPartExcelText = new MimeBodyPart();
                    mimeBodyPartExcelText.setContent(htmlContent, "text/html; charset=UTF-8");
                    mimeMultipart.addBodyPart(mimeBodyPartExcelText);
                }

                /*添加附件*/
                if (byteArray != null) {
                    MimeBodyPart fileBody = new MimeBodyPart();
                    DataSource source = new ByteArrayDataSource(byteArray, "application/msexcel");
                    fileBody.setDataHandler(new DataHandler(source));
                    if (StringUtils.isBlank(fileName)) {
                        fileName = "未命名文件";
                    }
                    // 中文乱码问题
                    fileBody.setFileName(MimeUtility.encodeText(fileName));
                    mimeMultipart.addBodyPart(fileBody);
                }
            }
        }

        message.setContent(mimeMultipart);

        message.setSubject(subJect);
        message.saveChanges();

        Transport transport = session.getTransport("smtp");

        transport.connect(HOST, username, password);
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
    }


}


class PopupAuthenticator extends Authenticator {
    String username = null;
    String password = null;


    public PopupAuthenticator() {
    }

    public PopupAuthenticator(String username, String password) {
        this.username = username;
        this.password = password;
    }


    PasswordAuthentication performCheck(String user, String pass) {
        username = user;
        password = pass;
        return getPasswordAuthentication();
    }


    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }


}

4.发送邮件的Service帮助类

/**
 * 发送邮件的Service帮助类
 *
 * @author admin
 */
@Service
public class MailServiceHelper   {
    private static final Logger logger = LoggerFactory.getLogger(MailServiceHelper.class);

    @Autowired
    private MailProperties mailProperties;

    /**
     * 发送邮件,这里账号密码写到配置文件中
     * @param mailInfo
     */
    public void sendMail(MailInfo mailInfo) throws Exception {
        //添加发送人,账号和密码
        mailInfo.setFrom(mailProperties.getFrom());
        mailInfo.setMailAccount(mailProperties.getUsername());
        mailInfo.setMailPassword(mailProperties.getPassword());
        SendUtil.send(mailInfo);
    }
}

 

5.controller

@Controller
public class SendMailController {
    private static final Logger logger = LoggerFactory.getLogger(SendMailController.class);

    @Autowired
    private MailServiceHelper mailServiceHelper;

    /**
     * 发送邮件
     *
     * @param mailInfo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "sendMail", method = RequestMethod.POST)
    public Map<String, Object> sendMail(@RequestBody MailInfo mailInfo) {
        String msg = null;
        logger.info("发送邮件开始");
        if (mailInfo == null) {
            msg = "发送邮件失败!原因:数据为空!!!";
            logger.error(msg);
            return RespUtils.badResponse(msg);
        }

        try {
            //发送
            mailServiceHelper.sendMail(mailInfo);
        } catch (Exception e) {
            logger.error("发送邮件失败!!", e);
            return RespUtils.badResponse("发送邮件失败!!");
        }

        System.out.println("mailInfo :" + mailInfo);
        return RespUtils.sucResp("发送成功!", null);
    }

}

 

6. 测试

    @Test
    public void sendPostToAttach() throws Exception {
        Properties props = new Properties();
        String host = "smtp.exmail.qq.com"; // 腾讯企业邮箱的smtp服务器
        String to = "611766xxx@qq.com";     // 邮件要发送到的邮箱地址
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", host);
        String content = "hello";
        String subJect = "这是一个好消息1";
        //发送邮件VO
        MailInfo mailInfo = new MailInfo();
        mailInfo.setSubject( subJect);
        mailInfo.setContent(content);
        //收件人
        List<String> receiveAddressArray = new ArrayList<>();
        receiveAddressArray.add(to);
        mailInfo.setReceiveAddressArray(receiveAddressArray);

        //获取excel
        MailInfo.ExcelFile excelFile = TestWrite.writeToMail();
        ArrayList<MailInfo.ExcelFile> list = Lists.newArrayList();
        list.add(excelFile);

        mailInfo.setExcelFiles(list);
        String json = JSONObject.toJSONString(mailInfo);

        //远程调用接口 http://localhost:8888/mailserv/sendMail
        String res = HttpJson.httpPostWithjson("http://localhost:8888/mailserv/sendMail", json);
        System.out.println("res :" + res);

    }
    /**
     * 使用byte数组写入excle发送邮件***重点是红色部分**这里使用eazyexcel
     *
     * @throws IOException
     */
    public static MailInfo.ExcelFile writeToMail() {
        //输出流放excel数据
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        //获取头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
        //列宽的策略,宽度是小单位
        Integer columnWidthArr[] = {3000, 6000};
        List<Integer> columnWidths = Arrays.asList(columnWidthArr);
        CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);

        // 根据用户传入字段 假设我们只要导出 string date
        String[] filds = {"string", "date"};

        //获取模拟的实体数据集合
        List<DemoData> demoDataList = getDemoDataList();

        //创建工作簿到流中
        //这里需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(os, DemoData.class)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(customSheetWriteHandler)
                //这个是导出需要展示的列
                .includeColumnFiledNames(Arrays.asList(filds))
                .sheet("模板")
                .doWrite(demoDataList);
        //保存字节数组
        MailInfo.ExcelFile excelFile = new MailInfo.ExcelFile();
        excelFile.setByteArray(os.toByteArray());
        return excelFile;
    }

 

posted @ 2020-06-08 19:12  将军上座  阅读(1503)  评论(0编辑  收藏  举报