JavaMail发送含有插入图片和表格的邮件

Posted 浪味仙人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaMail发送含有插入图片和表格的邮件相关的知识,希望对你有一定的参考价值。

引入依赖  javamail、jcommon、jfreechart

            <javamail-version>1.8.3</javamail-version>
            <jcommon.version>1.0.23</jcommon.version>
            <jfreechart.version>1.0.17</jfreechart.version> 
<dependency> <groupId>org.apache.geronimo.javamail</groupId> <artifactId>geronimo-javamail_1.4_provider</artifactId> <version>${javamail-version}</version> </dependency> <dependency> <groupId>org.jfree</groupId> <artifactId>jcommon</artifactId> <version>${jcommon.version}</version> </dependency> <dependency> <groupId>org.jfree</groupId> <artifactId>jfreechart</artifactId> <version>${jfreechart.version}</version> </dependency>

创建邮件发送模板,delay-mail.vm

<!DOCTYPE html>
<html lang="zh">
<head>
    <META http-equiv=Content-Type content=‘text/html; charset=UTF-8‘>
    <title>Title</title>
    <style type="text/css">
        table.reference, table.tecspec {
            border-collapse: collapse;
            width: 100%;
            margin-bottom: 4px;
            margin-top: 4px;
        }
        table.reference tr:nth-child(even) {
            background-color: #fff;
        }
        table.reference tr:nth-child(odd) {
            background-color: #f6f4f0;
        }
        table.reference th {
            color: #fff;
            background-color: #555;
            border: 1px solid #555;
            font-size: 12px;
            padding: 3px;
            vertical-align: top;
        }
        table.reference td {
            line-height: 2em;
            min-width: 24px;
            border: 1px solid #d4d4d4;
            padding: 5px;
            padding-top: 7px;
            padding-bottom: 7px;
            vertical-align: top;
        }
        .article-body h3 {
            font-size: 1.8em;
            margin: 2px 0;
            line-height: 1.8em;
        }
    </style>
</head>
<body>
<h3 style=";">滞留率分析报表</h3>
<div>
    <table class="reference">
        <tbody>
            <tr>
                <th>仓库</th>
                <th>初始化</th>
                <th>拣货中</th>
                <th>拣货完成</th>
                <th>装箱中</th>
                <th>装箱完成</th>
                <th>交接中</th>
                <th>交接完成</th>
                <th>已出库</th>
                <th>合计</th>
                <th>滞留率</th>
                <th>及时率</th>
            </tr>
        #foreach($element in  $datas)
        <tr>
            <td>
                #if($element.warehouseName)
                    $element.warehouseName
                #end
            </td>
            <td>
                #if($element.countInit)
                    $element.countInit
                #end
            </td>
            <td>
                #if($element.countPicking)
                    $element.countPicking
                #end
            </td>
            <td>
                #if($element.countPickFinish)
                    $element.countPickFinish
                #end
            </td>
            <td>
                #if($element.countPacking)
                    $element.countPacking
                #end
            </td>
            <td>
                #if($element.countPackFinish)
                    $element.countPackFinish
                #end
            </td>
            <td>
                #if($element.countTransferring)
                    $element.countTransferring
                #end
            </td>
            <td>
                #if($element.countTransferFinish)
                    $element.countTransferFinish
                #end
            </td>
            <td>
                #if($element.countDelivery)
                    $element.countDelivery
                #end
            </td>
            <td>
                #if($element.countTotal)
                    $element.countTotal
                #end
            </td>
            <td>
                #if($element.delayRate)
                    $element.delayRate
                #end
            </td>
            <td>
                #if($element.timelyRate)
                    $element.timelyRate
                #end
            </td>
        </tr>
        #end
        </tbody>
    </table>
    <img src="$imgPath" style="width: 100%">
    <div style="float: left; margin-top: 300px;;">
        <p>系统邮件(请勿回复) | 药品技术中心—供应链</p>
    </div>
</div>
</body>
</html>

邮件工具类 MailUtil.java

package com.yyw.scs.util;


import com.yyw.scs.model.Email;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.app.VelocityEngine;
import org.omg.CORBA.OBJ_ADAPTER;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.*;
import java.util.*;

