Java后台生成Excel文件并作为邮件附件发送

近期项目开发涉及到数据出现异常发送邮件给相关负责人,本来的邮件发送只是很简单的一个异常提醒信息,奈何甲方亲人不知足,又想要把异常数据做成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文件到发送带有附件的邮件就完成了,接下来看收到的内容。
在这里插入图片描述

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以提供一些基本的步骤: 1. 在Java中使用Apache POI库创建Excel文件 2. 使用JavaMail API连接邮箱服务器并创建邮件 3. 将Excel文件作为附件添加到邮件中 4. 设置邮件主题、内容、接收人等信息 5. 发送邮件 以下是一些参考代码: ```java // 1. 创建Excel文件 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Sheet1"); Row row = sheet.createRow(0); row.createCell(0).setCellValue("Hello"); row.createCell(1).setCellValue("World"); FileOutputStream outputStream = new FileOutputStream("example.xlsx"); workbook.write(outputStream); outputStream.close(); // 2. 创建邮件 Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", "smtp.gmail.com"); // 邮箱服务器 props.put("mail.smtp.port", "587"); // 邮箱SMTP端口 Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("your-email-address", "your-email-password"); } }); Message message = new MimeMessage(session); message.setFrom(new InternetAddress("your-email-address")); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient-email-address")); message.setSubject("Test Email"); // 3. 添加附件 MimeBodyPart attachmentPart = new MimeBodyPart(); attachmentPart.attachFile(new File("example.xlsx")); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(attachmentPart); // 4. 设置邮件内容、附件等信息 MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent("This is a test message", "text/html"); multipart.addBodyPart(messageBodyPart); message.setContent(multipart); // 5. 发送邮件 Transport.send(message); ``` 提醒一下,以上示例代码仅供参考,需要自己根据具体情况进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值