苍穹外卖学习笔记(十二)

数据统计-Excel 报表

工作台

今日数据接口

WorkSpaceController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@RestController
@RequestMapping("/admin/workspace")
@Slf4j
@Api(tags = "工作台")
public class WorkSpaceController {

@Autowired
private WorkspaceService workspaceService;

/**
* 查询今日运营数据
*/
@GetMapping("/businessData")
@ApiOperation(value = "查询今日运营数据")
public Result<BusinessDataVO> businessData() {
log.info("查询今日运营数据");
//获得当天的开始时间
LocalDateTime begin = LocalDateTime.now().with(LocalTime.MIN);
//获得当天的结束时间
LocalDateTime end = LocalDateTime.now().with(LocalTime.MAX);
BusinessDataVO businessDataVO = workspaceService.getBusinessData(begin, end);
return Result.success(businessDataVO);
}
}

WorkspaceService

1
2
3
4
5
6
7
public interface WorkspaceService {

/**
* 查询今日运营数据
*/
BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end);
}

WorkspaceServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {

@Autowired
private OrderMapper orderMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private DishMapper dishMapper;
@Autowired
private SetmealMapper setmealMapper;

/**
* 查询今日运营数据
*/
@Override
public 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();
}
}

订单管理接口

WorkSpaceController

1
2
3
4
5
6
7
8
9
10
/**
* 查询订单管理数据
*/
@GetMapping("/overviewOrders")
@ApiOperation(value = "查询订单管理数据")
public Result<OrderOverViewVO> orderOverView() {
log.info("查询订单概况");
OrderOverViewVO orderOverViewVO = workspaceService.getOrderOverView();
return Result.success(orderOverViewVO);
}

WorkspaceService

1
2
3
4
/**
* 查询订单管理数据
*/
OrderOverViewVO getOrderOverView();

WorkspaceServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* 查询订单管理数据
*/
@Override
public 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();
}

菜品总览接口

WorkSpaceController

1
2
3
4
5
6
7
8
/**
* 查询菜品总览
*/
@GetMapping("/overviewDishes")
@ApiOperation("查询菜品总览")
public Result<DishOverViewVO> dishOverView(){
return Result.success(workspaceService.getDishOverView());
}

WorkspaceService

1
2
3
4
/**
* 查询菜品管理数据
*/
DishOverViewVO getDishOverView();

WorkspaceServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 查询菜品总览
*/
@Override
public DishOverViewVO getDishOverView() {
LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<Dish>().eq(Dish::getStatus, StatusConstant.ENABLE);
Long sold = dishMapper.selectCount(wrapper);

Wrapper<Dish> wrapper1 = new LambdaQueryWrapper<Dish>().eq(Dish::getStatus, StatusConstant.DISABLE);
Long discontinued = dishMapper.selectCount(wrapper1);

return DishOverViewVO.builder()
.sold(sold.intValue())
.discontinued(discontinued.intValue())
.build();
}

套餐总览接口

WorkSpaceController

1
2
3
4
5
6
7
8
/**
* 查询套餐总览
*/
@GetMapping("/overviewSetmeals")
@ApiOperation("查询套餐总览")
public Result<SetmealOverViewVO> setmealOverView(){
return Result.success(workspaceService.getSetmealOverView());
}

WorkspaceService

1
2
3
4
/**
* 查询套餐管理数据
*/
SetmealOverViewVO getSetmealOverView();

WorkspaceServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 查询套餐总览
*/
@Override
public SetmealOverViewVO getSetmealOverView() {
LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<Setmeal>().eq(Setmeal::getStatus, StatusConstant.ENABLE);
Long sold = setmealMapper.selectCount(wrapper);

Wrapper<Setmeal> wrapper1 = new LambdaQueryWrapper<Setmeal>().eq(Setmeal::getStatus, StatusConstant.DISABLE);
Long discontinued = setmealMapper.selectCount(wrapper1);

return SetmealOverViewVO.builder()
.sold(sold.intValue())
.discontinued(discontinued.intValue())
.build();
}

Apache POI

介绍

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

一般情况下,POI 都是用于操作 Excel 文件

应用场景:

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

入门案例

1. 导入 maven 坐标

1
2
3
4
5
6
7
8
9
10
11
<!-- poi -->
<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>

2. POITest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.sky.test;

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.FileOutputStream;

/**
* @author Jie.
* @description: TODO
* @date 2024/10/22
* @version: 1.0
*/
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(0);
//在每一行上创建单元格
row.createCell(0).setCellValue("姓名");
row.createCell(1).setCellValue("城市");

row = sheet.createRow(1);

row.createCell(0).setCellValue("张三");
row.createCell(1).setCellValue("北京");

row = sheet.createRow(2);

row.createCell(0).setCellValue("李四");
row.createCell(1).setCellValue("天津");

FileOutputStream out = new FileOutputStream(new File("D:\\info.xlsx"));
excel.write(out);

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

//通过POI读取Excel文件并且读入文件内容
public static void read() throws Exception{
//读取磁盘上已经存在的excel文件
FileInputStream fileInputStream = new FileInputStream("D:\\info.xlsx");
XSSFWorkbook excel = new XSSFWorkbook(fileInputStream);
XSSFSheet sheet = excel.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();

for (int i = 1;i <= lastRowNum; i++) {
XSSFRow row = sheet.getRow(i);
String name = row.getCell(0).getStringCellValue();
String name1 = row.getCell(1).getStringCellValue();
System.out.println(name + " " + name1);
}
}

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

导出运营数据 Excel 报表

ReportController

1
2
3
4
5
@GetMapping("/export")
@ApiOperation("导出Excel报表")
public void export(HttpServletResponse response) {
reportService.exportBusinessData(response);
}

ReportService

1
2
3
4
5
/**
* 导出
* @param response 响应
*/
void exportBusinessData(HttpServletResponse response);

ReportServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* 导出
*
* @param response 响应
*/
@Override
public void exportBusinessData(HttpServletResponse response) {
//1. 查询数据库,获取营业数据
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));

//2. 通过POI将数据写入到Excel文件中
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
try {
XSSFWorkbook excel = new XSSFWorkbook(in);
//填充营业额数据
XSSFSheet sheet = excel.getSheet("Sheet1");
sheet.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd);
XSSFRow row = sheet.getRow(3);
row.getCell(2).setCellValue(businessDataVO.getTurnover());
row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
row.getCell(6).setCellValue(businessDataVO.getNewUsers());

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) {
throw new RuntimeException(e);
}
}

❤️❤️❤️ 完结撒花 ❤️❤️❤️