public class MailUtils {


    private static Logger log = Logger.getLogger(MailUtils.class);

    public static final String HTML_CONTENT = "text/html;charset=UTF-8";
    public static final String ATTACHMENT_CONTENT = "text/plain;charset=gb2312";

    private static VelocityEngine velocityEngine;


    public <T extends List> void sendEmail(T t, String title, String[] to, String[] bcc, String templateName) {
        Map map = new HashMap();
        map.put("datas", t);
        Email email = new Email.Builder(title, to, null).model(map).templateName(templateName).bcc(bcc).build();
        sendEmail(email);
    }
    public <T extends List> void sendEmail(T t, String imgPath, String title, String[] to, String[] bcc, String templateName) {
        Map map = new HashMap();
        map.put("datas", t);
        map.put("imgPath", imgPath);
        Email email = new Email.Builder(title, to, null).model(map).templateName(templateName).bcc(bcc).build();
        sendEmail(email);
    }

    public <T extends List> void sendEmail(String title, String[] to, String[] bcc, String templateName, Map<String, Object> data) {
        Email email = new Email.Builder(title, to, null).model(data).templateName(templateName).bcc(bcc).build();
        sendEmail(email);
    }

    public void sendEmail(String title, String[] to, String[] bcc, String content, byte[] data, String fileName, String fileType) {
        Email email = new Email.Builder(title, to, content).bcc(bcc).data(data).fileName(fileName).fileType(fileType).build();
        sendEmail(email);
    }

    public <T extends List> void sendEmail(String title, String[] to, String[] bcc, String templateName, byte[] data, String fileName, String fileType, Map map) {
        Email email = new Email.Builder(title, to, null).model(map).templateName(templateName).bcc(bcc).data(data).fileType(fileType).fileName(fileName).build();
        sendEmail(email);
    }

    public <T extends List> void sendEmail(T t, String title, String[] to, String[] bcc, String templateName, byte[] data, String fileName, String fileType) {
        Map map = new HashMap();
        map.put("datas", t);
        Email email = new Email.Builder(title, to, null).model(map).templateName(templateName).bcc(bcc).data(data).fileType(fileType).fileName(fileName).build();
        sendEmail(email);
    }

    public void sendEmail(String title, String[] to, String content) {
        Email email = new Email.Builder(title, to, content).bcc(null).build();
        sendEmail(email);
    }

    public void sendEmail(String title, String[] to, String[] bcc, String content) {
        Email email = new Email.Builder(title, to, content).bcc(bcc).build();
        sendEmail(email);
    }

    //发送html模板邮件
    private void sendEmail(Email email) {
        Long startTime = System.currentTimeMillis();
        // 发件人
        try {
            MimeMessage message = this.getMessage(email);
            // 新建一个存放信件内容的BodyPart对象
            Multipart multiPart = new MimeMultipart();
            MimeBodyPart mdp = new MimeBodyPart();
            // 给BodyPart对象设置内容和格式/编码方式
            setContent(email);
            mdp.setContent(email.getContent(), HTML_CONTENT);
            multiPart.addBodyPart(mdp);
            // 新建一个MimeMultipart对象用来存放BodyPart对象(事实上可以存放多个)
            if (null != email.getData()) {
                MimeBodyPart attchment = new MimeBodyPart();
                ByteArrayInputStream in = new ByteArrayInputStream(email.getData());
                DataSource fds = new ByteArrayDataSource(in, email.getFileType());
                attchment.setDataHandler(new DataHandler(fds));
                attchment.setFileName(MimeUtility.encodeText(email.getFileName()));
                multiPart.addBodyPart(attchment);
                if (in != null) {
                    in.close();
                }
            }
            message.setContent(multiPart);
            message.saveChanges();
            Transport.send(message);
            Long endTime = System.currentTimeMillis();
            log.info("邮件发送成功 耗时:" + (endTime - startTime) / 1000 + "s");
        } catch (Exception e) {
            log.error("Error while sending mail.", e);
        }
    }


