近期项目开发涉及到数据出现异常发送邮件给相关负责人,本来的邮件发送只是很简单的一个异常提醒信息,奈何甲方亲人不知足,又想要把异常数据做成excel表格,存为附件以供查看。甲方敢想,咱们就得敢做,不说废话,上代码。
首先是生成excel文件,在准备好要生成的excel数据之后调用生成excel的方法
public static ByteArrayOutputStream createExcel(List<Map<String, Object>> excelDataList) {
try {
//关联本地磁盘文件 在本地可以看到生成的excel文件
// File excel = new File("D:/testIO/" + "指标异常数据信息.xls");
// 1、创建一个流文件
ByteArrayOutputStream excel = new ByteArrayOutputStream();
//创建一个excel
WritableWorkbook workbook = Workbook.createWorkbook(excel);
// 2、创建一个Excel的工作表sheet
WritableSheet sheet = workbook.createSheet("指标群异常数据", 0);
// 3、样式设置
WritableFont bold = new WritableFont(WritableFont.createFont("微软雅黑"), 12, WritableFont.BOLD);
WritableFont noBold = new WritableFont(WritableFont.createFont("微软雅黑"), 12, WritableFont.NO_BOLD);
WritableCellFormat titleFormate = new WritableCellFormat(bold);
// 设置单元格中的内容水平方向居中、垂直方向居中设置边框
titleFormate.setAlignment(jxl.format.Alignment.CENTRE);
titleFormate.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
titleFormate.setBorder(Border.ALL, BorderLineStyle.THIN);
// 设置正文内容样式,单元格样式控制对象
WritableCellFormat textFormat = new WritableCellFormat(noBold);
// 单元格中的内容水平方向居中、垂直方向居中、设置边框
textFormat.setAlignment(jxl.format.Alignment.CENTRE);
textFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
textFormat.setBorder(Border.ALL,BorderLineStyle.THIN);
// 3.4、窗口冻结第一行
sheet.getSettings().setVerticalFreeze(1);
//sheet.getSettings().setHorizontalFreeze(2);//冻结 2列两行
// 3.5、设置行高--第一行标题行
sheet.setRowView(0,500);
// 3.6、设置列宽
sheet.setColumnView(0,15);
sheet.setColumnView(1,25);
sheet.setColumnView(2,30);
sheet.setColumnView(3,15);
sheet.setColumnView(4,15);
sheet.setColumnView(5,20);
// 4、构造表头
ExcelUtil.setSheetHeader(sheet, titleFormate);
// 5、填充数据
ExcelUtil.setSheetData(sheet, textFormat, 1, excelDataList);
workbook.write();
workbook.close();
return excel;
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("创建邮件失败");
}
}
因为生成的临时文件我不需要放到本地,所以这里直接用了一个字节流来存储excel信息
private static void setSheetHeader(WritableSheet sheet, WritableCellFormat titleFormate) throws WriteException {
// 构造表头
//mergeCells(0, 0, 0, 0) 表示不合并; sheet.mergeCells(1,0,2,0)表示第2列和第3列合并成一列
//Label label_20 = new Label(2, 0, "描述", cellFormat); 前面的数字表示第几列,第几行
//4.1、创建表数据
List<String> titleList = Arrays.asList("测试1", "测试2", "测试3", "测试4", "测试5", "测试6");
for (int i = 0; i < titleList.size(); i++) {
Label label_00 = new Label(i,0, titleList.get(i), titleFormate);
sheet.addCell(label_00);
}
}5
表头信息的话,根据自己需要来就行,可以动态生成,也可以给固定死,我这里不需要动态的,就直接给他固定死了。
private static void setSheetData(WritableSheet sheet, WritableCellFormat textFormat, int startRow, List<Map<String,Object>> excelDataList) throws WriteException {
for (int i = 0; i < excelDataList.size(); i++, startRow++) {
Map excelData = excelDataList.get(i);
Label label_02 = new Label(0, startRow, (String) excelData.get("INDEX_CODE"), textFormat);
sheet.addCell(label_02);
Label label_12 = new Label(1, startRow, (String) excelData.get("INDEX_NAME"), textFormat);
sheet.addCell(label_12);
Label label_22 = new Label(2, startRow, (String) excelData.get("IND_CONDITION"), textFormat);
sheet.addCell(label_22);
Label label_32 = new Label(3, startRow, (String) excelData.get("STATISTICAL_FREQUENCY"), textFormat);
sheet.addCell(label_32);
Label label_42 = new Label(4, startRow, (String) excelData.get("exceptionDate"), textFormat);
sheet.addCell(label_42);
Label label_52 = new Label(5, startRow, (String) excelData.get("msg"), textFormat);
sheet.addCell(label_52);
}
}
excelDataList就是要插入的行数据了,通过循环将数据插入到这些列中。当然列信息也是可以写成动态的,不过我只需要几列,也是固定死了。
上面代码执行完成之后,就得到了一个ByteArrayOutputStream类的excel流文件
// 将流文件存到字节数组缓冲区
ByteArrayInputStream excelAttachment = new ByteArrayInputStream(excel.toByteArray());
然后将流文件放到字节数组缓冲区中,以待使用。接下来就是创建邮件发送类
try {
// 创建邮件发送类
JavaMailSenderImpl javaMailSender = setMailSender();
// 创建邮件信息类
MimeMessage msg = javaMailSender.createMimeMessage();
// 创建MimeMessageHelper对象,MimeMessage的辅助类
MimeMessageHelper message = new MimeMessageHelper(msg, true);
message.setFrom(javaMailSender.getUsername());
String[] emailArray = emailList.toArray(new String[emailList.size()]);
// message.setTo(emailArray);
// 要发送的账号
message.setTo("***********@qq.com");
// 标题
message.setSubject(INDEX_CODE + "——" + INDEX_NAME + "——" + STATISTICAL_FREQUENCY + "——指标异常");
// 主体
message.setText(generateEmailMsg(item));
ByteArrayDataSource file = new ByteArrayDataSource(excelAttachment, "application/vnd.ms-excel;charset=UTF-8");
// 附件
message.addAttachment(MimeUtility.encodeWord("指标异常数据信息.xls","utf-8","B"),file);
javaMailSender.send(msg);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("邮件发送失败!" + e);
}
邮件发送使用的是SPring自带的JavaMailSenderImpl类;
public JavaMailSenderImpl setMailSender() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.qq.com");
javaMailSender.setUsername("*********@qq.com");
javaMailSender.setPassword("*************");
javaMailSender.setDefaultEncoding("UTF-8");
return javaMailSender;
}
这里是配置邮件的发送者,也就相当于客户端信息,演示使用的是QQ邮箱,需要注意的是,这里的Username是你的邮箱账号,Password并不是你的登录密码,而是在QQ邮箱-设置-账户,在这里用手机发送完成短信之后,点击页面的我已发送按钮,就可以获得一个授权码,Password那里就是填写这个授权码。
// 创建邮件信息类
MimeMessage msg = javaMailSender.createMimeMessage();
// 创建MimeMessageHelper对象,MimeMessage的辅助类
MimeMessageHelper message = new MimeMessageHelper(msg, true);
创建邮件的信息类,和邮件辅助类,邮件里的内容基本上都市用这个邮件的辅助类来完成的。这样从生成excel文件到发送带有附件的邮件就完成了,接下来看收到的内容。