lifuquan hai 1 ano
pai
achega
01cc6d5833

+ 10 - 1
.gitignore

@@ -1,4 +1,13 @@
+# maven项目编译输出目录
 **/target/
 **/download/
+
+# vscode
+**/.vscode/
+
+# idea
+**.iml
+**/.idea/
+
 # office临时文件
-**/~$*
+**/~$*

+ 19 - 0
doc/开发文档/数据库文档/一些语句.sql

@@ -0,0 +1,19 @@
+-- 重复工单
+with t1 as (select compl_area_local,busi_no from report_auto.he_d_mobile_comp hdmc where month_id = substring('20230420' from 1 for 6) and day_id <= substring('20230420' from 7 for 2)),
+t2 as (select distinct * from t1),
+t3 as (select compl_area_local, count(1) as total_num from t1 group by compl_area_local),
+t4 as (select compl_area_local, count(1) as distinct_num from t2 group by compl_area_local),
+t5 as (select t3.compl_area_local, t3.total_num, t3.total_num - t4.distinct_num as repeat_num, (t3.total_num - t4.distinct_num)/t3.total_num::numeric  as repeat_ratio from T3, t4 where t3.compl_area_local = t4.compl_area_local)
+select '全省' as compl_area_local, sum(total_num) as total_num, sum(repeat_num) as repeat_num, sum(repeat_num) /sum(total_num)::numeric as repeat_ratio from t5
+union select * from t5
+
+-- 超时工单
+with t1 as (select compl_area_local, is_timeout from report_auto.he_d_mobile_comp hdmc where month_id = substring('20230420' from 1 for 6) and day_id <= substring('20230420' from 7 for 2)),
+t2 as (select '全省' as compl_area_local, count(1) as total_num from t1),
+t3 as (select compl_area_local, count(1) as total_num from t1 group by compl_area_local),
+t4 as (select * from t2 union select * from t3),
+t5 as (select compl_area_local from t1 where is_timeout = '是'),
+t7 as (select '全省' as compl_area_local, count(1) as timeout_num from t5),
+t8 as (select compl_area_local, count(1) as timeout_num from t5 group by compl_area_local),
+t9 as (select * from t7 union select * from t8)
+select t4.compl_area_local, t4.total_num, t9.timeout_num, t9.timeout_num/t4.total_num::numeric as timeout_ratio from t4,t9 where t4.compl_area_local = t9.compl_area_local order by t9.timeout_num/t4.total_num::numeric desc

+ 22 - 0
doc/开发文档/数据库文档/建表.sql

@@ -107,3 +107,25 @@ CREATE TABLE report_auto.he_d_mobile_comp (
   cteate_time timestamp NULL DEFAULT now(),
   CONSTRAINT he_d_mobile_comp_pkey PRIMARY KEY (id)
 )
+
+-- 用户数
+drop table if exists report_auto.user_count;
+CREATE TABLE report_auto.user_count (
+	id bigserial NOT NULL,
+  month_id varchar(6) NOT NULL,
+  city_name varchar(10) NOT NULL,
+  user_count varchar(10) NOT NULL,
+  cteate_time timestamp NULL DEFAULT now(),
+  CONSTRAINT user_count_pkey PRIMARY KEY (id)
+)
+
+-- 目标万投比
+drop table if exists report_auto.target_ts_ratio;
+CREATE TABLE report_auto.target_ts_ratio (
+	id bigserial NOT NULL,
+  month_id varchar(6) NOT NULL,
+  city_name varchar(10) NOT NULL,
+  target_ts_ratio varchar(10) NOT NULL,
+  cteate_time timestamp NULL DEFAULT now(),
+  CONSTRAINT target_ts_ratio_pkey PRIMARY KEY (id)
+)

BIN=BIN
doc/开发文档/样本数据/输入/1-12月投诉率明细(1).xlsx


BIN=BIN
doc/开发文档/样本数据/输出/投诉清单各地市投诉率0322(1).xlsx


BIN=BIN
doc/开发文档/样本数据/输出/投诉清单各地市投诉率0424(1).xlsx


+ 77 - 1
tsl_data/src/main/java/com/nokia/tsl_data/dao/TslDao.java

@@ -4,12 +4,88 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface TslDao {
 
+    List<Map<String, Object>> selectTimeoutTsDurationForDay(String day);
+
+    /**
+     * 超时工单统计
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectTimeoutTsCountForDay(String day);
+
+    /**
+     * 重复工单数和比例按截止日期和地市查询
+     * 
+     * @param day
+     * @return
+     */
+    List<Map<String, Object>> selectRepeatTsCountForDay(String day);
+
     /**
      * 投诉清单按日按地市计数
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectCityTslForMonth(String monthId);
+
+    /**
+     * 投诉清单全省计数
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectAllTslForMonth(String monthId);
+
+    /**
+     * 投诉清单地市总数
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectCityAllForMonth(String monthId);
+
+    /**
+     * 投诉清单按月计算总数
+     * 
+     * @param monthId
+     * @return
+     */
+    int selectAllForMonth(String monthId);
+
+    /**
+     * 查询用户数
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectUserCountForMonth(String monthId);
+
+    /**
+     * 查询期望万投率
+     * 
+     * @param monthId
+     * @return
+     */
+    List<Map<String, Object>> selectTargetTsRatioForMonth(String monthId);
+
+    /**
+     * 插入用户数
+     * 
+     * @param map
+     */
+    void insertUserCount(@Param("map") Map<String, Object> map);
+
+    /**
+     * 插入目标万投比
+     * 
+     * @param map
      */
-    List<Map<String, Object>> selectTslforMonth(String monthId);
+    void insertTargetTsRatio(@Param("map") Map<String, Object> map);
 }

+ 11 - 0
tsl_data/src/main/java/com/nokia/tsl_data/pojo/UserCount.java

@@ -0,0 +1,11 @@
+package com.nokia.tsl_data.pojo;
+
+import lombok.Data;
+
+@Data
+public class UserCount {
+
+    private Long id;
+    private String cityName;
+    private String userCount;
+}

+ 215 - 0
tsl_data/src/main/java/com/nokia/tsl_data/service/TslDataService.java

@@ -0,0 +1,215 @@
+package com.nokia.tsl_data.service;
+
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.springframework.stereotype.Service;
+
+import com.nokia.tsl_data.dao.TslDao;
+
+import lombok.Getter;
+
+/**
+ * 计算输出到文件的数据
+ */
+@Service
+public class TslDataService {
+
+    private final TslDao tslDao;
+
+    @Getter
+    private final List<String> areas = new ArrayList<String>() {
+        {
+            add("保定");
+            add("沧州");
+            add("承德");
+            add("邯郸");
+            add("衡水");
+            add("廊坊");
+            add("秦皇岛");
+            add("石家庄");
+            add("唐山");
+            add("邢台");
+            add("雄安");
+            add("张家口");
+        }
+    };
+
+    public TslDataService(TslDao tslDao) {
+        this.tslDao = tslDao;
+    }
+
+    /**
+     * 管理端-重复投诉率
+     * 
+     * @param day
+     * @return
+     */
+    public List<List<Object>> getSheet2Data(String day) {
+        // 从数据库
+        List<Map<String, Object>> dayData = tslDao.selectRepeatTsCountForDay(day);
+        List<Map<String, Object>> preDayData = dayData;
+        if (!day.endsWith("01")) {
+            String preDay = String.valueOf(Integer.parseInt(day) - 1);
+            preDayData = tslDao.selectRepeatTsCountForDay(preDay);
+        }
+        // 转化格式方便读取
+        Map<String, Map<String, Object>> dayMap = new HashMap<>();
+        Map<String, Map<String, Object>> preMap = new HashMap<>();
+        for (Map<String, Object> map : dayData) {
+            dayMap.put((String) map.get("compl_area_local"), map);
+        }
+        for (Map<String, Object> map : preDayData) {
+            preMap.put((String) map.get("compl_area_local"), map);
+        }
+        List<List<Object>> result = new ArrayList<>();
+        // 各地市数据
+        for (String area : areas) {
+            List<Object> list = new ArrayList<>(7);
+            result.add(list);
+            list.add(0, area);
+            // 重复投诉工单数
+            list.add(1, preMap.get(area).get("repeat_num"));
+            list.add(2, dayMap.get(area).get("repeat_num"));
+            // 重复投诉率
+            list.add(3, preMap.get(area).get("repeat_ratio"));
+            list.add(4, dayMap.get(area).get("repeat_ratio"));
+            // 增量
+            list.add(5, ((BigDecimal) list.get(2)).subtract((BigDecimal) list.get(1)));
+            list.add(6, ((BigDecimal) list.get(4)).subtract((BigDecimal) list.get(3)));
+        }
+        // 排序--逆序
+        result.sort((o1, o2) -> {
+            return ((BigDecimal) o2.get(6)).compareTo(((BigDecimal) o1.get(6)));
+        });
+        // 全省数据
+        List<Object> list = new ArrayList<>(7);
+        result.add(list);
+        list.add(0, "全省");
+        // 重复投诉工单数
+        list.add(1, preMap.get("全省").get("repeat_num"));
+        list.add(2, dayMap.get("全省").get("repeat_num"));
+        // 重复投诉率
+        list.add(3, preMap.get("全省").get("repeat_ratio"));
+        list.add(4, dayMap.get("全省").get("repeat_ratio"));
+        // 增量
+        list.add(5, ((BigDecimal) list.get(2)).subtract((BigDecimal) list.get(1)));
+        list.add(6, ((BigDecimal) list.get(4)).subtract((BigDecimal) list.get(3)));
+        return result;
+    }
+
+    /**
+     * 管理端-移网质量类
+     * 
+     * @param day
+     * @return
+     */
+    public Map<String, List<Object>> getSeet1Data(String day) {
+        // 获取当前月
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        int actualMaximumDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+        // monthId
+        String monthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
+
+        List<Map<String, Object>> cityTslforMonth = tslDao.selectCityTslForMonth(monthId);
+        List<Map<String, Object>> allTslforMonth = tslDao.selectAllTslForMonth(monthId);
+        List<Map<String, Object>> cityAllforMonth = tslDao.selectCityAllForMonth(monthId);
+        int total = tslDao.selectAllForMonth(monthId);
+        List<Map<String, Object>> userCount = getUserCount(monthId);
+        List<Map<String, Object>> targetTsRatio = tslDao.selectTargetTsRatioForMonth(monthId);
+
+        Map<String, List<Object>> result = new HashMap<>();
+        for (String area : areas) {
+            result.put(area, new ArrayList<>());
+        }
+        result.put("全省", new ArrayList<>());
+
+        // 各地市每日投诉量
+        for (Map<String, Object> map : cityTslforMonth) {
+            result.get(map.get("compl_area_local")).add(map.get("num"));
+        }
+        // 全省每日投诉量
+        for (Map<String, Object> map : allTslforMonth) {
+            result.get("全省").add(map.get("num"));
+        }
+        // 各地市投诉总量
+        for (Map<String, Object> map : cityAllforMonth) {
+            result.get(map.get("compl_area_local")).add(map.get("num"));
+        }
+        // 全省总量
+        result.get("全省").add(total);
+        // 用户数
+        for (Map<String, Object> map : userCount) {
+            result.get(map.get("city_name")).add(map.get("user_count"));
+        }
+
+        // 万投率和本月预测
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            // 计算万投率
+            double wtl = Double.parseDouble(list.get(size - 2).toString())
+                    / Double.parseDouble(list.get(size - 1).toString());
+            list.add(wtl);
+            // 计算预测万投率
+            double ycwtl = wtl * actualMaximumDayOfMonth / dayOfMonth;
+            list.add(ycwtl);
+        }
+
+        // 期望万投率--从数据库取出来是一个字符串
+        for (Map<String, Object> map : targetTsRatio) {
+            result.get(map.get("city_name")).add(Double.parseDouble(map.get("target_ts_ratio").toString()));
+        }
+
+        // 与目标差距
+        for (Entry<String, List<Object>> entry : result.entrySet()) {
+            List<Object> list = entry.getValue();
+            int size = list.size();
+            double cj = ((double) list.get(size - 2)) - ((double) list.get(size - 1));
+            list.add(cj);
+        }
+
+        return result;
+    }
+
+    /**
+     * 读取用户数如果当前月份没有数据就读上一个月
+     * 
+     * 递归方式,最多递归2层
+     * 
+     * @param monthId
+     * @return
+     */
+    public List<Map<String, Object>> getUserCount(String monthId) {
+        return getUserCount(monthId, 2);
+    }
+
+    private List<Map<String, Object>> getUserCount(String monthId, int stackLayerCount) {
+        List<Map<String, Object>> result = tslDao.selectUserCountForMonth(monthId);
+        if (stackLayerCount != 0) {
+            if (result == null || result.size() == 0) {
+                LocalDate localDate = LocalDate.parse(monthId + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
+                localDate = localDate.plusMonths(-1L);
+                String newMonthId = DateTimeFormatter.ofPattern("yyyyMM").format(localDate);
+                getUserCount(newMonthId);
+            }
+        }
+        return result;
+    }
+}