    private Email setContent(Email email) {
        if (StringUtils.isEmpty(email.getContent())) {
            email.setContent("");
        }
        if (StringUtils.isNotEmpty(email.getTemplateName()) && null != email.getModel()) {
            String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, email.getTemplateName(), "UTF-8", email.getModel());
            email.setContent(content);
        }
        return email;
    }

    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    private MimeMessage getMessage(Email email) {
        Properties props = new Properties();
        props.put("mail.smtp.host", "10.6.8.19");
        props.put("mail.smtp.auth", "true");
        props.put("username", "gyl_sys");
        props.put("password", "wms,123456");
        // 发件人
        MimeMessage message = null;
        try {
            if (email.getTo() == null || email.getTo().length == 0 || StringUtils.isEmpty(email.getSubject())) {
                throw new Exception("接收人或主题为空");
            }
            InternetAddress fromAddress = new InternetAddress("[email protected]");
            // toemails(字符串,多个收件人用,隔开)
            Session mailSession = Session.getDefaultInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("gyl_sys", "wms,123456");
                }
            });
            message = new MimeMessage(mailSession);
            message.setFrom(fromAddress);
            for (String mailTo : email.getTo()) {
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(mailTo));
            }
            List<InternetAddress> ccAddress = new ArrayList<>();
            if (null != email.getBcc()) {
                for (String mailCC : email.getBcc()) {
                    ccAddress.add(new InternetAddress(mailCC));
                }
                message.addRecipients(Message.RecipientType.CC,
                        ccAddress.toArray(new InternetAddress[email.getBcc().length]));
            }
            message.setSentDate(new Date());
            message.setSubject(email.getSubject());
        } catch (Exception e) {
            log.error("Error while sending mail." + e.getMessage(), e);
        }
        return message;
    }

}

 

绘制图表以及发送 SendDelayMailJobServiceImpl.java

package com.yyw.scs.service.impl;

import com.yyw.scs.model.request.DelayResultDto;
import com.yyw.scs.service.SendDelayMailJobService;
import com.yyw.scs.util.DiamondScsConfig;
import com.yyw.scs.util.MailUtils;
import com.yyw.scs.wms.service.DelayRateService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

@Service("sendDelayMailJobService")
public class SendDelayMailJobServiceImpl implements SendDelayMailJobService {

    @Autowired
    private MailUtils mailUtils;

    @Autowired
    private DelayRateService delayRateService;

    private final static Logger LOGGER = Logger.getLogger(SendDelayMailJobServiceImpl.class);

    @Override
    public Boolean send() {
        try {

            // 1. 得到数据
            List<DelayResultDto> res = delayRateService.findDelayResultDtoList(null, null, null, 1);
            if (!CollectionUtils.isNotEmpty(res)) {
                LOGGER.info("SendDelayMailJobServiceImpl.send nodata:");
                return null;
            }
            CategoryDataset dataset = getDataSet(res);


            // 2. 构造chart
            JFreeChart chart = ChartFactory.createBarChart3D(
                    "仓库履约实时分析", // 图表标题
                    "状态", // 目录轴的显示标签--横轴
                    "数量", // 数值轴的显示标签--纵轴
                    dataset, // 数据集
                    PlotOrientation.VERTICAL, // 图表方向:水平、
                    true, // 是否显示图例(对于简单的柱状图必须
                    false, // 是否生成工具
                    false // 是否生成URL链接
            );
            // 3. 处理chart中文显示问题
            processChart(chart);

            // 4. chart输出图片
            // 输出到本机TOMCAT路径
//            File directory = new File(".");
//            String path = null;
//            try {
//                path = directory.getCanonicalPath();
//            } catch (IOException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//            path += "\img\delay.jpg";
            // 输出到本机绝对路径
            String path = "/app/img/";
            File file = new File(path);
            System.out.println(path);
            if (!file.exists() && !file.isDirectory()) {
                file.mkdir();
            }
            path += "delay.jpg";
            writeChartAsImage(chart, path);

            // 5. chart 以swing形式输出
//            ChartFrame pieFrame = new ChartFrame("XXX", chart);
//            pieFrame.pack();
//            pieFrame.setVisible(true);

            // 6.发送邮件
            List<String> toList = DiamondScsConfig.getJobSendDelayToList();
            if (CollectionUtils.isNotEmpty(toList)) {
                String[] toArr = (String[]) toList.toArray(new String[toList.size()]);
                mailUtils.sendEmail(res, path, "滞留率分析报表", toArr, null, "spring/email/delay-mail.vm");
            } else {
                LOGGER.info("发送邮件: 未获取到收件人列表");
            }

        } catch (Exception e) {
            LOGGER.error("SendDelayMailJobServiceImpl.send error:", e);
            // todo 发送报警邮件
            return false;
        }
        return true;
    }

