课程内容

  • 完成工作台功能
  • Apache POI
  • 导出运营数据Excel报表

工作台

需求分析

  • 系统运营的数据看板
  • 提供快捷操作入口
  • 展示数据包括
    • 今日数据
    • 订单管理
    • 菜品总览
    • 订单信息
  • 工作台应当设计多个接口
    • 今日数据接口
    • 订单管理接口
    • 菜品总览接口
    • 套餐总览接口
    • 订单搜索(已完成)
    • 各个状态订单数据统计(已完成)

代码开发

  • 已经提供了代码 直接导入即可
  • 都是之前学习过的内容 这里不再赘述

Apache POI

基础介绍

  • 处理Office文件格式的开源项目
  • 可以用POI在Java程序中对Office各种文件进行读写操作
  • 一般用于操作Excel文件

应用场景

  • 网银系统导出交易明细
  • 各种业务系统导出Excel报表
  • 批量导入业务数据

入门案例

  • 首先导入maven坐标(已导入)
<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>

写入操作

  • 开发详细代码
public class POITest {

    /**
     * 基于POI向Excel文件写入数据
     * @throws Exception
     */
    public static void write() throws Exception{
        //在内存中创建一个Excel文件对象
        XSSFWorkbook excel = new XSSFWorkbook();
        //创建Sheet页
        XSSFSheet sheet = excel.createSheet("itcast");

        //在Sheet页中创建行,0表示第1行
        XSSFRow row1 = sheet.createRow(0);
        //创建单元格并在单元格中设置值,单元格编号也是从0开始,1表示第2个单元格
        row1.createCell(1).setCellValue("姓名");
        row1.createCell(2).setCellValue("城市");

        XSSFRow row2 = sheet.createRow(1);
        row2.createCell(1).setCellValue("张三");
        row2.createCell(2).setCellValue("北京");

        XSSFRow row3 = sheet.createRow(2);
        row3.createCell(1).setCellValue("李四");
        row3.createCell(2).setCellValue("上海");

        FileOutputStream out = new FileOutputStream(new File("D:\\itcast.xlsx"));
        //通过输出流将内存中的Excel文件写入到磁盘上
        excel.write(out);

        //关闭资源
        out.flush();
        out.close();
        excel.close();
    }
    public static void main(String[] args) throws Exception {
        write();
    }
}
  • 此代码实现了基础的写入操作
  • 先使用XSSFWorkbook 拆杆件一个新的sheet页对象
  • 然后通过row方法创建行
  • row对象中可使用creatceCell方法填充内容

读操作

  • 开发代码
public class POITest {

    public static void read() throws Exception{
        FileInputStream in = new FileInputStream(new File("D:\\itcast.xlsx"));
        //通过输入流读取指定的Excel文件
        XSSFWorkbook excel = new XSSFWorkbook(in);
        //获取Excel文件的第1个Sheet页
        XSSFSheet sheet = excel.getSheetAt(0);

        //获取Sheet页中的最后一行的行号
        int lastRowNum = sheet.getLastRowNum();
        for (int i = 0; i <= lastRowNum; i++) {
            //获取Sheet页中的行
            XSSFRow titleRow = sheet.getRow(i);
            //获取行的第2个单元格
            XSSFCell cell1 = titleRow.getCell(1);
            //获取单元格中的文本内容
            String cellValue1 = cell1.getStringCellValue();
            //获取行的第3个单元格
            XSSFCell cell2 = titleRow.getCell(2);
            //获取单元格中的文本内容
            String cellValue2 = cell2.getStringCellValue();

            System.out.println(cellValue1 + " " +cellValue2);
        }

        //关闭资源
        in.close();
        excel.close();
    }

    public static void main(String[] args) throws Exception {
        read();
    }
}
  • XSSFRow创建读取类
  • 使用getSheetAt方法获得sheet
  • getRow和getCell方法获取单元格和对应的文本内容

导出运营数据

需求分析

  • 先确定导出的Excel报表格式
  • 然后导出最近三十天的运营数据
  • 表格的形式已经固定
  • 只填充其中的数据即可
  • 导出本质上是下载文件
  • 不需要请求参数和返回数据

代码开发

  • 实际开发中 需要生成的报表可能较为复杂
  • 一般不使用poi生成 而是手动生成模板文件
  • 之后使用poi读取文件 并且填充数据
  • 通过输出流将Excel文件下载到客户端浏览器
  • 课程资料内已提供excel模板文件
  • 复制到resource.template文件夹中

