[苍穹外卖]-12Apache POI入门与实战

工作台

需求分析: 工作台是系统运营的数据看板, 并提供快捷操作入口, 可以有效提高商家的工作效率

  1. 营业额: 已完成订单的总金额
  2. 有效订单: 已经完成订单的数量
  3. 订单完成率: 有效订单数/总订单数*100%
  4. 平均客单价: 营业额/有效订单数
  5. 新增用户: 新增的用户数量

接口设计: 一个接口返回所有数据, 会导致后端代码耦合严重, 所以还是按照模块, 划分接口

  1. 今日数据接口
  1. 订单管理接口
  1. 菜品总览接口
  1. 套餐总览接口

代码导入: 按需复制, 不要覆盖之前的代码

功能测试

Apache POI

Apache POI是一个处理Office各种文件格式的开源项目, 我们可以使用POI在java程序中对Office的各种文件进行读写操作, 一般情况下, POI都是用于读写Excel文件

快速入门: 引入坐标, 编写测试方法, 写入和读取Excel文件

复制代码
<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>${poi}</version>
</dependency>
<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>${poi}</version>
</dependency

/**
 * 使用POI操作Excel文件
 */
public class ApachePoiTest {

    /**
     * 通过POI创建Excel文件并且写入文件内容
     * POI代码的可读性很高, 跟手动操作Excel的步骤相似
     */
    public static void write() throws Exception {
        //在内存中创建一个Excel对象
        XSSFWorkbook excel = new XSSFWorkbook();
        //在Excel文件中创建一个Sheet页
        XSSFSheet sheet = excel.createSheet("info");
        //在Sheeet页中创建行对象, rownum编号从0开始
        XSSFRow row = sheet.createRow(1);
        //创建单元格并且写入文件内容
        row.createCell(1).setCellValue("姓名");
        row.createCell(2).setCellValue("城市");
        //创建一个新行
        row = sheet.createRow(2);
        //在新行中创建单元格
        row.createCell(1).setCellValue("张三");
        row.createCell(2).setCellValue("北京");
        //创建一个新行
        row = sheet.createRow(3);
        //在新行中创建单元格
        row.createCell(1).setCellValue("李四");
        row.createCell(2).setCellValue("南京");

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

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

    public static void main(String[] args) throws Exception {
       write();
    }

}
复制代码
/**
 * 使用POI操作Excel文件
 */
public class ApachePoiTest {
    /*
     * 通过 POI 读取Excel文件中的内容
     *
     * @throws Exception
     */
    public static void read() throws Exception {
        //通过输入流获取文件对象
        InputStream in = new FileInputStream(new File("C:\\Users\\Lenovo\\Desktop\\test.xlsx"));
        //创建Excel对象,  通过Excel对象读取文件
        XSSFWorkbook excel = new XSSFWorkbook(in);
        //读取Excel文件中的第一个Sheet页(索引从0开始)
        XSSFSheet sheet = excel.getSheetAt(0);
        //获取Sheet页最后一行的行号(最后的有文字的行的行号)
        int lastRowNum = sheet.getLastRowNum();
        //遍历每一行,读取每个单元格的数据(第一行没数据, 所以从第二行开始读)
        for (int i = 1; i < lastRowNum; i++) {
            //获取某一行
            XSSFRow row = sheet.getRow(i);
            //获取单元格对象
            String cellValue1 = row.getCell(1).getStringCellValue();
            String cellValue2 = row.getCell(2).getStringCellValue();
            //拼接读取到的单元格内容
            System.out.println(cellValue1 + ":" + cellValue2);

        }

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

    public static void main(String[] args) throws Exception {
       read();
    }

}

导出运营报表

需求分析: 导出Excel形式的报表文件, 导出最近30天的运营数据

接口设计: 该接口无需返回数据, 报表导出功能本质是文件下载, 服务端通过输出流将Excel文件下载到客户端浏览器即可

设计Excel模版文件, 以简化代码, 降低编码难度, 模版文件放在resources/template/运行数据报表模版.xlsx

controller

复制代码
/**
 * 数据统计相关接口
 */
@RestController
@RequestMapping("/admin/report")
@Api(tags = "数据统计相关接口")
@Slf4j
public class ReportController {
   /**
     * 导出运营数据报表
     * @param response
     */
    @GetMapping("/export")
    @ApiOperation("导出运营数据报表")
    public void export(HttpServletResponse response) {
        // 通过 HttpServletRequest对象 获取输出流对象
        reportService.exportBusinessData(response);
    }
    
}

service

复制代码
public interface ReportService {
  /**
    * 导出运营数据报表
    * @param response
    */
  void exportBusinessData(HttpServletResponse response);
    
}

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
   /**
     * 导出运营数据报表
     *
     * @param response
     */
    public void exportBusinessData(HttpServletResponse response) {
        //1, 查询数据库, 获取营业数据----查询最近30天的运营数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);  // 计算开始日期
        LocalDate dateEnd = LocalDate.now().minusDays(1); // 计算结束时间
        // 查询概览数据
        BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));
       // 获取文件的输出流对象
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        //2, 通过POI将数据写入到Excel文件中
           
        try {
            // 获取excel对象
            XSSFWorkbook excel = new XSSFWorkbook(in);
            // 获取sheet页对象
            XSSFSheet sheet = excel.getSheet("Sheet1");
            // 填充概览数据(先获取行, 在获取单元格, 在写入)
            sheet.getRow(1).getCell(1).setCellValue("时间: " + dateBegin + "至" + dateEnd);
            // 填充数据(获取新行--第4行)
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            // 填充数据(获取新行--第5行)
               row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());
            
            // 填充明细数据
            for (int i = 0; i < 30; i++) {
                LocalDate date = dateBegin.plusDays(i);
                //查询某一天的营业数据
                BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                //获取某一行(在获取单元格,写入数据)
                row = sheet.getRow(7 + i);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }
            
            //3,通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //4,关闭资源
            out.close();
            excel.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

功能测试

相关推荐
李慕婉学姐7 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆8 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin9 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20059 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉9 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国9 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882489 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈10 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_9910 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹10 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理