[苍穹外卖]-12Apache POI入门与实战
工作台
需求分析: 工作台是系统运营的数据看板, 并提供快捷操作入口, 可以有效提高商家的工作效率
- 营业额: 已完成订单的总金额
- 有效订单: 已经完成订单的数量
- 订单完成率: 有效订单数/总订单数*100%
- 平均客单价: 营业额/有效订单数
- 新增用户: 新增的用户数量
接口设计: 一个接口返回所有数据, 会导致后端代码耦合严重, 所以还是按照模块, 划分接口
- 今日数据接口
- 订单管理接口
- 菜品总览接口
- 套餐总览接口
代码导入: 按需复制, 不要覆盖之前的代码
功能测试
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();
}
}
}
功能测试