JavaWeb合集22-Apache POI

二十二、Apache POI

Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用POI在Java

序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI都是用于操作Excel文件。

使用场景:银行网银系统导出交易明细、各种业务系统导出Excel报表、批量导,入业务数据。

1、入门案例

  1. 导入对应的Maven坐标

    xml 复制代码
    <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.16</version>
    </dependency>
    
    <dependency>
    <groupId>org.apache .poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.16</version>
    </dependency>
  2. 创建Excel工作簿,并对其写入和读取

    java 复制代码
    public class POITest {
    
        /**
         通过POI.创建Excel.文件并且写入文件内容
         */
        public static void wirteExcel() throws Exception{
            // 在内存中创建一个EXcel工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();
            // 在工作簿中创建一个工作表,并命名为info
            XSSFSheet sheet = workbook.createSheet("info");
            // 在info工作表中创建一行,行号是从0开始的
            XSSFRow row = sheet.createRow(1);
            // 在row行中创建一个单元格,列号从0开始,并设置单元格的值为,姓名(2行3列)性别(2行4列)
            row.createCell(2).setCellValue("姓名");
            row.createCell(3).setCellValue("性别");
    
            //再次创创建一个新行,第3行
            row=sheet.createRow(2);
            // 在row行中创建单元格,并设置单元格的值
            row.createCell(2).setCellValue("张三");
            row.createCell(3).setCellValue("男");
    
            // 再次创建一个新行,第4行
            row=sheet.createRow(3);
            row.createCell(2).setCellValue("小明");
            row.createCell(3).setCellValue("女");
    
            // 将内存中的数据写入到磁盘中
            OutputStream outputStream=new FileOutputStream("D:\\info.xlsx");
            workbook.write(outputStream);  // 写入到输出流中
    
            //关闭资源
            outputStream.close();
            workbook.close();
        }
    
        /**
         * 读取Excel文件
         * @throws Exception
         */
        public static void readExcel() throws Exception{
            // 创建输入流对象
            InputStream inputStream=new FileInputStream("D:\\info.xlsx");
            //从输入流中读取一个工作簿
            XSSFWorkbook workbook=new XSSFWorkbook(inputStream);
            // 根据名字来获取工作表
           //  XSSFSheet sheet = workbook.getSheet("info");
            //根据下标来获取工作表
            XSSFSheet sheet = workbook.getSheetAt(0);
            // 获取最后一行的行号(下标从0开始的)
            Integer lastRowNum = sheet.getLastRowNum();
          //  循环读取每一行,以及每一行对应的单元格数据,(第一行为空白,我们从第二行开始读取,下标为1)
            for(int i=1;i<=lastRowNum;i++){
               XSSFRow row = sheet.getRow(i); // 获取第i行
                String name =  row.getCell(2).getStringCellValue(); // 获取第i行,第3列的数据
                String sex = row.getCell(3).getStringCellValue(); // 获取第i行,第4列的数据
                System.out.println(name+"---"+sex);
            }
            // 关闭资源
            inputStream.close();
            workbook.close();
    
        }
        public static void main(String[] args) throws Exception {
               wirteExcel();
               readExcel();
        }
    }

2、实操案例

报表导出,营业数据导出到工作表中,下载下来。

接口:没有参数,也没有返回值。
一般情况下,想这个比较复杂的工作表,都是不需要提供POI来创建的,一般是手动创建这样一个模板文件,通过输入流将其读取进去,只需要将数据写入对应的单元格,通过输出流由客户端、浏览器进行下载即可。

2.1 Controller层
java 复制代码
  /**
     * 导出运营数据报表
     */
    @Operation(summary = "导出运营数据报表")
    @GetMapping("/export")
    public void getBusinessReportData(HttpServletResponse response){
        // 调用service导出报表,传入响应对象
      reportService.exportBusinessReport(response);
    }
2.2 Service层
java 复制代码
    /**
     * 导出运营数据报表
     * @param response
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) {
      //1、获取运营数据
        LocalDate beginDate=LocalDate.now().minusDays(30);
        LocalDate endDate=LocalDate.now().minusDays(1);
        LocalDateTime beginTime=LocalDateTime.of(beginDate,LocalTime.MIN);
        LocalDateTime endTime=LocalDateTime.of(endDate,LocalTime.MAX);

       BusinessDataVO businessDataVO= workspaceService.getBusinessData(beginTime,endTime); //获取运营数据

        //2、将数据写入到模板文件中
        //2.1、获取模板文件

        log.info("name:{}",this.getClass().getClassLoader());

 //通过类加载器,获取到路径:src/main/resources,再拼接路径:template/运营数据报表模板.xlsx
        InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            //2.2、通过模块创建工作簿
            XSSFWorkbook workbook=new XSSFWorkbook(inputStream);
            //2.3、读取第一个工作表
            XSSFSheet sheet=workbook.getSheetAt(0);
            //2.4、设置时间数据
            sheet.getRow(1).getCell(0).setCellValue("日期范围:"+beginDate+" 至 "+endDate);
            //2.5、设置概况数据
             XSSFRow row= sheet.getRow(3);
             row.getCell(1).setCellValue(businessDataVO.getTurnover().doubleValue());//营业额
             row.getCell(3).setCellValue(businessDataVO.getOrderCompletionRate()); //订单完成率
             row.getCell(5).setCellValue(businessDataVO.getNewUsers()); //新增用户数

            row= sheet.getRow(4);
            row.getCell(1).setCellValue(businessDataVO.getValidOrderCount());//有效订单数
            row.getCell(3).setCellValue(businessDataVO.getUnitPrice().doubleValue());//平均客单价

            //2.6、设置订单明细数据
           for(int i=0;i<30;i++){
               LocalDate date=beginDate.plusDays(i);
               LocalDateTime begin=LocalDateTime.of(date,LocalTime.MIN);
               LocalDateTime end=LocalDateTime.of(date,LocalTime.MAX);
               businessDataVO=workspaceService.getBusinessData(begin,end);
               row= sheet.getRow(7+i);
               row.getCell(0).setCellValue(date.toString()); //日期
               row.getCell(1).setCellValue(businessDataVO.getTurnover().doubleValue()); //营业额
               row.getCell(2).setCellValue(businessDataVO.getValidOrderCount()); //有效订单数
               row.getCell(3).setCellValue(businessDataVO.getOrderCompletionRate());//订单完成率
               row.getCell(4).setCellValue(businessDataVO.getUnitPrice().doubleValue());
               row.getCell(5).setCellValue(businessDataVO.getNewUsers()); //新增用户数
           }

            //3、将文件输出到浏览器 浏览器下载
           ServletOutputStream servletOutputStream = response.getOutputStream();
           workbook.write(servletOutputStream);

           //4、关闭资源
            workbook.close();
            servletOutputStream.close();
            inputStream.close();

        }catch (Exception e){
            e.printStackTrace();
        }
    }
相关推荐
咩咩啃树皮35 分钟前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚1 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白3 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司3 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地4 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun3141594 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风7 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠7 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z123456789867 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin5211238 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python