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;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM