课程内容
- 完成工作台功能
- Apache POI
- 导出运营数据Excel报表
工作台
需求分析
- 系统运营的数据看板
- 提供快捷操作入口
- 展示数据包括
- 工作台应当设计多个接口
- 今日数据接口
- 订单管理接口
- 菜品总览接口
- 套餐总览接口
- 订单搜索(已完成)
- 各个状态订单数据统计(已完成)
代码开发
- 已经提供了代码 直接导入即可
- 都是之前学习过的内容 这里不再赘述
Apache POI
基础介绍
- 处理Office文件格式的开源项目
- 可以用POI在Java程序中对Office各种文件进行读写操作
- 一般用于操作Excel文件
应用场景
- 网银系统导出交易明细
- 各种业务系统导出Excel报表
- 批量导入业务数据
入门案例
<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层
@GetMapping("/export")
@ApiOperation("输出数据报表")
public void export(HttpServletResponse response){
reportService.exportBusinessData(response);
}
Service层
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);
}