IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Java读取Hbase数据,使用POI操作Excel模板并定时发送带有Excel附件的邮件 -> 正文阅读

[大数据]Java读取Hbase数据,使用POI操作Excel模板并定时发送带有Excel附件的邮件


前言

在做航空方面的业务,需求为根据现有Excel模板,进行数据处理,并定时发送excel附件的相关邮件。


一、读取Excel模板

//读取excel模板
ClassPathResource resource = new ClassPathResource(template);
InputStream in = resource.getInputStream();
XSSFWorkbook wb = new XSSFWorkbook(in);

二、读取Hbase数据

1.创建Hbase连接和查询条件

代码如下:需求查询两个hbase表数据,可根据实际需求进行调整

        String tomorrowDateStr = tomorrowDateStr();
        String splitPrefix = tomorrowDateStr.substring(tomorrowDateStr.length() - 1);
        String rowKey = splitPrefix + "-" + tomorrowDateStr;
        try {
            Connection conn = null;
            Table inbndHTable = null;
            Table transHTable = null;

            conn = hBaseDataSource.getConnection();
            inbndHTable = HTableUtil.getTable(conn, HbaseName1);
            transHTable = HTableUtil.getTable(conn, HbaseName2);

            Scan inbndScan = new Scan();
            inbndScan.setCaching(conn.getConfiguration().getInt(HConstants.HBASE_CLIENT_SCANNER_CACHING, 10000));
            inbndScan.setCacheBlocks(true);
            inbndScan.setRowPrefixFilter(Bytes.toBytes(rowKey));

            Scan transScan = new Scan();
            transScan.setCaching(conn.getConfiguration().getInt(HConstants.HBASE_CLIENT_SCANNER_CACHING, 10000));
            transScan.setCacheBlocks(true);
            transScan.setRowPrefixFilter(Bytes.toBytes(rowKey));        

2.获取数据

代码如下(示例):

Map<String, Map<String, byte[]>> inbndckiResults = HTableUtil.scan(inbndHTable, inbndScan);
Map<String, Map<String, byte[]>> transckiResults = HTableUtil.scan(transHTable, transScan);

三、向Excel模板写入相关数据,并生成本地文件

public void exportTemplateSendEmail(List platinumForecastLists, List platinumTeansForecastLists) throws Exception {
        Date date = new Date();//取时间
        String todayStr = sdf1.format(date);
        //读取excel模板
        ClassPathResource resource = new ClassPathResource(template);
        InputStream in = resource.getInputStream();
        XSSFWorkbook wb = new XSSFWorkbook(in);
        XSSFSheet indndSheet = wb.getSheetAt(0);
        XSSFSheet transSheet = wb.getSheetAt(1);

        XSSFCellStyle style = wb.createCellStyle();
        //单元格边框属性设置
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);

        indndSheet.createRow(1).createCell(0).setCellValue("日期:" + todayStr);
        transSheet.createRow(1).createCell(0).setCellValue("日期:" + todayStr);
        indndSheet.getRow(1).getCell(0).setCellStyle(style);
        transSheet.getRow(1).getCell(0).setCellStyle(style);
        indndSheet.getRow(1).createCell(7).setCellStyle(style);
        transSheet.getRow(1).createCell(10).setCellStyle(style);

        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setAlignment(HorizontalAlignment.CENTER);

        for (int i = 0; i < platinumForecastLists.size(); i++) {
            PlatinumInbndForecastBean platinumForecastBean = (PlatinumInbndForecastBean) platinumForecastLists.get(i);
            // row从0开始  cell 从0开始的
            indndSheet.createRow(i + 3).createCell(0).setCellValue(i + 1);
            indndSheet.getRow(i + 3).createCell(1).setCellValue(platinumForecastBean.getFullName());
            indndSheet.getRow(i + 3).createCell(2).setCellValue(platinumForecastBean.getDepartureTime());
            indndSheet.getRow(i + 3).createCell(3).setCellValue(platinumForecastBean.getFlightNum());
            indndSheet.getRow(i + 3).createCell(4).setCellValue(platinumForecastBean.getFQTVNumber());
            indndSheet.getRow(i + 3).createCell(6).setCellValue(platinumForecastBean.getCheckInInfoStatus());
            indndSheet.getRow(i + 3).createCell(7).setCellValue(platinumForecastBean.getTerminal());
            indndSheet.getRow(i + 3).getCell(0).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(1).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(2).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(3).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(4).setCellStyle(style);
            indndSheet.getRow(i + 3).createCell(5).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(6).setCellStyle(style);
            indndSheet.getRow(i + 3).getCell(7).setCellStyle(style);
        }

        for (int i = 0; i < platinumTeansForecastLists.size(); i++) {
            PlatinumTransForecastBean platinumForecastBean = (PlatinumTransForecastBean) platinumTeansForecastLists.get(i);
            // row从0开始  cell 从0开始的
            transSheet.createRow(i + 3).createCell(0).setCellValue(i + 1);
            transSheet.getRow(i + 3).createCell(1).setCellValue(platinumForecastBean.getInbndFltNum());
            transSheet.getRow(i + 3).createCell(2).setCellValue(platinumForecastBean.getArrTime());
            transSheet.getRow(i + 3).createCell(3).setCellValue(platinumForecastBean.getLastSeg());
            transSheet.getRow(i + 3).createCell(4).setCellValue(platinumForecastBean.getFullName());
            transSheet.getRow(i + 3).createCell(5).setCellValue(platinumForecastBean.getTransFltNum());
            transSheet.getRow(i + 3).createCell(6).setCellValue(platinumForecastBean.getDepTime());
            transSheet.getRow(i + 3).createCell(7).setCellValue(platinumForecastBean.getNextSeg());
            transSheet.getRow(i + 3).createCell(9).setCellValue(platinumForecastBean.getFQTVNumber());
            transSheet.getRow(i + 3).createCell(10).setCellValue(platinumForecastBean.getTelNum());


            transSheet.getRow(i + 3).getCell(0).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(1).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(2).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(3).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(4).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(5).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(6).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(7).setCellStyle(style);
            transSheet.getRow(i + 3).createCell(8).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(9).setCellStyle(style);
            transSheet.getRow(i + 3).getCell(10).setCellStyle(style);
        }
        indndSheet.createFreezePane(0, 3, 0, 3);
        transSheet.createFreezePane(0, 3, 0, 3);

        //写入磁盘保存文件
        FileOutputStream output = new FileOutputStream(patinumFileName);
        wb.write(output);
        output.close();

        //作为输出流发邮件
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        wb.write(byteArrayOutputStream);
        List<String> emailList = new ArrayList<>();
        emailList.add("自定义邮箱");


        for (String email : emailList) {
            boolean rst = sendMail(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), "白金卡预报", email);
            if (rst) {
                LOGGER.info("向" + email + "邮件发送成功!");
            } else {
                LOGGER.info("向" + email + "邮件发送失败!");
            }
        }


    }

