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