    /**
     * 获取一个演示用的组合数据集对象
     *
     * @return
     */
    private CategoryDataset getDataSet(List<DelayResultDto> res) {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (DelayResultDto item : res) {
            dataset.addValue(item.getCountInit(), item.getWarehouseName(), "初始化");
            dataset.addValue(item.getCountPicking(), item.getWarehouseName(), "拣货中");
            dataset.addValue(item.getCountPickFinish(), item.getWarehouseName(), "拣货完成");
            dataset.addValue(item.getCountPacking(), item.getWarehouseName(), "装箱中");
            dataset.addValue(item.getCountPackFinish(), item.getWarehouseName(), "装箱完成");
            dataset.addValue(item.getCountTransferring(), item.getWarehouseName(), "交接中");
            dataset.addValue(item.getCountTransferFinish(), item.getWarehouseName(), "交接完成");
            dataset.addValue(item.getCountDelivery(), item.getWarehouseName(), "已出库");
        }
        return dataset;
    }

    private CategoryDataset getDemoDataSet() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.addValue(100, "北京", "苹果");
        dataset.addValue(120, "上海", "苹果");
        dataset.addValue(160, "广州", "苹果");
        dataset.addValue(210, "北京", "梨子");
        dataset.addValue(220, "上海", "梨子");
        dataset.addValue(230, "广州", "梨子");
        dataset.addValue(330, "北京", "葡萄");
        dataset.addValue(340, "上海", "葡萄");
        dataset.addValue(340, "广州", "葡萄");
        dataset.addValue(420, "北京", "香蕉");
        dataset.addValue(430, "上海", "香蕉");
        dataset.addValue(400, "广州", "香蕉");
        dataset.addValue(510, "北京", "荔枝");
        dataset.addValue(530, "上海", "荔枝");
        dataset.addValue(510, "广州", "荔枝");
        return dataset;
    }

    /**
     * 解决图表汉字显示问题
     *
     * @param chart
     */
    private static void processChart(JFreeChart chart) {
        CategoryPlot plot = chart.getCategoryPlot();
        CategoryAxis domainAxis = plot.getDomainAxis();
        ValueAxis rAxis = plot.getRangeAxis();
        chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        TextTitle textTitle = chart.getTitle();
        textTitle.setFont(new Font("宋体", Font.PLAIN, 20));
        domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
        domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
        rAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
        rAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
        chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 12));
        // renderer.setItemLabelGenerator(new LabelGenerator(0.0));
        // renderer.setItemLabelFont(new Font("宋体", Font.PLAIN, 12));
        // renderer.setItemLabelsVisible(true);
    }

    /**
     * 输出图片
     *
     * @param chart
     */
    private static void writeChartAsImage(JFreeChart chart, String path) {
        FileOutputStream fos_jpg = null;
        try {
            fos_jpg = new FileOutputStream(path);
            ChartUtilities.writeChartAsJPEG(fos_jpg, 1, chart, 800, 500, null);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fos_jpg.close();
            } catch (Exception e) {
            }
        }
    }
}

 


以上是关于JavaMail发送含有插入图片和表格的邮件的主要内容,如果未能解决你的问题,请参考以下文章

JavaMail:利用JavaMail发送复杂邮件

[Java] JavaMail 发送带图片的 html 格式的邮件

JavaMail邮件发送

JavaMail邮件发送

邮件测试须知(JavaMail)

javamail: UrlDataSource获取网络文件作为邮件的附件|javamail发送二进制流附件的问题