欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot使用JavaMailSender實現(xiàn)發(fā)送郵件+Excel附件

 更新時間:2023年10月31日 09:37:59   作者:困知勉行1985  
項目審批完畢后,需要發(fā)送郵件通知相關(guān)人員,并且要附帶數(shù)據(jù)庫表生成的Excel表格,這就要求不光是郵件發(fā)送功能,還要臨時生成Excel表格做為附件,本文詳細介紹了SpringBoot如何使用JavaMailSender實現(xiàn)發(fā)送郵件+Excel附件,需要的朋友可以參考下

需求描述:項目審批完畢后,需要發(fā)送郵件通知相關(guān)人員,并且要附帶數(shù)據(jù)庫表生成的Excel表格,這就要求不光是郵件發(fā)送功能,還要臨時生成Excel表格做為附件

1.生成Excel表格

使用huTool工具包的Excel表格生成功能

1.依賴設(shè)置

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.22</version>
</dependency>

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
</dependency>

Hutool-all中包含了Hutool的所有工具類,由于需要生成Excel文件需要依賴poi

2.代碼:

    @Override
    public void publish(xxxxxxPublishVo publishVo) {
        /**
         * 生成Excel表格
         */
        //在內(nèi)存操作,寫到輸出流中
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定義標題別名
        writer.addHeaderAlias("projectCode", "xx編號");
        writer.addHeaderAlias("projectName", "xx名稱");
        writer.addHeaderAlias("targetType", "xx類型");
        writer.addHeaderAlias("targetName", "xx名稱");
        writer.addHeaderAlias("targetForMp", "xxxx目標");
        writer.addHeaderAlias("symbols", "xx限制符");
        //獲取數(shù)據(jù)
        QpmxxxxTargetMg query = new QpmxxxxTargetMg();
        query.setProjectCode(publishVo.getProjectCode());
        List<xxxxxxListDTO> data =  selectxxxxxxByCondition(query);
 
        //整理數(shù)據(jù),以便于生成Excel表格
        List<Object> dataNew = new ArrayList<>();
        Set<String> stageCollectSet = new HashSet<>();
        for (xxxxxxListDTO target: data){
            List<xxxxxxTargetMgStage> stageList = target.getxxxxxxStageList();
            Map<String, Object> addProperties = new HashMap<>();
            for (xxxxxxMgStage stage: stageList){
                if (!stageCollectSet.contains(stage)){
                    stageCollectSet.add(stage.getStage());
                    //給Excel增加列
                    writer.addHeaderAlias(stage.getStage(), stage.getStage() + "目標");
                }
                //為對象動態(tài)增加屬性
                addProperties.put(stage.getStage(), stage.getStageTarget());
            }
 
            //生成新的包含了新增字段的對象
            Object targetNew = ReflectUtil.getTarget(target, addProperties);
            dataNew.add(targetNew);
        }
 
        //只保留別名的數(shù)據(jù)
        writer.setOnlyAlias(true);
        writer.write(dataNew,true);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
        // excel寫入到輸出流
        writer.flush(outputStream,true);

上述代碼中,調(diào)用了工具類ReflectUtil給對象動態(tài)增加屬性。由于數(shù)據(jù)中有子類,需要獲取到子類中的某個字段并生成Excel表格,所以Excel表格構(gòu)造就需要對數(shù)據(jù)對象進行改造,簡單來說就是需要給對象動態(tài)增加新的屬性(成員對象的屬性),如下所示示例:

把studentList里面的關(guān)鍵屬性數(shù)據(jù),新增給Test類

示例不是很合適,湊合著用吧

class Test {

    private String class;

    .............................................

    private List<Student> studentList;

}

工具類ReflectUtil,用于給對象動態(tài)增加新的屬性:

import com.google.common.collect.Maps;
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
 
/**
 * 為實體類動態(tài)增加屬性,用于生成Excel表格時的特殊情況,例如表格中的列需要動態(tài)增加
 */
public class ReflectUtil {
    static Logger logger = LoggerFactory.getLogger(ReflectUtil.class);
 
    public static Object getTarget(Object dest, Map<String, Object> addProperties) {
        // get property map
        PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
        PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(dest);
        Map<String, Class> propertyMap = Maps.newHashMap();
        for (PropertyDescriptor d : descriptors) {
            if (!"class".equalsIgnoreCase(d.getName())) {
                propertyMap.put(d.getName(), d.getPropertyType());
            }
        }
        // add extra properties
        for (Map.Entry<String, Object> entry : addProperties.entrySet()) {
            propertyMap.put(entry.getKey(), entry.getValue().getClass());
        }
//        addProperties.forEach((k, v) -> propertyMap.put(k, v.getClass()));
        // new dynamic bean
        DynamicBean dynamicBean = new DynamicBean(dest.getClass(), propertyMap);
        // add old value
        for (Map.Entry<String, Class> entry : propertyMap.entrySet()) {
            try {
                // filter extra properties
                if (!addProperties.containsKey(entry.getKey())) {
                    dynamicBean.setValue(entry.getKey(), propertyUtilsBean.getNestedProperty(dest, entry.getKey()));
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
        ;
        // add extra value
        for (Map.Entry<String, Object> entry : addProperties.entrySet()) {
            try {
                dynamicBean.setValue(entry.getKey(), entry.getValue());
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
        ;
        Object target = dynamicBean.beanMap;
        return target;
    }
 
    public static class DynamicBean {
        /**
         * 目標對象
         */
        private Object target;
 
        /**
         * 屬性集合
         */
        private BeanMap beanMap;
 
        public DynamicBean(Class superclass, Map<String, Class> propertyMap) {
            this.target = generateBean(superclass, propertyMap);
            this.beanMap = BeanMap.create(this.target);
        }
 
 
        /**
         * bean 添加屬性和值
         *
         * @param property
         * @param value
         */
        public void setValue(String property, Object value) {
            beanMap.put(property, value);
        }
 
        /**
         * 獲取屬性值
         *
         * @param property
         * @return
         */
        public Object getValue(String property) {
            return beanMap.get(property);
        }
 
        /**
         * 獲取對象
         *
         * @return
         */
        public Object getTarget() {
            return this.target;
        }
 
 
        /**
         * 根據(jù)屬性生成對象
         *
         * @param superclass
         * @param propertyMap
         * @return
         */
        private Object generateBean(Class superclass, Map<String, Class> propertyMap) {
            BeanGenerator generator = new BeanGenerator();
            if (null != superclass) {
                generator.setSuperclass(superclass);
            }
            BeanGenerator.addProperties(generator, propertyMap);
            return generator.create();
        }
    }
}

至此,我們就生成了Excel表格,并且把數(shù)據(jù)寫入到了輸出流中。

下面我們需要從輸出流中拿到Excel表格數(shù)據(jù),并做為郵件的附件發(fā)送出去。

2.郵件發(fā)送

1.郵件發(fā)送功能實現(xiàn)-帶附件

Spring Email 抽象的核心是 JavaMailSender接口,通過實現(xiàn)JavaMailSender接口把 Email 發(fā)送給郵件服務(wù)器,由郵件服務(wù)器實現(xiàn)郵件發(fā)送的功能。

Spring 自帶了一個 JavaMailSender的實現(xiàn) JavaMailSenderImpl。SpringBoot 應(yīng)用在發(fā)送 Email 之前,我們需要在配置文件中對JavaMailSender進行屬性配置,這樣就可以利用Springboot的自動裝配機制,將 JavaMailSenderImpl 裝配為 Spring容器的一個 bean。

spring.mail.host: xxxxxxx.com
# 設(shè)置端口
spring.mail.port: 25
# 設(shè)置用戶名
spring.mail.username: xxxxxxxxxx
# 設(shè)置密碼,該處的密碼是QQ郵箱開啟SMTP的授權(quán)碼而非QQ密碼
spring.mail.password: xxxxxxxxx
# 設(shè)置是否需要認證,如果為true,那么用戶名和密碼就必須的,
# 如果設(shè)置false,可以不設(shè)置用戶名和密碼,當然也得看你的對接的平臺是否支持無密碼進行訪問的。
spring.mail.properties.mail.smtp.auth: false
# STARTTLS[1]  是對純文本通信協(xié)議的擴展。它提供一種方式將純文本連接升級為加密連接(TLS或SSL),而不是另外使用一個端口作加密通信。
spring.mail.properties.mail.smtp.starttls.enable: true
spring.mail.properties.mail.smtp.starttls.required: fasle
spring.mail.properties.mail.imap.starttls.socketFactory.fallback: false
spring.mail.properties.mail.smtp.starttls.socketFactory.class: com.ey.model.MailCommand

繼上面完整的Excel生成代碼,現(xiàn)在繼續(xù)寫郵件發(fā)送代碼:

    @Autowired
    private JavaMailSender springMailSender;    
 
    @Override
    public void publish(xxxxxxPublishVo publishVo) {
	    //........這里不再復(fù)制上面的代碼,只從Excel表格寫入輸出流開始.........
        // excel寫入輸出流
        writer.flush(outputStream,true);
 
        //郵件附件名稱
        String fileName = String.format("制定xx目標-%s.xlsx",UUID.randomUUID());
 
          //這個地方無需再配置,springboot自動裝配,配置信息在nacos配置中心
//        springMailSender.setDefaultEncoding("UTF-8");
//        springMailSender.setHost("mx.goertek.com");
//        springMailSender.setPort(25);
//        springMailSender.setProtocol(JavaMailSenderImpl.DEFAULT_PROTOCOL);
//        springMailSender.setUsername("tims.sys@goertek.com");
//        springMailSender.setPassword("Khkd0804");
//        Properties p = new Properties();
//        p.setProperty("mail.smtp.timeout", "25000");
//        p.setProperty("mail.smtp.auth", "true");
//        p.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
//        springMailSender.setJavaMailProperties(p);
 
        MimeMessage mimeMessage = springMailSender.createMimeMessage();
        System.getProperties().setProperty("mail.mime.splitlongparameters", "false");
        MimeMessageHelper messageHelper = null;
        try {
            messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        try {
            LoginUser userInfo = UserUtil.getCurrentUser();
//            String currentUserEmail = userInfo.getEmaila();
//            messageHelper.setFrom(currentUserEmail);
            messageHelper.setFrom(mailUserName);
 
            //設(shè)置收件人
            String[] emailArr = publishVo.getEmails().replaceAll("\\s+", "").split(",");
            messageHelper.setTo(emailArr);
 
            //設(shè)置抄送人
            if (!StringUtils.isBlank(publishVo.getCcEmails())){
                String[] ccEmailArr = publishVo.getCcEmails().replaceAll("\\s+", "").split(",");
                messageHelper.setCc(ccEmailArr);
            }
 
            messageHelper.setSubject("項目-" + publishVo.getProjectName().concat(": 制定品質(zhì)目標完畢"));
            messageHelper.setText("項目-" + publishVo.getProjectName().concat(": 制定品質(zhì)目標完畢"));
            try {
                //messageHelper.addInline("doge.gif", new File("xx/xx/doge.gif"));
                messageHelper.addAttachment(MimeUtility.encodeWord(fileName,"utf-8","B"), new ByteArrayResource(outputStream.toByteArray()));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            springMailSender.send(mimeMessage);
 
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }

2.踩過的坑

上述郵件發(fā)送功能實現(xiàn)過程中踩過的坑:

附件名中文亂碼問題

附件的名字是中文,發(fā)送成功后,在郵件中的附件名字中文亂碼,怎樣解決這個問題?

1. 設(shè)置系統(tǒng)值:

System.setProperty("mail.mime.splitlongparameters", "false");

2. 這里,在創(chuàng)建對象的時候定義編碼格式(utf-8):

MimeMessageHelper messageHelper = new MimeMessageHelper(mes, true, "utf-8");

3. 其次,在添加附件的時候,附件名是需要定義編碼:

messageHelper.addAttachment(MimeUtility.encodeWord(附件名,"utf-8","B"), 附件輸入流));

3.參考文章:

使用hutool工具進行導(dǎo)入導(dǎo)出excel表格_java_腳本之家 (jb51.net)

SpringBoot實現(xiàn)excel生成并且通過郵件發(fā)送的步驟詳解_java_腳本之家 (jb51.net)

以上就是SpringBoot使用JavaMailSender實現(xiàn)發(fā)送郵件+Excel附件的詳細內(nèi)容,更多關(guān)于SpringBoot JavaMailSender發(fā)送郵件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論