Controller层

  • 在ReportController文件中添加方法
@GetMapping("/export")  
@ApiOperation("输出数据报表")  
public void export(HttpServletResponse response){  
    reportService.exportBusinessData(response);  
}

Service层

  • 在ReportService层声明方法
 void exportBusinessData(HttpServletResponse response)
  • 在实现类中实现
@Autowired  
private WorkspaceService workspaceService;

@Override  
public void exportBusinessData(HttpServletResponse response) {  
    //查询数据库 获取营业数据  
    //从工作台获取统计好的数据  
    //查询30天的数据  
    LocalDate dataBegin = LocalDate.from(LocalDateTime.now().minusDays(30));  
    LocalDate dataEnd = LocalDate.from(LocalDateTime.now().minusDays(1));  
  
    //查询概览数据  
  
        BusinessDataVO businessDataVO = workspaceService.getBusinessData  
                (LocalDateTime.of(LocalDate.now(), LocalTime.MIN),  
                 LocalDateTime.of(LocalDate.now(), LocalTime.MAX));  
    //通过POI将数据写入Excel  
    //基于模板创建一个新的Excel文件  
    //读取模板文件  
    //模板文件放在resource目录下  
    InputStream in = this.getClass().getClassLoader()  
            .getResourceAsStream("template/运营数据报表模板");  
    try{  
        XSSFWorkbook excel = new XSSFWorkbook(in);  
        //填充数据--时间  
        excel.getSheet("Sheet1").getRow(1).getCell(1)  
                .setCellValue("时间:" + dataBegin + "至" + dataEnd);  
        //填充数据--营业额  
        excel.getSheet("Sheet1").getRow(3).getCell(2)  
                .setCellValue(businessDataVO.getTurnover());  
        //填充数据--有效订单完成率  
        excel.getSheet("Sheet1").getRow(3).getCell(4)  
                .setCellValue(businessDataVO.getOrderCompletionRate());  
        //填充数据--新增用户数  
        excel.getSheet("Sheet1").getRow(3).getCell(6)  
                .setCellValue(businessDataVO.getNewUsers());  
        //填充数据--有效订单数  
        excel.getSheet("Sheet1").getRow(4).getCell(2)  
                .setCellValue(businessDataVO.getValidOrderCount());  
        //填充数据--平均客单价  
        excel.getSheet("Sheet1").getRow(4).getCell(4)  
                .setCellValue(businessDataVO.getUnitPrice());  
  
        //填充明细数据  
        //按照每天一次获取日期 营业额 有效订单 订单完成率 平均客单价 新增用户数  
        for(int i = 0 ;  i < 30 ;i++){  
            LocalDate date = dataBegin.plusDays(i);  
            workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));  
            //获得某一行  
            //日期  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(1)  
                    .setCellValue(date.toString());  
            //营业额  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(2)  
                    .setCellValue(businessDataVO.getTurnover());  
            //有效订单数  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(3)  
                    .setCellValue(businessDataVO.getValidOrderCount());  
            //订单完成率  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(4)  
                    .setCellValue(businessDataVO.getOrderCompletionRate());  
            //平均客单价  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(5)  
                    .setCellValue(businessDataVO.getUnitPrice());  
            //新增用户数  
            excel.getSheet("Sheet1").getRow(7 + i).getCell(6)  
                    .setCellValue(businessDataVO.getNewUsers());  
        }  
  
        //通过输出流将Excel文件写回浏览器  
        ServletOutputStream out = response.getOutputStream();  
        excel.write(out);  
  
        //关闭资源  
        out.close();  
        excel.close();  
    }catch (IOException e){  
        e.printStackTrace();  
    }  
  
}  
  
private Integer getOrderCount(LocalDateTime beginTime, LocalDateTime endTime, Integer status) {  
    Map map = new HashMap();  
    map.put("status", status);  
    map.put("begin",beginTime);  
    map.put("end", endTime);  
    return orderMapper.countByMap(map);  
}  
  
private Integer getUserCount(LocalDateTime beginTime, LocalDateTime endTime) {  
    Map map = new HashMap();  
    map.put("begin",beginTime);  
    map.put("end", endTime);  
    return userMapper.countByMap(map);  
}

想温柔的对待这个世界