以下代码可以复制直接使用,目前自己正在使用
发送邮件的依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
实现的原理
邮件内容是html,在邮件内容中需要带图的地方写
<img src="cid:cid的值">
换成代码就是
String cid = "1111";
StringBuilder sb = new StringBuilder();
sb.append("<h3>测试图片发送</h3>\r\n");
sb.append("<img src=\"cid:").append(cid).append("\">");
String mailContent = sb.toString();
发送邮件的工具类,可以直接用
package com.test;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.HtmlEmail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.activation.DataSource;
import java.util.Date;
public class EmailUtil {
private static Logger logger = LoggerFactory.getLogger(EmailUtil.class);
/**
* 发送给谁
*/
private String toUser = "xxx";
/**
* 抄送给谁
*/
private String ccUser = "xxx";
/**
* 密送给谁
*/
private String bccUser = "";
/**
* host
*/
private String host = "邮箱host";
/**
* auth
*/
private String auth = "true";
/**
* port
*/
private String port = "25";
/**
* username
*/
private String username = "发送邮件的邮箱";
/**
* password
*/
private String password = "密码";
/**
* type
*/
private String contentType = "UTF-8";
public boolean sendMail(MailInfo content){
boolean iscoorect=false;
String[] to=toUser.contains(",")?toUser.split(","):new String[] {toUser};
String[] cc=ccUser.contains(",")?ccUser.split(","):new String[] {ccUser};
String[] bcc=bccUser.contains(",")?bccUser.split(","):new String[] {bccUser};
try {
HtmlEmail mail = new HtmlEmail();
// 设置邮箱服务器信息
mail.setSmtpPort(Integer.parseInt(port));
mail.setHostName(host);
// 设置密码验证器
mail.setAuthentication(username, password);
// 设置邮件发送者
mail.setFrom(username);
// 设置邮件接收者
mail.addTo(to);
if(StringUtils.isNoneBlank(bcc)) {
mail.addBcc(bcc);
}
if(StringUtils.isNoneBlank(cc)) {
mail.addCc(cc);
}
// 设置邮件编码
mail.setCharset(contentType);
// 设置邮件主题
if(StringUtils.isNoneBlank(content.subject)){
mail.setSubject(content.subject);
}
// 邮件内容
if(StringUtils.isNoneBlank(content.msg)){
mail.setHtmlMsg(content.msg);
}
// 插入图片资源
String[] cids = content.cids;
if(cids != null){
DataSource[] ds = content.ds;
for (int i = 0; i < cids.length; i++) {
mail.embed(ds[i], cids[i]);
}
}
// 创建附件
if(StringUtils.isNotBlank(content.attachmentPath) && StringUtils.isNotBlank(content.attachmentName)){
EmailAttachment attachment = new EmailAttachment();
attachment.setPath(content.attachmentPath);
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setName(content.attachmentName);
mail.attach(attachment);
}
// 设置邮件发送时间
mail.setSentDate(new Date());
// 发送邮件
mail.send();
logger.info("发送成功");
iscoorect=true;
}catch(Exception e) {
logger.info("发送失败,异常:{}", e);
}
return iscoorect;
}
public static class MailInfo{
/**
* 附件名称
*/
public String attachmentName;
/**
* 附件路径
*/
public String attachmentPath;
public String subject;
/**
* html邮件内容,包涵所有的信息,上面提到的图片内嵌的标签也在这里
*/
public String msg;
/**
* 邮件中插入的图片cid,引用方式为 <img src=\"cid:" + cid + "\"></html>"
*/
public String[] cids;
/**
* 邮件中插入的图片资源,和cids一一对应
*/
public DataSource[] ds;
}
}
上面的邮件工具使用的图表生成工具。注意这个依赖的是java的生成图片的类库,确保运行程序的java环境中能正常初始化。如果不能用,继续往后看。有替代的工具。反正我是本地可以用,服务器上用不了。没有深入研究为啥,先完成任务再说。。。
package com.test;
import brand.entity.ReportBean;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.image.WritableImage;
import javax.imageio.ImageIO;
import javax.mail.util.ByteArrayDataSource;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 生成折线图的工具,发送邮件时插入图片
*/
public class ChartUtils {
/**
*
* 返回的是ByteArrayDataSource类型的折线图。大家可以根据需要扩展曲线图的类型。
* 注意调用时要这样调用
* PlatformImpl.startup(() -> {
*
* ByteArrayDataSource ds = generateLineChart(xxxxxxxxxx);
*
* });
*
*
*/
public static ByteArrayDataSource generateLineChart(Long[] x, Long[] y, String title){
//Defining the x axis
NumberAxis xAxis = new NumberAxis(x[0], x[x.length - 1], 1);
xAxis.setLabel("Minutes");
List<XYChart.Data> l = new ArrayList<XYChart.Data>();
long min = y[0];
long max = 0;
for (int i = 0; i < y.length; i++) {
long count = y[i];
if(count < min){
min = count;
}
if(count > max){
max = count;
}
l.add(new XYChart.Data(x[i], y[i]));
}
min = min - 10;
//Defining the y axis
NumberAxis yAxis = new NumberAxis(min < 0 ? 0 : min, max + 10, (max - min) / 10);
yAxis.setLabel("count");
//Creating the line chart
LineChart linechart = new LineChart(xAxis, yAxis);
//Prepare XYChart.Series objects by setting data
XYChart.Series series = new XYChart.Series();
series.setName(title);
series.getData().addAll(l);
//Setting the data to Line chart
linechart.getData().add(series);
//防止坐标刻度不显示
linechart.setAnimated(false);
//Creating a scene object
Scene scene = new Scene(linechart, 1000, 600);
WritableImage writableImage = new WritableImage(1000, 600);
linechart.snapshot(new SnapshotParameters(), writableImage);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(SwingFXUtils.fromFXImage(writableImage, null), "png", bos);
} catch (Exception s) {
s.printStackTrace();
}
return new ByteArrayDataSource(bos.toByteArray(),"image/png");
}
}
如果上面说的工具不可以,还有个工具JFreeChart
注意版本是1.0.19
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
这个工具类中的示例方法返回的也是ByteArrayDataSource
,和上面那种java的返回类型一样,因此可以随意切换。如果有其他的工具也可以扩展,很容易
package com.test;
import java.awt.*;
import java.io.*;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import javax.mail.util.ByteArrayDataSource;
public class JFreeChartTest {
// 这个方法自己测试过,中文也能正常显示。代码比较乱,大家简单重构一下即可
public static ByteArrayDataSource generateLineChart() {
String[] rowKeys = {"A系列"};
String[] colKeys = {"0:00", "1:00", "2:00", "7:00", "8:00", "9:00",
"10:00", "11:00", "12:00", "13:00", "16:00", "20:00", "21:00",
"23:00"};
double[][] data = {{4, 3, 1, 1, 1, 1, 2, 2, 2, 1, 8, 2, 1, 1},};
// 或者使用类似以下代码
// DefaultCategoryDataset categoryDataset = new
// DefaultCategoryDataset();
// categoryDataset.addValue(10, "rowKey", "colKey");
CategoryDataset categoryDataset = DatasetUtilities.createCategoryDataset(rowKeys, colKeys, data);
// 创建JFreeChart对象:ChartFactory.createLineChart
JFreeChart jfreechart = ChartFactory.createLineChart("不同类别按小时计算拆线图", // 标题
"年分", // categoryAxisLabel (category轴,横轴,X轴标签)
"数量", // valueAxisLabel(value轴,纵轴,Y轴的标签)
categoryDataset, // dataset
PlotOrientation.VERTICAL, true, // legend
false, // tooltips
false); // URLs
// 使用CategoryPlot设置各种参数。以下设置可以省略。
CategoryPlot plot = (CategoryPlot)jfreechart.getPlot();
//设置图片标题的字体
jfreechart.getTitle().setFont(new Font("新宋体", Font.BOLD, 15));
//设置图例项目字体
jfreechart.getLegend().setItemFont(new Font("新宋体", Font.BOLD, 15));
//得到绘图区的域轴(横轴),设置标签的字体
plot.getDomainAxis().setLabelFont(new Font("新宋体", Font.BOLD, 15));
//设置横轴标签项字体
plot.getDomainAxis().setTickLabelFont(new Font("新宋体", Font.BOLD, 15));
//设置范围轴(纵轴)字体
plot.getRangeAxis().setLabelFont(new Font("新宋体", Font.BOLD, 15));
// 背景色 透明度
plot.setBackgroundAlpha(0.5f);
// 前景色 透明度
plot.setForegroundAlpha(0.5f);
// 其他设置 参考 CategoryPlot类
LineAndShapeRenderer renderer = (LineAndShapeRenderer)plot.getRenderer();
renderer.setBaseShapesVisible(true); // series 点(即数据点)可见
renderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见
renderer.setUseSeriesOffset(true); // 设置偏移量
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
ByteArrayOutputStream out = null;
try {
out = new ByteArrayOutputStream();
// 保存为PNG
ChartUtilities.writeChartAsPNG(out, jfreechart, 600, 400);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
// do nothing
}
}
}
return new ByteArrayDataSource(out.toByteArray(),"image/png");
}