+ 0 - 11
tsl_data/src/main/java/com/nokia/tsl_data/service/TslReportGenerateService.java

@@ -1,11 +0,0 @@
-package com.nokia.tsl_data.service;
-
-import org.springframework.stereotype.Service;
-
-/**
- * 投诉报表数据生成
- */
-@Service
-public class TslReportGenerateService {
-
-}

+ 584 - 0
tsl_data/src/main/java/com/nokia/tsl_data/service/TslReportService.java

@@ -0,0 +1,584 @@
+package com.nokia.tsl_data.service;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.RegionUtil;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFColor;
+import org.apache.poi.xssf.usermodel.XSSFDataFormat;
+import org.apache.poi.xssf.usermodel.XSSFFont;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.stereotype.Service;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 投诉报表数据生成
+ */
+@Slf4j
+@Service
+public class TslReportService {
+
+    private final TslDataService tslDataService;
+
+    private XSSFWorkbook workbook = null;
+
+    // 等线 9号字 普通单元格 带边框
+    private XSSFCellStyle cellStyle1 = null;
+    // 等线 9号字 加粗 标题栏 带边框
+    private XSSFCellStyle cellStyle2 = null;
+    // 等线 9号字 带边框 小数 保留2位
+    private XSSFCellStyle cellStyle3 = null;
+
+    private static final DateFormat DAY_FORMAT = new SimpleDateFormat("yyyyMMdd");
+
+    public TslReportService(TslDataService tslDataService) {
+        this.tslDataService = tslDataService;
+    }
+
+    public void workbookToFile(String day, String path) {
+        getSheet1(day);
+        getSheet2(day);
+        getSheet3(day);
+        try (OutputStream outputStream = new FileOutputStream(path)) {
+            workbook.write(outputStream);
+            workbook.close();
+            workbook = null;
+        } catch (Exception e) {
+            log.info("写入失败。。。");
+        }
+    }
+
+    /**
+     * 投诉处理时长、超时工单概况
+     * 
+     * @param day
+     */
+    private void getSheet3(String day) {
+        // 计算时间常数
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(DAY_FORMAT.parse(day));
+        } catch (ParseException e) {
+            log.error("时间字符串解析失败--{}", day);
+        }
+        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+        int monthOfYear = calendar.get(Calendar.MONTH);
+        int preMonthOfYear = monthOfYear > 1 ? monthOfYear - 1 : 12;
+
+        Sheet sheet = getWorkbook().createSheet("投诉处理时长、超时工单概况");
+        Row row;
+        Cell cell;
+        CellRangeAddress rangeAddress;
+        XSSFDataFormat dataFormat = getWorkbook().createDataFormat();
+        XSSFFont font = getWorkbook().createFont();
+        font.setFontName("等线");
+        font.setFontHeightInPoints((short) 10);
+        // 基本模式 等线 10号字 带全边框 水平居中
+        XSSFCellStyle baseStyle = getWorkbook().createCellStyle();
+        baseStyle.setFont(font);
+        baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setBorderBottom(BorderStyle.THIN);
+        baseStyle.setBorderTop(BorderStyle.THIN);
+        baseStyle.setBorderLeft(BorderStyle.THIN);
+        baseStyle.setBorderRight(BorderStyle.THIN);
+        // 样式1 与base相同
+        XSSFCellStyle cellStyle1 = baseStyle.copy();
+        // 样式2 百分比 2位小数
+        XSSFCellStyle cellStyle2 = baseStyle.copy();
+        cellStyle2.setDataFormat(dataFormat.getFormat("0.00%"));
+        // 样式3 自动换行 背景色FFE7E6E6
+        XSSFCellStyle cellStyle3 = baseStyle.copy();
+        cellStyle3.setWrapText(true);
+        XSSFColor color = new XSSFColor();
+        color.setARGBHex("FFE7E6E6");
+        cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        cellStyle3.setFillForegroundColor(color);
+        // 样式4 小数 保留2位
+        XSSFCellStyle cellStyle4 = baseStyle.copy();
+        cellStyle4.setDataFormat(dataFormat.getFormat("0.00"));
+
+        // 第一行
+        row = sheet.createRow(0);
+        cell = row.createCell(0);
+        cell.setCellValue(String.format("超时工单情况(1-%s)", dayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 A1 - D1
+        rangeAddress = new CellRangeAddress(0, 0, 0, 3);
+        addMergedRegion(sheet, rangeAddress);
+        cell = row.createCell(6);
+        cell.setCellValue(String.format("平均处理时长(1-%s)", dayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 G1 - J1
+        rangeAddress = new CellRangeAddress(0, 0, 6, 9);
+        addMergedRegion(sheet, rangeAddress);
+
+        // 第二行
+        row = sheet.createRow(1);
+        cell = row.createCell(0);
+        cell.setCellValue("地市");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(1);
+        cell.setCellValue("工单数");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(2);
+        cell.setCellValue("超时工单数");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(3);
+        cell.setCellValue("超时工单占比");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(6);
+        cell.setCellValue("地市");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(7);
+        cell.setCellValue(String.format("%s月", preMonthOfYear));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(8);
+        cell.setCellValue(String.format("%s月", monthOfYear));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(9);
+        cell.setCellValue("涨幅");
+        cell.setCellStyle(cellStyle3);
+
+        // 设置列宽 2048 2276*3 2048*3 2276*2 3612
+        sheet.setColumnWidth(0, 2048);
+        sheet.setColumnWidth(1, 2276);
+        sheet.setColumnWidth(2, 2276);
+        sheet.setColumnWidth(3, 2276);
+        sheet.setColumnWidth(4, 2048);
+        sheet.setColumnWidth(5, 2048);
+        sheet.setColumnWidth(6, 2048);
+        sheet.setColumnWidth(7, 2276);
+        sheet.setColumnWidth(8, 2276);
+        sheet.setColumnWidth(9, 3612);
+
+        // 设置行高 14.25 25.5 14.25...
+        sheet.getRow(0).setHeightInPoints(14.25F);
+        sheet.getRow(1).setHeightInPoints(25.5F);
+        for (int i = 2; i < 15; i++) {
+            sheet.getRow(i).setHeightInPoints(14.25F);
+        }
+    }
+
+    /**
+     * 管理端-重复投诉率
+     * 
+     * @param day
+     */
+    private void getSheet2(String day) {
+        // 计算时间常数
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        try {
+            calendar.setTime(DAY_FORMAT.parse(day));
+        } catch (ParseException e) {
+            log.error("时间字符串解析失败--{}", day);
+        }
+        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+        int monthOfYear = calendar.get(Calendar.MONTH);
+        // 显示当前和前一天的对比
+        int preDayOfMonth = (dayOfMonth > 1) ? dayOfMonth - 1 : dayOfMonth;
+
+        Sheet sheet = getWorkbook().createSheet("管理端-重复投诉率");
+        Row row;
+        Cell cell;
+        CellRangeAddress rangeAddress;
+        XSSFFont font;
+        XSSFDataFormat dataFormat = getWorkbook().createDataFormat();
+        // 基本模式 等线 10号字 带全边框 水平居中
+        XSSFCellStyle baseStyle = getWorkbook().createCellStyle();
+        font = getWorkbook().createFont();
+        font.setFontName("等线");
+        font.setFontHeightInPoints((short) 10);
+        baseStyle.setFont(font);
+        baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setBorderBottom(BorderStyle.THIN);
+        baseStyle.setBorderTop(BorderStyle.THIN);
+        baseStyle.setBorderLeft(BorderStyle.THIN);
+        baseStyle.setBorderRight(BorderStyle.THIN);
+        // 基础模式
+        XSSFCellStyle cellStyle1 = baseStyle.copy();
+        // 带边框 百分比 2位小数
+        XSSFCellStyle cellStyle2 = baseStyle.copy();
+        cellStyle2.setDataFormat(dataFormat.getFormat("0.00%"));
+        // 等线 10号字 自动换行 背景色FFE7E6E6
+        XSSFCellStyle cellStyle3 = baseStyle.copy();
+        cellStyle3.setWrapText(true);
+        XSSFColor color = new XSSFColor();
+        color.setARGBHex("FFE7E6E6");
+        cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        cellStyle3.setFillForegroundColor(color);
+
+        // 第一行 标题栏
+        row = sheet.createRow(0);
+        cell = row.createCell(0);
+        cell.setCellValue(String.format("重复投诉率(1-%s)", dayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 A1 - G1
+        rangeAddress = new CellRangeAddress(0, 0, 0, 6);
+        addMergedRegion(sheet, rangeAddress);
+
+        // 第二行
+        row = sheet.createRow(1);
+        cell = row.createCell(0);
+        cell.setCellValue("");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(1);
+        cell.setCellValue("重复投诉工单数");
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 B2-C2
+        rangeAddress = new CellRangeAddress(1, 1, 1, 2);
+        addMergedRegion(sheet, rangeAddress);
+        cell = row.createCell(3);
+        cell.setCellValue("重复投诉率");
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 B2-C2
+        rangeAddress = new CellRangeAddress(1, 1, 3, 4);
+        addMergedRegion(sheet, rangeAddress);
+        cell = row.createCell(5);
+        cell.setCellValue("增量");
+        cell.setCellStyle(cellStyle3);
+        // 合并单元格 F2-G2
+        rangeAddress = new CellRangeAddress(1, 1, 5, 6);
+        addMergedRegion(sheet, rangeAddress);
+
+        // 第三行
+        row = sheet.createRow(2);
+        cell = row.createCell(0);
+        cell.setCellValue("地市");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(1);
+        cell.setCellValue(String.format("%s月截止%s日", monthOfYear, preDayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(2);
+        cell.setCellValue(String.format("%s月截止%s日", monthOfYear, dayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(3);
+        cell.setCellValue(String.format("%s月截止%s日", monthOfYear, preDayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(4);
+        cell.setCellValue(String.format("%s月截止%s日", monthOfYear, dayOfMonth));
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(5);
+        cell.setCellValue("重复投诉工单数");
+        cell.setCellStyle(cellStyle3);
+        cell = row.createCell(6);
+        cell.setCellValue("重复投诉率");
+        cell.setCellStyle(cellStyle3);
+
+        // 写入数据行
+        List<List<Object>> sheet2Data = tslDataService.getSheet2Data(day);
+        int rowNum = 3;
+        for (List<Object> list : sheet2Data) {
+            row = sheet.createRow(rowNum++);
+            cell = row.createCell(0);
+            // 地市
+            cell.setCellValue(list.get(0).toString());
+            cell.setCellStyle(cellStyle1);
+            // 前一天重复工单数
+            cell = row.createCell(1);
+            cell.setCellValue(((BigDecimal) list.get(1)).intValue());
+            cell.setCellStyle(cellStyle1);
+            // 当天重复工单数
+            cell = row.createCell(2);
+            cell.setCellValue(((BigDecimal) list.get(2)).intValue());
+            cell.setCellStyle(cellStyle1);
+            // 前一天重复投诉率
+            cell = row.createCell(3);
+            cell.setCellValue(((BigDecimal) list.get(3)).doubleValue());
+            cell.setCellStyle(cellStyle2);
+            // 当前重复投诉率
+            cell = row.createCell(4);
+            cell.setCellValue(((BigDecimal) list.get(4)).doubleValue());
+            cell.setCellStyle(cellStyle2);
+            // 重复工单增量
+            cell = row.createCell(5);
+            cell.setCellValue(((BigDecimal) list.get(5)).intValue());
+            cell.setCellStyle(cellStyle1);
+            // 重复投诉率增量
+            cell = row.createCell(6);
+            cell.setCellValue(((BigDecimal) list.get(6)).doubleValue());
+            cell.setCellStyle(cellStyle2);
+        }
+
+        // 添加条件格式F4-F15
+        rangeAddress = new CellRangeAddress(3, 14, 5, 5);
+        setConditionalFormatting(sheet, rangeAddress);
+        // 添加条件格式G4-G15
+        rangeAddress = new CellRangeAddress(3, 14, 6, 6);
+        setConditionalFormatting(sheet, rangeAddress);
+
+        // 设置列宽2048
+        for (int i = 0; i <= 6; i++) {
+            sheet.setColumnWidth(i, 2048);
+        }
+
+        // 设置行高 14.25 27.5 25.5 14.25 ...
+        sheet.getRow(0).setHeightInPoints(14.25F);
+        sheet.getRow(1).setHeightInPoints(27.5F);
+        sheet.getRow(2).setHeightInPoints(25.5F);
+        for (int i = 3; i < 16; i++) {
+            sheet.getRow(i).setHeightInPoints(14.25F);
+        }
+    }
+
+    /**
+     * 管理端-移网质量类
+     * 
+     * @param day
+     */
+    private void getSheet1(String day) {
+        Sheet sheet = getWorkbook().createSheet("管理端-移网质量类");
+
+        // 计算天数
+        LocalDate date = LocalDate.parse(day, DateTimeFormatter.ofPattern("yyyyMMdd"));
+        int dayOfMonth = date.getDayOfMonth();
+
+        Row row;
+        Cell cell;
+
+        // 第一行 标题栏
+        cell = sheet.createRow(0).createCell(0);
+        cell.setCellValue("2023年客服投诉清单各地市投诉率情况(管理端-移网质量类)");
+        cell.setCellStyle(getCellStyle2());
+        // 合并单元格
+        CellRangeAddress range = new CellRangeAddress(0, 0, 0, dayOfMonth + 7);
+        sheet.addMergedRegion(range);
+        // 设置合并单元格的边框
+        RegionUtil.setBorderBottom(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderTop(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderLeft(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderRight(BorderStyle.THIN, range, sheet);
+
+        // 第二行 列名
+        row = sheet.createRow(1);
+        cell = row.createCell(0);
+        cell.setCellValue("地市");
+        cell.setCellStyle(getCellStyle1());
+        for (int i = 1; i <= dayOfMonth; i++) {
+            cell = row.createCell(i);
+            cell.setCellValue(i + "日");
+            cell.setCellStyle(getCellStyle1());
+        }
+        cell = row.createCell(dayOfMonth + 1);
+        cell.setCellValue("投诉总量");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 2);
+        cell.setCellValue("用户数");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 3);
+        cell.setCellValue("目前万投率");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 4);
+        cell.setCellValue("本月预测");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 5);
+        cell.setCellValue("目标值");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 6);
+        cell.setCellValue("与目标差距");
+        cell.setCellStyle(getCellStyle1());
+        cell = row.createCell(dayOfMonth + 7);
+        cell.setCellValue("地市");
+        cell.setCellStyle(getCellStyle1());
+
+        // 获取数据
+        Map<String, List<Object>> seet1Data = tslDataService.getSeet1Data(day);
+
+        int rowNum = 2;
+        int cellNum = 0;
+        // 写入各地市数据
+        for (String area : tslDataService.getAreas()) {
+            row = sheet.createRow(rowNum++);
+            // 写入A列的地市
+            cell = row.createCell(cellNum++);
+            cell.setCellValue(area);
+            cell.setCellStyle(getCellStyle1());
+            for (Object obj : seet1Data.get(area)) {
+                cell = row.createCell(cellNum++);
+                cell.setCellValue(Double.parseDouble(obj.toString()));
+                cell.setCellStyle(getCellStyle1());
+            }
+            // 写入AC列的地市
+            cell = row.createCell(cellNum++);
+            cell.setCellValue(area);
+            cell.setCellStyle(getCellStyle1());
+            // cellNum复位
+            cellNum = 0;
+        }
+        // 写入全省数据
+        row = sheet.createRow(rowNum);
+        // 写入A列的地市
+        cell = row.createCell(cellNum++);
+        cell.setCellValue("全省");
+        cell.setCellStyle(getCellStyle1());
+        for (Object obj : seet1Data.get("全省")) {
+            cell = row.createCell(cellNum++);
+            cell.setCellValue(Double.parseDouble(obj.toString()));
+            cell.setCellStyle(getCellStyle1());
+        }
+        // 写入AC列的地市
+        cell = row.createCell(cellNum++);
+        cell.setCellValue("全省");
+        cell.setCellStyle(getCellStyle1());
+
+        // 3-15行(2-14)X列到AB列 (23-27)是浮点数,设置为显示小数点后2位
+        for (int i = 2; i <= 14; i++) {
+            row = sheet.getRow(i);
+            for (int j = 23; j <= 27; j++) {
+                cell = row.getCell(j);
+                cell.setCellStyle(getCellStyle3());
+            }
+        }
+
+        // 添加条件格式B15-V15
+        CellRangeAddress rangeAddress = new CellRangeAddress(rowNum, rowNum, 1, dayOfMonth);
+        setConditionalFormatting(sheet, rangeAddress);
+        // 添加条件格式Y3-Y14
+        rangeAddress = new CellRangeAddress(2, 13, 24, 24);
+        setConditionalFormatting(sheet, rangeAddress);
+        // 添加条件格式Z3-Z14
+        rangeAddress = new CellRangeAddress(2, 13, 25, 25);
+        setConditionalFormatting(sheet, rangeAddress);
+        // 添加条件格式AB3-AB14
+        rangeAddress = new CellRangeAddress(2, 13, 27, 27);
+        setConditionalFormatting(sheet, rangeAddress);
+
+        // 设置sheet的列宽 1409, 876, 876, ..., 876, 1792, 1665, 2177, 2844, 1409, 2177, 1409
+        sheet.setColumnWidth(0, 1409);
+        for (int i = 1; i <= dayOfMonth; i++) {
+            sheet.setColumnWidth(i, 876);
+        }
+        sheet.setColumnWidth(dayOfMonth + 1, 1792);
+        sheet.setColumnWidth(dayOfMonth + 2, 1665);
+        sheet.setColumnWidth(dayOfMonth + 3, 2177);
+        sheet.setColumnWidth(dayOfMonth + 4, 2844);
+        sheet.setColumnWidth(dayOfMonth + 5, 1409);
+        sheet.setColumnWidth(dayOfMonth + 6, 2177);
+        sheet.setColumnWidth(dayOfMonth + 7, 1409);
+
+        // 设置行高 12
+        for (int i = 0; i < rowNum; i++) {
+            sheet.getRow(i).setHeightInPoints(12F);
+        }
+    }
+
+    private XSSFWorkbook getWorkbook() {
+        if (workbook == null) {
+            workbook = new XSSFWorkbook();
+        }
+        return this.workbook;
+    }
+
+    private XSSFCellStyle getCellStyle1() {
+        if (cellStyle1 == null) {
+            cellStyle1 = getWorkbook().createCellStyle();
+            cellStyle1.setAlignment(HorizontalAlignment.CENTER);
+            XSSFFont font = getWorkbook().createFont();
+            font.setFontName("等线");
+            font.setBold(false);
+            font.setFontHeightInPoints((short) 9);
+            cellStyle1.setFont(font);
+            cellStyle1.setBorderBottom(BorderStyle.THIN);
+            cellStyle1.setBorderTop(BorderStyle.THIN);
+            cellStyle1.setBorderLeft(BorderStyle.THIN);
+            cellStyle1.setBorderRight(BorderStyle.THIN);
+        }
+        return this.cellStyle1;
+    }
+
+    private XSSFCellStyle getCellStyle2() {
+        if (cellStyle2 == null) {
+            cellStyle2 = getWorkbook().createCellStyle();
+            cellStyle2.setAlignment(HorizontalAlignment.CENTER);
+            XSSFFont font = getWorkbook().createFont();
+            font.setFontName("等线");
+            font.setBold(true);
+            font.setFontHeightInPoints((short) 9);
+            cellStyle2.setFont(font);
+            cellStyle2.setBorderBottom(BorderStyle.THIN);
+            cellStyle2.setBorderTop(BorderStyle.THIN);
+            cellStyle2.setBorderLeft(BorderStyle.THIN);
+            cellStyle2.setBorderRight(BorderStyle.THIN);
+        }
+        return this.cellStyle2;
+    }
+
+    private XSSFCellStyle getCellStyle3() {
+        if (cellStyle3 == null) {
+            cellStyle3 = getWorkbook().createCellStyle();
+            cellStyle3.setAlignment(HorizontalAlignment.CENTER);
+            XSSFFont font = getWorkbook().createFont();
+            font.setFontName("等线");
+            font.setBold(false);
+            font.setFontHeightInPoints((short) 9);
+            cellStyle3.setFont(font);
+            cellStyle3.setBorderBottom(BorderStyle.THIN);
+            cellStyle3.setBorderTop(BorderStyle.THIN);
+            cellStyle3.setBorderLeft(BorderStyle.THIN);
+            cellStyle3.setBorderRight(BorderStyle.THIN);
+            XSSFDataFormat format = getWorkbook().createDataFormat();
+            cellStyle3.setDataFormat(format.getFormat("0.00"));
+        }
+        return this.cellStyle3;
+    }
+
+    /**
+     * 添加合并单元格并添加边框
+     * 
+     * @param sheet
+     * @param range
+     */
+    private void addMergedRegion(Sheet sheet, CellRangeAddress range) {
+        sheet.addMergedRegion(range);
+        // 设置合并单元格的边框
+        RegionUtil.setBorderBottom(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderTop(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderLeft(BorderStyle.THIN, range, sheet);
+        RegionUtil.setBorderRight(BorderStyle.THIN, range, sheet);
+    }
+
+    /**
+     * 条件格式 3色渐变
+     * 绿 FF63BE7B 黄 FFFFEB84 红 FFF8696B
+     * 
+     * @return
+     */
+    private void setConditionalFormatting(Sheet sheet, CellRangeAddress rangeAddress) {
+        SheetConditionalFormatting conditionalFormatting = sheet.getSheetConditionalFormatting();
+        ConditionalFormattingRule rule = conditionalFormatting.createConditionalFormattingColorScaleRule();
+        XSSFColor[] colors = new XSSFColor[] {
+                new XSSFColor(), new XSSFColor(), new XSSFColor()
+        };
+        colors[0].setARGBHex("FF63BE7B");
+        colors[1].setARGBHex("FFFFEB84");
+        colors[2].setARGBHex("FFF8696B");
+
+        rule.getColorScaleFormatting().setColors(colors);
+
+        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[] {
+                rangeAddress
+        };
+
+        conditionalFormatting.addConditionalFormatting(cellRangeAddresses, rule);
+    }
+}

+ 52 - 3
tsl_data/src/main/resources/mapper/TslDao.xml

@@ -2,7 +2,56 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
 <mapper namespace="com.nokia.tsl_data.dao.TslDao">
-    <select id="selectTslforMonth" resultType="Map"> select compl_area_local, day_id, count(1) from
-        report_auto.he_d_mobile_comp hdmc where month_id = #{monthId} group by compl_area_local,
-        day_id order by day_id,compl_area_local </select>
+
+    <select id="selectTimeoutTsCountForDay" resultType="Map">with t1 as (select compl_area_local,
+        is_timeout from report_auto.he_d_mobile_comp hdmc where month_id = substring(#{day} from 1
+        for 6) and day_id &lt;= substring(#{day} from 7 for 2)), t2 as (select '全省' as
+        compl_area_local, count(1) as total_num from t1), t3 as (select compl_area_local, count(1)
+        as total_num from t1 group by compl_area_local), t4 as (select * from t2 union select * from
+        t3), t5 as (select compl_area_local from t1 where is_timeout = '是'), t7 as (select '全省' as
+        compl_area_local, count(1) as timeout_num from t5), t8 as (select compl_area_local, count(1)
+        as timeout_num from t5 group by compl_area_local), t9 as (select * from t7 union select *
+        from t8) select t4.compl_area_local, t4.total_num, t9.timeout_num, t9.timeout_num /
+        t4.total_num::numeric as timeout_ratio from t4,t9 where t4.compl_area_local =
+        t9.compl_area_local order by t9.timeout_num / t4.total_num::numeric desc</select>
+
+    <select id="selectRepeatTsCountForDay" resultType="Map"> with t1 as (select
+        compl_area_local,busi_no from report_auto.he_d_mobile_comp hdmc where month_id =
+        substring(#{day} from 1 for 6) and day_id &lt;= substring(#{day} from 7 for 2)), t2 as
+        (select distinct * from t1), t3 as (select compl_area_local, count(1) as total_num from t1
+        group by compl_area_local), t4 as (select compl_area_local, count(1) as distinct_num from t2
+        group by compl_area_local), t5 as (select t3.compl_area_local, t3.total_num, t3.total_num -
+        t4.distinct_num as repeat_num, (t3.total_num - t4.distinct_num)/t3.total_num::numeric as
+        repeat_ratio from T3, t4 where t3.compl_area_local = t4.compl_area_local) select '全省' as
+        compl_area_local, sum(total_num) as total_num, sum(repeat_num) as repeat_num,
+        sum(repeat_num) /sum(total_num)::numeric as repeat_ratio from t5 union select * from t5 </select>
+
+    <select id="selectCityTslForMonth" resultType="Map"> select compl_area_local, day_id, count(1)
+        as num from report_auto.he_d_mobile_comp hdmc where month_id = #{monthId} group by
+        compl_area_local, day_id order by compl_area_local,day_id </select>
+
+    <select id="selectAllTslForMonth" resultType="Map"> select day_id, count(1) as num from
+        report_auto.he_d_mobile_comp hdmc where month_id = #{monthId} group by day_id order by
+        day_id </select>
+
+    <select id="selectCityAllForMonth" resultType="Map">select compl_area_local, count(1) as num
+        from report_auto.he_d_mobile_comp hdmc where month_id = #{monthId} group by compl_area_local
+        order by compl_area_local </select>
+
+    <select id="selectAllForMonth" resultType="int">select count(1) as num from
+        report_auto.he_d_mobile_comp hdmc where month_id =#{monthId}</select>
+
+    <select id="selectUserCountForMonth" resultType="Map">select city_name, user_count from
+        report_auto.user_count where month_id = #{monthId}</select>
+
+    <select id="selectTargetTsRatioForMonth" resultType="Map">select city_name, target_ts_ratio from
+        report_auto.target_ts_ratio where month_id = #{monthId}</select>
+
+    <insert id="insertUserCount" parameterType="map"> INSERT INTO report_auto.user_count (month_id,
+        city_name, user_count) VALUES(#{map.monthId}, #{map.cityName}, #{map.userCount})</insert>
+
+    <insert id="insertTargetTsRatio" parameterType="map">INSERT INTO report_auto.target_ts_ratio
+        (month_id, city_name, target_ts_ratio) VALUES(#{map.monthId}, #{map.cityName},
+        #{map.targetTsRatio}); </insert>
+
 </mapper>

+ 13 - 130
tsl_data/src/test/java/com/nokia/tsl_data/TslDataApplicationTest.java

@@ -1,150 +1,33 @@
 package com.nokia.tsl_data;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.time.LocalDateTime;
-import org.apache.poi.ss.usermodel.BorderStyle;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.HorizontalAlignment;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.RegionUtil;
-import org.apache.poi.xssf.usermodel.XSSFCellStyle;
-import org.apache.poi.xssf.usermodel.XSSFFont;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import java.util.List;
+import java.util.Map;
+
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
 import com.nokia.tsl_data.dao.TslDao;
+import com.nokia.tsl_data.service.TslReportService;
 
 @SpringBootTest
 public class TslDataApplicationTest {
-    @Autowired
-    private TslDao tslDao;
 
-    @Test
-    void test1() {
-        LocalDateTime dateTime = LocalDateTime.now();
-        System.out.println(dateTime.getDayOfMonth());
-    }
+    @Autowired
+    private TslReportService tslReportService;
 
     @Test
     void test() throws IOException {
-        // List<Map<String, Object>> result = tslDao.selectTslforMonth("202304");
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        Sheet sheet = workbook.createSheet("管理端-移网质量类");
-        Row row;
-        Cell cell;
-
-        LocalDateTime dateTime = LocalDateTime.now();
-        int dayOfMonth = dateTime.getDayOfMonth();
-
-        cell = sheet.createRow(0).createCell(0);
-        cell.setCellValue("2023年客服投诉清单各地市投诉率情况(管理端-移网质量类)");
-        cell.setCellStyle(getStyle2(workbook));
-
-        CellRangeAddress range = new CellRangeAddress(0, 0, 0, dayOfMonth + 7);
-        sheet.addMergedRegion(range);
-
-        RegionUtil.setBorderBottom(BorderStyle.THIN, range, sheet);
-        RegionUtil.setBorderTop(BorderStyle.THIN, range, sheet);
-        RegionUtil.setBorderLeft(BorderStyle.THIN, range, sheet);
-        RegionUtil.setBorderRight(BorderStyle.THIN, range, sheet);
-
-        row = sheet.createRow(1);
-        cell = row.createCell(0);
-        cell.setCellValue("地市");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(0);
-
-        for (int i = 1; i <= dayOfMonth; i++) {
-            cell = row.createCell(i);
-            cell.setCellValue((i) + "日");
-            cell.setCellStyle(getStyle1(workbook));
-            sheet.autoSizeColumn(i);
-        }
-
-        cell = row.createCell(dayOfMonth + 1);
-        cell.setCellValue("投诉总量");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 1);
-
-        cell = row.createCell(dayOfMonth + 2);
-        cell.setCellValue("用户数");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 2);
-
-        cell = row.createCell(dayOfMonth + 3);
-        cell.setCellValue("目前万投率");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 3);
-
-        cell = row.createCell(dayOfMonth + 4);
-        cell.setCellValue("本月预测");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 4);
-
-        cell = row.createCell(dayOfMonth + 5);
-        cell.setCellValue("目标值");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 5);
-
-        cell = row.createCell(dayOfMonth + 6);
-        cell.setCellValue("与目标差距");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 6);
-
-        cell = row.createCell(dayOfMonth + 7);
-        cell.setCellValue("地市");
-        cell.setCellStyle(getStyle1(workbook));
-        sheet.autoSizeColumn(dayOfMonth + 7);
-
-        File file = new File("D:/src/test.xlsx");
-
-        FileOutputStream fout = new FileOutputStream(file);
-        workbook.write(fout);
-        fout.close();
-        workbook.close();
-    }
-
-    private XSSFFont getFont1(XSSFWorkbook workbook) {
-        XSSFFont font = workbook.createFont();
-        font.setFontName("等线");
-        font.setFontHeightInPoints((short) 9);
-        return font;
+        tslReportService.workbookToFile("20230421", "D:/src/cccccc.xlsx");
     }
 
-    private CellStyle getStyle1(XSSFWorkbook workbook) {
-        XSSFCellStyle cellStyle = workbook.createCellStyle();
-        cellStyle.setAlignment(HorizontalAlignment.CENTER);
-        cellStyle.setFont(getFont1(workbook));
-        cellStyle.setBorderBottom(BorderStyle.THIN);
-        cellStyle.setBorderTop(BorderStyle.THIN);
-        cellStyle.setBorderLeft(BorderStyle.THIN);
-        cellStyle.setBorderRight(BorderStyle.THIN);
-        return cellStyle;
-    }
-
-    private XSSFFont getFont2(XSSFWorkbook workbook) {
-        XSSFFont font = workbook.createFont();
-        font.setFontName("等线");
-        font.setBold(true);
-        font.setFontHeightInPoints((short) 9);
-        return font;
-    }
+    @Autowired
+    private TslDao tslDao;
 
-    private CellStyle getStyle2(XSSFWorkbook workbook) {
-        XSSFCellStyle cellStyle = workbook.createCellStyle();
-        cellStyle.setAlignment(HorizontalAlignment.CENTER);
-        cellStyle.setFont(getFont2(workbook));
-        cellStyle.setBorderBottom(BorderStyle.THIN);
-        cellStyle.setBorderTop(BorderStyle.THIN);
-        cellStyle.setBorderLeft(BorderStyle.THIN);
-        cellStyle.setBorderRight(BorderStyle.THIN);
-        return cellStyle;
+    @Test
+    void test1() {
+        List<Map<String, Object>> selectTimeoutTsCountForDay = tslDao.selectTimeoutTsCountForDay("20230420");
+        System.out.println(selectTimeoutTsCountForDay);
     }
 }