四、将新生成的Excel以流的方式,进行邮件发送

public boolean sendMail(InputStream is, String fileName, String toMail) {
        Transport transport = null;
        try {
            System.setProperty("mail.mime.splitlongparameters", "false");
            Properties props = new Properties();
            // 设置发送邮件的邮件服务器的属性(这里使用网易的smtp服务器)
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.ssl.trust", "*");
            // 需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
            props.put("mail.smtp.auth", "true");
            // 用刚刚设置好的props对象构建一个session
            Session session = Session.getDefaultInstance(props);
            // 有了这句便可以在发送邮件的过程中在console处显示过程信息,供调试使
            // 用(你可以在控制台(console)上看到发送邮件的过程)
            session.setDebug(false);
            // 用session为参数定义消息对象
            MimeMessage message = new MimeMessage(session);
            // 加载发件人地址
            message.setFrom(new InternetAddress(username));
            // 加载收件人地址
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail));
            // 加载标题
            message.setSubject(fileName);

            // 向multipart对象中添加邮件的各个部分内容,包括文本内容和附件
            Multipart multipart = new MimeMultipart();

            // 设置邮件的文本内容
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setText("自定义邮件内容");
            multipart.addBodyPart(contentPart);
            // 添加附件
            BodyPart messageBodyPart = new MimeBodyPart();
            DataSource source = new ByteArrayDataSource(is, "application/msexcel");
            // 添加附件的内容
            messageBodyPart.setDataHandler(new DataHandler(source));
            // 添加附件的标题
            // 这里很重要,通过下面的Base64编码的转换可以保证你的中文附件标题名在发送时不会变成乱码
            messageBodyPart.setFileName(MimeUtility.encodeText(fileName + ".xlsx"));
            multipart.addBodyPart(messageBodyPart);

            // 将multipart对象放到message中
            message.setContent(multipart);
            // 保存邮件
            message.saveChanges();
            // 发送邮件
            transport = session.getTransport(protocol);
            // 连接服务器的邮箱 发件人和授权码
            transport.connect(host, username, password);
            // 把邮件发送出去
            transport.sendMessage(message, message.getAllRecipients());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                transport.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

五、编写定时任务

定时下午5点进行邮件发送; task.sendMsg();调用了exportTemplateSendEmail(List list1,List list2)

@Scheduled(cron = "0 0 17 * * *")
    public void taskSync() {
        try {
            task.sendMsg();
        } catch (Exception e) {
            LOGGER.warn("PlatinumForecast email send failed!", e);
        }
    }

总结

遇到的问题,SSL协议证书问题(连接邮箱主机失败),将SSL协议设置为全部跳过,详见标题四

props.put("mail.smtp.ssl.trust", "*") 
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:18:23  更:2022-06-01 15:19:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:57:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码