<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html"><head><!-- 页面meta --><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>瑞通健康</title><meta name="description" content="瑞通健康"><meta name="keywords" content="瑞通健康"><meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"><!-- 引入样式 --><link rel="stylesheet" href="../plugins/elementui/index.css"><link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css"><link rel="stylesheet" href="../css/style.css"><style>.grid-content {border-radius: 4px;min-height: 40px;}</style></head><body class="hold-transition"><div id="app"><div class="content-header"><h1>统计分析<small>运营数据</small></h1><el-breadcrumb separator-class="el-icon-arrow-right" class="breadcrumb"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>统计分析</el-breadcrumb-item><el-breadcrumb-item>运营数据</el-breadcrumb-item></el-breadcrumb></div><div class="app-container"><div class="box" style="height: 900px"><div class="excelTitle" ><el-button @click="exportExcel">导出Excel</el-button>运营数据统计</div><div class="excelTime">日期:{{reportData.reportDate}}</div><table class="exceTable" cellspacing="0" cellpadding="0"><tr><td colspan="4" class="headBody">会员数据统计</td></tr><tr><td width='20%' class="tabletrBg">新增会员数</td><td width='30%'>{{reportData.todayNewMember}}</td><td width='20%' class="tabletrBg">总会员数</td><td width='30%'>{{reportData.totalMember}}</td></tr><tr><td class="tabletrBg">本周新增会员数</td><td>{{reportData.thisWeekNewMember}}</td><td class="tabletrBg">本月新增会员数</td><td>{{reportData.thisMonthNewMember}}</td></tr><tr><td colspan="4" class="headBody">预约到诊数据统计</td></tr><tr><td class="tabletrBg">今日预约数</td><td>{{reportData.todayOrderNumber}}</td><td class="tabletrBg">今日到诊数</td><td>{{reportData.todayVisitsNumber}}</td></tr><tr><td class="tabletrBg">本周预约数</td><td>{{reportData.thisWeekOrderNumber}}</td><td class="tabletrBg">本周到诊数</td><td>{{reportData.thisWeekVisitsNumber}}</td></tr><tr><td class="tabletrBg">本月预约数</td><td>{{reportData.thisMonthOrderNumber}}</td><td class="tabletrBg">本月到诊数</td><td>{{reportData.thisMonthVisitsNumber}}</td></tr><tr><td colspan="4" class="headBody">热门套餐</td></tr><tr class="tabletrBg textCenter"><td>套餐名称</td><td>预约数量</td><td>占比</td><td>备注</td></tr><tr v-for="s in reportData.hotSetmeal"><td>{{s.name}}</td><td>{{s.setmeal_count}}</td><td>{{s.proportion}}</td><td></td></tr></table></div></div></div></body><!-- 引入组件库 --><script src="../js/vue.js"></script><script src="../plugins/elementui/index.js"></script><script type="text/javascript" src="../js/jquery.min.js"></script><script src="../js/axios-0.18.0.js"></script><script>var vue = new Vue({el: '#app',data:{reportData:{reportDate:null,todayNewMember :0,totalMember :0,thisWeekNewMember :0,thisMonthNewMember :0,todayOrderNumber :0,todayVisitsNumber :0,thisWeekOrderNumber :0,thisWeekVisitsNumber :0,thisMonthOrderNumber :0,thisMonthVisitsNumber :0,hotSetmeal :[{name:'阳光爸妈升级肿瘤12项筛查(男女单人)体检套餐',setmeal_count:200,proportion:0.222},{name:'阳光爸妈升级肿瘤12项筛查体检套餐',setmeal_count:200,proportion:0.222}]}},created() {axios.get("/report/getBusinessReportData.do").then((res)=>{this.reportData = res.data.data;});},methods:{exportExcel(){window.location.href = '/report/exportBusinessReport.do';}}})</script>
</html>
后端代码,先查询表上的数据,封装成对应的前端需要的形式的Map集合
@GetMapping("/getBusinessReportData")public Result getBusinessReportData(){Map<Object,Object> reportData=memberService.getReportExcelResult();return new Result(true,"success",reportData);}
/*** reportDate:null,* todayNewMember :0,* totalMember :0,* thisWeekNewMember :0,* thisMonthNewMember :0,* todayOrderNumber :0,* todayVisitsNumber :0,* thisWeekOrderNumber :0,* thisWeekVisitsNumber :0,* thisMonthOrderNumber :0,* thisMonthVisitsNumber :0,* hotSetmeal :[* {name:'阳光爸妈升级肿瘤12项筛查(男女单人)体检套餐',setmeal_count:200,proportion:0.222},* {name:'阳光爸妈升级肿瘤12项筛查体检套餐',setmeal_count:200,proportion:0.222}* ]
数据形式如上,封装过程如下:
@Overridepublic Map<Object, Object> getReportExcelResult(){Map<Object,Object> resultMap=new HashMap<>();try {System.out.println("=============================");//reportDateString data= Date2Utils.parseDate2String(new Date());System.out.println(data);resultMap.put("reportDate",data);//todayNewMemberint count = memberMapper.selectCurrentDayMemberCount(data);resultMap.put("todayNewMember",count);//totalMemberint totalMember=memberMapper.seelectTotalMember();resultMap.put("totalMember",totalMember);//thisWeekNewMemberint thisWeekNewMember=memberMapper.selectthisWeekNewMember(data);resultMap.put("thisWeekNewMember",thisWeekNewMember);//thisMonthNewMemberint thisMonthNewMember=memberMapper.selectthisMonthNewMember();resultMap.put("thisMonthNewMember",thisMonthNewMember);//todayOrderNumberint todayOrderNumber=orderSettingMapper.selecttodayOrderNumber();resultMap.put("todayOrderNumber",todayOrderNumber);//thisWeekOrderNumberint thisWeekOrderNumber=orderSettingMapper.selectthisWeekOrderNumber();resultMap.put("thisWeekOrderNumber",thisWeekOrderNumber);//thisMonthOrderNumberint thisMonthOrderNumber=orderSettingMapper.selectthisMonthOrderNumber();resultMap.put("thisMonthOrderNumber",thisMonthOrderNumber);//todayVisitsNumberint todayVisitsNumber=orderSettingMapper.selecttodayVisitsNumber();resultMap.put("todayVisitsNumber",todayVisitsNumber);//thisWeekVisitsNumberint thisWeekVisitsNumber=orderSettingMapper.selectthisWeekVisitsNumber();resultMap.put("thisWeekVisitsNumber",thisWeekVisitsNumber);//thisMonthVisitsNumberint thisMonthVisitsNumber=orderSettingMapper.selectthisMonthVisitsNumber();resultMap.put("thisMonthVisitsNumber",thisMonthVisitsNumber);//hotSetmealList<Map<String,String>> hotSetmeal=new ArrayList<>();hotSetmeal=orderSettingMapper.selecthotSetmeal();resultMap.put("hotSetmeal",hotSetmeal);System.out.println(resultMap);} catch (Exception e) {throw new RuntimeException(e);}return resultMap;}
以下是一组时间范围查询的相关的SQL记录:
@Select("SELECT COUNT(0) " +"FROM`t_order` " +"WHERE orderDate = CURDATE() AND orderStatus='已到诊'")int selecttodayVisitsNumber();
@Select("SELECT COUNT(*) " +"FROM `t_order` " +"WHERE orderDate >= DATE_SUB(CURDATE(), INTERVAL 1 WEEK) " +" AND orderDate <= CURDATE() AND orderStatus='已到诊';")int selectthisWeekVisitsNumber();
@Select("SELECT COUNT(*) " +"FROM `t_order` " +"WHERE orderDate >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) " +"AND orderDate <= CURDATE() AND orderStatus='已到诊';")int selectthisMonthVisitsNumber();
@Select("SELECT \n" +" s.`name` AS 'name',\n" +" COUNT(0) AS 'setmeal_count',\n" +" COUNT(0) * 1.0 / (SELECT COUNT(*) FROM `t_order`) AS 'proportion'\n" +" \n" +"FROM \n" +" `t_order` o \n" +"LEFT JOIN \n" +" `t_setmeal` s ON o.`setmeal_id` = s.`id`\n" +"GROUP BY \n" +" s.`id` LIMIT 4;")List<Map<String, String>> selecthotSetmeal();
然后是根据查到的数据导入定制好的格式的Excel表格,并可以使之导出;
@RequestMapping("/exportBusinessReport")public void exportBusinessReport(HttpServletRequest request, HttpServletResponse response) {Map<Object, Object> result = memberService.getReportExcelResult();String reportDate = (String) result.get("reportDate");Integer todayNewMember = (Integer) result.get("todayNewMember");Integer totalMember = (Integer) result.get("totalMember");Integer thisWeekNewMember = (Integer) result.get("thisWeekNewMember");Integer thisMonthNewMember = (Integer) result.get("thisMonthNewMember");Integer todayOrderNumber = (Integer) result.get("todayOrderNumber");Integer thisWeekOrderNumber = (Integer) result.get("thisWeekOrderNumber");Integer thisMonthOrderNumber = (Integer) result.get("thisMonthOrderNumber");Integer todayVisitsNumber = (Integer) result.get("todayVisitsNumber");Integer thisWeekVisitsNumber = (Integer) result.get("thisWeekVisitsNumber");Integer thisMonthVisitsNumber = (Integer) result.get("thisMonthVisitsNumber");List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal");//获得Excel模板文件绝对路径String temlateRealPath = request.getSession().getServletContext().getRealPath("template") +File.separator + "report_template.xlsx";/*** 读取模板文件创建Excel表格对象* File.separator:根据操作系统获取文件分隔符(Windows为\,Linux/Unix为/)*/XSSFWorkbook workbook = null;//初始化XSSFWorkbook对象,用于表示Excel文件。try {//读取Excel模板文件workbook = new XSSFWorkbook(new FileInputStream(new File(temlateRealPath)));//获取Excel的第一个工作表:XSSFSheet sheet = workbook.getSheetAt(0);//示例:获取第3行(索引从0开始),第6个单元格(索引从0开始),并设置其值为reportDateXSSFRow row = sheet.getRow(2);row.getCell(5).setCellValue(reportDate);//日期row = sheet.getRow(4);row.getCell(5).setCellValue(todayNewMember);//新增会员数(本日)row.getCell(7).setCellValue(totalMember);//总会员数row = sheet.getRow(5);row.getCell(5).setCellValue(thisWeekNewMember);//本周新增会员数row.getCell(7).setCellValue(thisMonthNewMember);//本月新增会员数row = sheet.getRow(7);row.getCell(5).setCellValue(todayOrderNumber);//今日预约数row.getCell(7).setCellValue(todayVisitsNumber);//今日到诊数row = sheet.getRow(8);row.getCell(5).setCellValue(thisWeekOrderNumber);//本周预约数row.getCell(7).setCellValue(thisWeekVisitsNumber);//本周到诊数row = sheet.getRow(9);row.getCell(5).setCellValue(thisMonthOrderNumber);//本月预约数row.getCell(7).setCellValue(thisMonthVisitsNumber);//本月到诊数int rowNum = 12;for (Map map : hotSetmeal) {//热门套餐String name = (String) map.get("name");Long setmeal_count = (Long) map.get("setmeal_count");BigDecimal proportion = (BigDecimal) map.get("proportion");row = sheet.getRow(rowNum++);row.getCell(4).setCellValue(name);//套餐名称row.getCell(5).setCellValue(setmeal_count);//预约数量row.getCell(6).setCellValue(proportion.doubleValue());//占比}/*** 获取Servlet的输出流。* 设置响应的内容类型为Excel文件。* 设置响应头,指示浏览器将响应作为附件下载,并指定下载的文件名为report.xlsx。* 将workbook的内容写入输出流。*/ServletOutputStream out = response.getOutputStream();response.setContentType("application/vnd.ms-excel");response.setHeader("content-Disposition", "attachment;filename=report.xlsx");workbook.write(out);/*** 刷新输出流,确保所有数据都被写出。* 关闭输出流和workbook对象,释放资源。*/out.flush();out.close();workbook.close();} catch (IOException e) {throw new RuntimeException(e);}}
知识补充:
1.使用【always-use-default-target="true"】
配置在springSecurity的登陆界面配置中
<!--配置自己的登录页面--><security:form-login login-page="/login.html" username-parameter="username"password-parameter="password" login-processing-url="/login2.do"default-target-url="/pages/main.html" authentication-failure-url="/login.html"always-use-default-target="true"/>
可以避免登陆后跳转未放行的404或304界面
2.状态码
200:成功
三开头是重定向
302:临时重定向(网站维护或更新、网站结构调整、负载均衡、SEO优化)
四开头得是前端错误
400:Bad Request 请求和服务器不匹配,参数类型不匹配
(请求的格式、语法或参数不符合服务器的要求)
401:没有http认证信息或者认证失败,
在HTTP协议中,401
表示未认证的,通常是没有成功登录的
(身份验证失败、需要身份验证、访问权限不足被拒绝)
403:服务器拒绝请求,可能没有权限,403
表示未授权的,
通常是已经登录,但是不具备相关的操作权限。
(验证通过但是权限不足、客户端问题)
404:找不到资源,资源路径有误(资源未找到、资源路径有误)
409:请求发生冲突(版本控制冲突、资源状态不匹配、并发请求冲突、权限问题)
五开头的是后端错误
500:内部服务器错误:这是服务器端的错误,与客户端的请求无关,
包括但不限于服务器程序错误、数据库问题、文件权限错误、服务器配置错误等。
502:网关错误,服务器作为网关或代理,从上游服务器收到无效响应
(上游服务器无响应或响应超时、网络问题、代理服务器配置错误、后端应用程序错误)
503:服务器目前无法使用(由于超载或停机维护)。通常是暂时状态。
(服务器超载、服务器维护)
504:网关超时