《苍穹外卖》Day12部分知识点记录——数据统计-Excel报表

一、工作台

需求分析和设计

接口设计

  • 今日数据接口
  • 订单管理接口
  • 菜品总览接口
  • 套餐总览接口
  • 订单搜索(已完成)
  • 各个状态的订单数量统计(已完成)

代码实现

今日数据接口

1. WorkspaceController

注意不要导错包了

package com.sky.controller.admin;import com.sky.result.Result;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;
import java.time.LocalTime;/*** 工作台*/
@RestController
@RequestMapping("/admin/workspace")
@Slf4j
@Api(tags = "工作台相关接口")
public class WorkspaceController {@Autowiredprivate WorkspaceService workspaceService;/*** 工作台今日数据查询* @return*/@GetMapping("/businessData")@ApiOperation("工作台今日数据查询")public Result<BusinessDataVO> businessData() {// 获取当天的开始时间LocalDateTime begin = LocalDateTime.now().with(LocalTime.MIN);// 获取当天的结束时间LocalDateTime end = LocalDateTime.now().with(LocalTime.MAX);BusinessDataVO businessDataVO = workspaceService.getBusinessData(begin, end);return Result.success(businessDataVO);}
}

2. WorkspaceService

    /*** 根据时间段统计营业数据* @param begin* @param end* @return*/BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end);

3. WorkspaceServiceImpl

package com.sky.service.impl;import com.sky.entity.Orders;
import com.sky.mapper.DishMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserMapper userMapper;@Autowiredprivate DishMapper dishMapper;@Autowiredprivate SetmealMapper setmealMapper;/*** 根据时间段统计营业数据* @param begin* @param end* @return*/@Overridepublic BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {/*** 营业额:当日已完成订单的总金额* 有效订单:当日已完成订单的数量* 平均客单价:营业额 / 有效订单数* 新增用户:当日新增用户的数量*/Map map = new HashMap();map.put("begin", begin);map.put("end", end);// 查询总订单数Integer totalOrderCount = orderMapper.countByMap(map);map.put("status", Orders.COMPLETED);// 营业额Double turnover = orderMapper.sumByMap(map);turnover = turnover == null ? 0.0 : turnover;// 有效订单数Integer validOrderCount = orderMapper.countByMap(map);Double unitPrice = 0.0;Double orderCompletionRate = 0.0;if(totalOrderCount != 0 && validOrderCount != 0) {// 订单完成率orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;// 平均客单价unitPrice = turnover / validOrderCount;}// 新增用户数Integer newUsers = userMapper.countByMap(map);return BusinessDataVO.builder().turnover(turnover).validOrderCount(validOrderCount).orderCompletionRate(orderCompletionRate).unitPrice(unitPrice).newUsers(newUsers).build();}
}

4. 功能测试

订单管理接口

1. WorkspaceController

    /*** 查询订单管理数据* @return*/@GetMapping("/overviewOrders")@ApiOperation("查询订单管理数据")public Result<OrderOverViewVO> orderOverView() {return Result.success(workspaceService.getOrderOverView());}

2. WorkspaceService

    /*** 查询订单管理数据* @return*/OrderOverViewVO getOrderOverView();

3. WorkspaceServiceImpl

    /*** 查询订单管理数据* @return*/@Overridepublic OrderOverViewVO getOrderOverView() {Map map = new HashMap();map.put("begin", LocalDateTime.now().with(LocalTime.MIN));// 待接单map.put("status", Orders.TO_BE_CONFIRMED);  Integer waitingOrders = orderMapper.countByMap(map);// 待派送map.put("status", Orders.CONFIRMED);Integer deliveredOrders = orderMapper.countByMap(map);// 已完成map.put("status", Orders.COMPLETED);Integer completedOrders = orderMapper.countByMap(map);// 已取消map.put("status", Orders.CANCELLED);Integer cancelledOrders = orderMapper.countByMap(map);// 全部订单map.put("status", null);Integer allOrders = orderMapper.countByMap(map);return OrderOverViewVO.builder().waitingOrders(waitingOrders).deliveredOrders(deliveredOrders).completedOrders(completedOrders).cancelledOrders(cancelledOrders).allOrders(allOrders).build();}

4. 测试

菜品总览接口 

1. WorkspaceController

    /*** 查询菜品总览* @return*/@GetMapping("/overviewDishes")@ApiOperation("查询菜品总览")public Result<DishOverViewVO> dishOverView() {return Result.success(workspaceService.getDishOverView());}

2. WorkspaceService

    /*** 查询菜品总览* @return*/DishOverViewVO getDishOverView();

3. WorkspaceServiceImpl

    /*** 查询菜品总览* @return*/@Overridepublic DishOverViewVO getDishOverView() {Map map = new HashMap();map.put("status", StatusConstant.ENABLE);Integer sold = dishMapper.countByMap(map);map.put("status", StatusConstant.DISABLE);Integer discontinued = dishMapper.countByMap(map);return DishOverViewVO.builder().sold(sold).discontinued(discontinued).build();}

4. DishMapper

    /*** 根据条件统计菜品数量* @param map* @return*/Integer countByMap(Map map);

5. DishMapper.xml

    <select id="countByMap" resultType="java.lang.Integer">select count(id) from dish<where><if test="status != null">and status = #{status}</if><if test="categoryId != null">and category_id = #{categoryId}</if></where></select>

6. 测试

套餐总览接口

1. WorkspaceController

    /*** 查询套餐总览* @return*/@GetMapping("/overviewSetmeals")@ApiOperation("查询套餐总览")public Result<SetmealOverViewVO> setmealOverView() {return Result.success(workspaceService.getSetmealOverView());}

2. WorkspaceService

    /*** 查询套餐总览* @return*/SetmealOverViewVO getSetmealOverView();

3. WorkspaceServiceImpl

    /*** 查询套餐总览* @return*/@Overridepublic SetmealOverViewVO getSetmealOverView() {Map map = new HashMap();map.put("status", StatusConstant.ENABLE);Integer sold = setmealMapper.countByMap(map);map.put("status", StatusConstant.DISABLE);Integer discontinued = setmealMapper.countByMap(map);return SetmealOverViewVO.builder().sold(sold).discontinued(discontinued).build();}

4. SetmealMapper

    /*** 根据条件统计套餐数量* @param map* @return*/Integer countByMap(Map map);

5. SetmealMapper.xml

    <select id="countByMap" resultType="java.lang.Integer">select count(id) from setmeal<where><if test="status != null">and status = #{status}</if><if test="categoryId != null">and category_id = #{categoryId}</if></where></select>

6. 测试

二、Apache POI

介绍

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

Apache POI的应用场景

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

入门案例

1. 导入Apache POI的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>

2. POITest

package com.sky.test;import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;/*** 使用POI操作excel文件*/
public class POITest {/*** 通过POI创建EXCEL文件并且写入文件内容*/public static void write() throws Exception {// 在内存中创建一个excel文件XSSFWorkbook excel = new XSSFWorkbook();// 在excel文件中创建一个新的sheet页XSSFSheet sheet = excel.createSheet("info");// 在sheet页中创建行对象,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("E:\\info.xlsx"));excel.write(out);// 关闭资源out.close();excel.close();}/*** 通过POI读取EXCEL文件中的内容* @throws Exception*/public static void read() throws Exception {// 读取磁盘上已经存在的excel文件FileInputStream in = new FileInputStream(new File("E:\\info.xlsx"));XSSFWorkbook excel = new XSSFWorkbook(in);// 读取excel文件中的第一个sheet页XSSFSheet sheet = excel.getSheetAt(0);// 获取sheet中最后一行的行号int lastRowNum = sheet.getLastRowNum();for (int i = 1; i <= lastRowNum; i++) {// 获得某一行XSSFRow row = sheet.getRow(i);// 获得某个单元格对象String cellValue = row.getCell(1).getStringCellValue();String cellValue2 = row.getCell(2).getStringCellValue();System.out.println(cellValue + " " + cellValue2);}// 关闭资源in.close();excel.close();}public static void main(String[] args) throws Exception {write();read();}
}

3. 测试

三、导出运营数据Excel报表

需求分析和设计

产品原型

导出的Excel报表格式

业务规则

  • 导出Excel形式的报表文件
  • 导出最近30天的运营数据

接口设计

注意:当前接口没有返回数据,因为报表导出功能本质上是文件下载,服务端会通过输出流将Excel文件下载到客户端浏览器。

代码开发

实现步骤:

  • ①设计Excel模板文件
  • ②查询近30天的运营数据
  • ③将查询到的运营数据写入模板文件
  • ④通过输出流将Excel文件下载到客户端浏览器

1. ReportController

    /*** 导出运营数据报表* @param response*/@GetMapping("/export")@ApiOperation("导出运营数据报表")public void export(HttpServletResponse response) {reportService.exportBusinessData(response);}

2. ReportService

    /*** 导出运营数据报表* @param response*/void exportBusinessData(HttpServletResponse response);

3. ReportServiceImpl

    @Autowiredprivate WorkspaceService workspaceService;/*** 导出运营数据报表* @param response*/@Overridepublic void exportBusinessData(HttpServletResponse response) {// 1. 查询数据库,获取营业数据--查询最近30天的运营数据LocalDate dateBegin = LocalDate.now().minusDays(30);LocalDate dateEnd = LocalDate.now().minusDays(1);LocalDateTime beginTime = LocalDateTime.of(dateBegin, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(dateEnd, LocalTime.MAX);// 查询概览数据BusinessDataVO businessDataVO = workspaceService.getBusinessData(beginTime, endTime);// 2. 通过POI把查询到的数据写道到excel文件中InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");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 (IOException e) {e.printStackTrace();}}

功能测试

完结撒花~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/4467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经典算法】LeetCode104二叉树的最大深度(Java/C/Python3实现含注释说明,Easy)

目录 题目描述思路及实现方式一&#xff1a;递归思路代码实现Java版本C语言版本Python3版本Go语言版本 复杂度分析 方式二&#xff1a;广度优先搜索(BFS)思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相似题目 标签(题目类型)&#xff1a;树、深度优先搜索(DFS)、…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

多进程编程:原理、技术与应用

title: 多进程编程&#xff1a;原理、技术与应用 date: 2024/4/26 12:14:47 updated: 2024/4/26 12:14:47 categories: 后端开发 tags: 多进程并发编程网络服务分布式系统任务处理进程池线程对比 第一章&#xff1a;进程与线程 进程与线程的概念及区别&#xff1a; 进程&am…

gitcode 上传文件报错文件太大has exceeded the upper limited size

报错 remote: Start Git Hooks Checking Error: Deny by project hooks setting ‘default’ has exceeded the upper limited size (10 MB) in commit 当前有效的解决方案 项目设置->提交设置->勾选管理员不受规则限制->提交 重新push&#xff0c;提交成功

Vitis HLS 学习笔记--IDE软件高效操作指引

目录 1. 简介 2. 实用软件操作 2.1 C/RTL Cosimulation 选项 2.2 Do not show this dialog again 2.3 New Solution 2.4 对比 Solution 2.5 以命令行方式运行&#xff08;windows&#xff09; 2.6 文本缩放快捷键 2.7 查看和修改快捷键 2.8 将Vitis HLS RTL 导入 Viv…

Oracle集群ORA-03113:end-of-file on communication channel

一、问题场景描述 今天Oracle集群要更新各数据库的数据&#xff0c;折腾的启动不了了&#xff1a; --》数据量比较大&#xff0c;数据泵方式导出的dmp文件 准备导入集群 --》由于之前的生产数据库数据比较少&#xff0c;需要增大表空间。 --》于是在sqlplus命令窗口&#xff0c…

【JavaWeb】Day51.Mybatis动态SQL(一)

什么是动态SQL 在页面原型中&#xff0c;列表上方的条件是动态的&#xff0c;是可以不传递的&#xff0c;也可以只传递其中的1个或者2个或者全部。 而在我们刚才编写的SQL语句中&#xff0c;我们会看到&#xff0c;我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字…

进程地址空间 【Linux】

文章目录 进程地址空间 进程地址空间 进程地址空间&#xff0c;本质是一个描述进程可视范围的大小&#xff0c; 地址空间内一定要存在各种区域划分&#xff0c;对线性地址进行start&#xff0c;和end即可 在每一个区的_start 到_end 范围内&#xff0c;这段连续的空间中&…

深入探索计算机视觉:高级主题与前沿应用的全面解析

引言 计算机视觉&#xff0c;作为人工智能领域的一个重要分支&#xff0c;旨在让计算机能够“看”懂世界&#xff0c;理解和解释视觉场景。随着深度学习技术的迅猛发展&#xff0c;计算机视觉已经在许多领域取得了显著的进展&#xff0c;如自动驾驶、安防监控、医疗诊断等。在…

JDBC查询大数据时怎么防止内存溢出-流式查询

文章目录 1.前言2.流式查询介绍3.使用流式查询3.1不开启流式查询的内存占用情况3.2开启流式查询的内存占用情况 4.开启流式查询的注意点 1.前言 在使用 JDBC 查询大数据时&#xff0c;由于 JDBC 默认将整个结果集加载到内存中&#xff0c;当查询结果集过大时&#xff0c;很容易…

刷机维修进阶教程----小米6 6x 5x机型修复基带 改写参数 改写串码实例步骤操作解析

在于众多工作室 业务接洽中有很多需要过新机的业务需求。那么大多都在机型参数和型号上面有关联。众所周知,改写机型参数为不允许的行为。操作只为解惑参数的一些常识,修复合规参数和修复手机系统为目的,请遵守国安家法律法规,今天将详细通过实例演示来解析小米6 6x 5x这些…

Fast-DetectGPT 无需训练的快速文本检测

本文提出了一种新的文本检测方法 ——Fast-DetectGPT&#xff0c;无需训练&#xff0c;直接使用开源小语言模型检测各种大语言模型&#xff0c;如GPT等生成的文本内容。 Fast-DetectGPT 将检测速度提高了 340 倍&#xff0c;将检测准确率相对提升了 75%&#xff0c;超过商用系…

【中级软件设计师】上午题12-软件工程(1):软件工程模型、敏捷方法、软件需求、系统设计

上午题12-软件工程&#xff08;1&#xff09; 1 软件过程1.1 CMM 能力成熟度模型1.1 CMMI (建议直接看思维导图&#xff09; 2 软件过程模型2.1 瀑布模型2.2 增量模型2.3 演化模型2.3.1 原型模型2.3.2 螺旋模型 2.5 喷泉模型 3 统一过程&#xff08;UP&#xff09;模型4 敏捷方…

【python】利用 GridSearchCV 和 SVM 进行学生成绩预测

在机器学习领域&#xff0c;寻找最优模型参数是一个重要的步骤&#xff0c;它直接影响模型的泛化能力和预测准确性。本文将通过一个具体案例介绍如何使用支持向量机&#xff08;SVM&#xff09;和网格搜索&#xff08;GridSearchCV&#xff09;来预测学生的成绩&#xff0c;并通…

可审批可审计追溯的单网络导出文件方案,了解一下

在物理隔离状态下&#xff0c;单网络导出文件是一个重要的安全需求&#xff0c;特别是在处理敏感数据时。在这种环境下&#xff0c;数据导出需要采取特殊的安全措施&#xff0c;以确保数据传输的安全性和合规性。需要考虑以下因素&#xff1a; 安全性&#xff1a;确保传输过程加…

筛选日志并生成序列化文件

1.在idea中创建项目 selectData. 2.添加依赖&#xff0c;插件包&#xff0c;指定打包方式&#xff0c;日志文件 大家可以直接从前面项目复制。 3.本次只需要进行序列化操作&#xff0c;所以不需要Reducer模块&#xff0c;编写Mapper模块 package com.maidu.selectdata;import…

Bert基础(十八)--Bert实战:NER命名实体识别

1、命名实体识别介绍 1.1 简介 命名实体识别&#xff08;NER&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一项关键技术&#xff0c;它的目标是从文本中识别出具有特定意义或指代性强的实体&#xff0c;并对这些实体进行分类。这些实体通常包括人名、地名、组织…

极简shell制作

&#x1f30e;自定义简单shell制作 &#xff08;ps: 文末有完整代码&#xff09; 文章目录&#xff1a; 自定义简单shell制作 简单配置Linux文件 自定义Shell编写 命令行解释器       获取输入的命令       字符串分割       子进程进行进程替换 内建命令…

28.Gateway-网关过滤器

GatewayFilter是网关中提供的一种过滤器&#xff0c;可以多进入网关的请求和微服务返回的响应做处理。 GatewayFilter(当前路由过滤器&#xff0c;DefaultFilter) spring中提供了31种不同的路由过滤器工厂。 filters针对部分路由的过滤器。 default-filters针对所有路由的默认…

opencv基础篇 ——(九)图像几何变换

图像几何变换是通过对图像的几何结构进行变换来改变图像的形状、大小、方向或者透视关系。常见的图像几何变换包括缩放、旋转、平移、仿射变换和透视变换等。下面对这些几何变换进行简要介绍&#xff1a; 矩阵的转置&#xff08;transpose &#xff09;&#xff1a; 对于图像来…