package com.nokia.tsl_data.service;

import java.io.FileOutputStream;
import java.io.OutputStream;
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.usermodel.VerticalAlignment;
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;

    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);
        getSheet4_6(day);
        try (OutputStream outputStream = new FileOutputStream(path)) {
            workbook.write(outputStream);
            workbook.close();
            workbook = null;
        } catch (Exception e) {
            log.error("写入失败。。。");
        }
    }

    /**
     * 客户端-投诉问题解决满意度
     * 客户端-投诉问题解决率
     * 客户端-投诉问题响应率
     * 
     * @param day
     */
    private void getSheet4_6(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);
        Sheet sheet4 = getWorkbook().createSheet("客户端-投诉问题解决满意度");
        Sheet sheet5 = getWorkbook().createSheet("客户端-投诉问题解决率");
        Sheet sheet6 = 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.setVerticalAlignment(VerticalAlignment.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 FFAEAAAA
        XSSFCellStyle cellStyle3 = baseStyle.copy();
        // cellStyle3.setWrapText(true);
        XSSFColor color = new XSSFColor();
        color.setARGBHex("FFAEAAAA");
        cellStyle3.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle3.setFillForegroundColor(color);

        List<List<List<Object>>> sheet4_6Data = tslDataService.getSheet4_6Data(day);

        // 客户端-投诉问题解决满意度 第一行
        row = sheet4.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(sheet4, rangeAddress);
        // 客户端-投诉问题解决满意度 第二行
        row = sheet4.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);
        int rowNum = 2;
        for (List<Object> list : sheet4_6Data.get(0)) {
            row = sheet4.createRow(rowNum++);
            // 地市
            cell = row.createCell(0);
            cell.setCellValue(list.get(0).toString());
            cell.setCellStyle(cellStyle1);
            // 投诉问题解决满意率
            cell = row.createCell(1);
            cell.setCellValue(((double) list.get(1)));
            cell.setCellStyle(cellStyle2);
            // 达标值
            cell = row.createCell(2);
            cell.setCellValue((double) list.get(2));
            cell.setCellStyle(cellStyle2);
            // 与达标值差距
            cell = row.createCell(3);
            cell.setCellValue(((double) list.get(3)));
            cell.setCellStyle(cellStyle2);
        }
        // 设置条件格式D3-D14
        rangeAddress = new CellRangeAddress(2, 13, 3, 3);
        setConditionalFormatting2(sheet4, rangeAddress);

        // 设置列宽 2048 1304 2048 2304
        for (int i = 0; i < 4; i++) {
            sheet4.setColumnWidth(i, 2848);
        }
        // sheet4.setColumnWidth(0, 2048);
        // sheet4.setColumnWidth(1, 2304);
        // sheet4.setColumnWidth(2, 2048);
        // sheet4.setColumnWidth(3, 2804);

        // 设置行高 15.0 15.0...
        for (int i = 0; i < 15; i++) {
            sheet4.getRow(i).setHeightInPoints(15.0F);
        }

        // 客户端-投诉问题解决率
        row = sheet5.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(sheet5, rangeAddress);
        // 客户端-投诉问题解决率 第二行
        row = sheet5.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);
        rowNum = 2;
        for (List<Object> list : sheet4_6Data.get(1)) {
            row = sheet5.createRow(rowNum++);
            // 地市
            cell = row.createCell(0);
            cell.setCellValue(list.get(0).toString());
            cell.setCellStyle(cellStyle1);
            // 投诉问题解决率
            cell = row.createCell(1);
            cell.setCellValue(((double) list.get(1)));
            cell.setCellStyle(cellStyle2);
            // 达标值
            cell = row.createCell(2);
            cell.setCellValue((double) list.get(2));
            cell.setCellStyle(cellStyle2);
            // 与达标值差距
            cell = row.createCell(3);
            cell.setCellValue(((double) list.get(3)));
            cell.setCellStyle(cellStyle2);
        }
        // 设置条件格式D3-D14
        rangeAddress = new CellRangeAddress(2, 13, 3, 3);
        setConditionalFormatting2(sheet5, rangeAddress);

        // 设置列宽 2048 1304 2048 2304
        for (int i = 0; i < 4; i++) {
            sheet5.setColumnWidth(i, 2848);
        }
        // sheet5.setColumnWidth(0, 2048);
        // sheet5.setColumnWidth(1, 2304);
        // sheet5.setColumnWidth(2, 2048);
        // sheet5.setColumnWidth(3, 2804);

        // 设置行高 15.0 15.0...
        for (int i = 0; i < 15; i++) {
            sheet5.getRow(i).setHeightInPoints(15.0F);
        }

        // 客户端-投诉问题响应率
        row = sheet6.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(sheet6, rangeAddress);
        // 客户端-投诉问题响应率 第二行
        row = sheet6.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);
        rowNum = 2;
        for (List<Object> list : sheet4_6Data.get(2)) {
            row = sheet6.createRow(rowNum++);
            // 地市
            cell = row.createCell(0);
            cell.setCellValue(list.get(0).toString());
            cell.setCellStyle(cellStyle1);
            // 投诉问题解决率
            cell = row.createCell(1);
            cell.setCellValue(((double) list.get(1)));
            cell.setCellStyle(cellStyle2);
            // 达标值
            cell = row.createCell(2);
            cell.setCellValue((double) list.get(2));
            cell.setCellStyle(cellStyle2);
            // 与达标值差距
            cell = row.createCell(3);
            cell.setCellValue(((double) list.get(3)));
            cell.setCellStyle(cellStyle2);
        }
        // 设置条件格式D3-D14
        rangeAddress = new CellRangeAddress(2, 13, 3, 3);
        setConditionalFormatting2(sheet6, rangeAddress);

        // 设置列宽 2048 1304 2048 2304
        for (int i = 0; i < 4; i++) {
            sheet6.setColumnWidth(i, 2848);
        }
        // sheet6.setColumnWidth(0, 2048);
        // sheet6.setColumnWidth(1, 2304);
        // sheet6.setColumnWidth(2, 2048);
        // sheet6.setColumnWidth(3, 2848);

        // 设置行高 15.0 15.0...
        for (int i = 0; i < 15; i++) {
            sheet6.getRow(i).setHeightInPoints(15.0F);
        }
    }

    /**
     * 投诉处理时长、超时工单概况
     * 
     * @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);
        // 修正，MONTH是从0开始
        int monthOfYear = calendar.get(Calendar.MONTH) + 1;
        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.setVerticalAlignment(VerticalAlignment.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 FFAEAAAA
        XSSFCellStyle cellStyle3 = baseStyle.copy();
        // cellStyle3.setWrapText(true);
        XSSFColor color = new XSSFColor();
        color.setARGBHex("FFAEAAAA");
        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);

        // 写入超时工单情况
        List<List<Object>> sheet3Data1 = tslDataService.getSheet3Data1(day);
        int rowNum = 2;
        for (List<Object> list : sheet3Data1) {
            row = sheet.createRow(rowNum++);
            // 地市
            cell = row.createCell(0);
            cell.setCellValue(list.get(0).toString());
            cell.setCellStyle(cellStyle1);
            // 工单数
            cell = row.createCell(1);
            cell.setCellValue((long) list.get(1));
            cell.setCellStyle(cellStyle1);
            // 超时工单数
            cell = row.createCell(2);
            cell.setCellValue((long) list.get(2));
            cell.setCellStyle(cellStyle1);
            // 超时工单占比
            cell = row.createCell(3);
            cell.setCellValue(((double) list.get(3)));
            cell.setCellStyle(cellStyle2);
        }
        // 设置条件格式D3-D14
        rangeAddress = new CellRangeAddress(2, 13, 3, 3);
        setConditionalFormatting(sheet, rangeAddress);

        // 写入平均处理时长
        List<List<Object>> sheet3Data2 = tslDataService.getSheet3Data2(day);
        rowNum = 2;
        for (List<Object> list : sheet3Data2) {
            row = sheet.getRow(rowNum++);
            // 地市
            cell = row.createCell(6);
            cell.setCellValue(list.get(0).toString());
            cell.setCellStyle(cellStyle1);
            // 上月
            cell = row.createCell(7);
            cell.setCellValue((double) list.get(1));
            cell.setCellStyle(cellStyle4);
            // 当月
            cell = row.createCell(8);
            cell.setCellValue((double) list.get(2));
            cell.setCellStyle(cellStyle4);
            // 涨幅
            cell = row.createCell(9);
            cell.setCellValue((double) list.get(3));
            cell.setCellStyle(cellStyle4);
        }
        // 设置条件格式J3-J14
        rangeAddress = new CellRangeAddress(2, 13, 9, 9);
        setConditionalFormatting(sheet, rangeAddress);

        // 设置列宽 2048 2276*3 2048*3 2276*2 3612
        for (int i = 0; i < 10; i++) {
            sheet.setColumnWidth(i, 2848);
        }
        // sheet.setColumnWidth(0, 2848);
        // 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...
        for (int i = 0; i < 15; i++) {
            sheet.getRow(i).setHeightInPoints(15.0F);
        }
    }

    /**
     * 管理端-重复投诉率
     * 
     * @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) + 1;
        // 显示当前和前一天的对比
        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.setVerticalAlignment(VerticalAlignment.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 FFAEAAAA
        XSSFCellStyle cellStyle3 = baseStyle.copy();
        // cellStyle3.setWrapText(true);
        XSSFColor color = new XSSFColor();
        color.setARGBHex("FFAEAAAA");
        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(((double) list.get(1)));
            cell.setCellStyle(cellStyle1);
            // 当天重复工单数
            cell = row.createCell(2);
            cell.setCellValue(((double) list.get(2)));
            cell.setCellStyle(cellStyle1);
            // 前一天重复投诉率
            cell = row.createCell(3);
            cell.setCellValue(((double) list.get(3)));
            cell.setCellStyle(cellStyle2);
            // 当前重复投诉率
            cell = row.createCell(4);
            cell.setCellValue(((double) list.get(4)));
            cell.setCellStyle(cellStyle2);
            // 重复工单增量
            cell = row.createCell(5);
            cell.setCellValue(((double) list.get(5)));
            cell.setCellStyle(cellStyle1);
            // 重复投诉率增量
            cell = row.createCell(6);
            cell.setCellValue(((double) list.get(6)));
            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, 2848);
        }

        // 设置行高 15.0 ...
        for (int i = 0; i < 16; i++) {
            sheet.getRow(i).setHeightInPoints(15.0F);
        }
    }

    /**
     * 管理端-移网质量类
     * 
     * @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;

        XSSFCellStyle cellStyle1 = getWorkbook().createCellStyle();
        cellStyle1.setAlignment(HorizontalAlignment.CENTER);
        cellStyle1.setVerticalAlignment(VerticalAlignment.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);
        XSSFCellStyle cellStyle3 = getWorkbook().createCellStyle();
        cellStyle3.setAlignment(HorizontalAlignment.CENTER);
        cellStyle3.setVerticalAlignment(VerticalAlignment.CENTER);
        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"));
        XSSFCellStyle cellStyle2 = getWorkbook().createCellStyle();
        cellStyle2.setAlignment(HorizontalAlignment.CENTER);
        cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
        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);

        // 第一行 标题栏
        cell = sheet.createRow(0).createCell(0);
        cell.setCellValue("2023年客服投诉清单各地市投诉率情况（管理端-移网质量类）");
        cell.setCellStyle(cellStyle2);
        // 合并单元格
        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(cellStyle1);
        for (int i = 1; i <= dayOfMonth; i++) {
            cell = row.createCell(i);
            cell.setCellValue(i + "日");
            cell.setCellStyle(cellStyle1);
        }
        cell = row.createCell(dayOfMonth + 1);
        cell.setCellValue("投诉总量");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 2);
        cell.setCellValue("用户数");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 3);
        cell.setCellValue("目前万投率");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 4);
        cell.setCellValue("本月预测");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 5);
        cell.setCellValue("目标值");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 6);
        cell.setCellValue("与目标差距");
        cell.setCellStyle(cellStyle1);
        cell = row.createCell(dayOfMonth + 7);
        cell.setCellValue("地市");
        cell.setCellStyle(cellStyle1);

        // 获取数据
        Map<String, List<Object>> seet1Data = tslDataService.getSheet1Data(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(cellStyle1);
            for (Object obj : seet1Data.get(area)) {
                cell = row.createCell(cellNum++);
                cell.setCellValue(Double.parseDouble(obj.toString()));
                cell.setCellStyle(cellStyle1);
            }
            // 写入最后一列的地市
            cell = row.createCell(cellNum++);
            cell.setCellValue(area);
            cell.setCellStyle(cellStyle1);
            // cellNum复位
            cellNum = 0;
        }
        // 写入全省数据
        row = sheet.createRow(rowNum);
        // 写入A列的地市
        cell = row.createCell(cellNum++);
        cell.setCellValue("全省");
        cell.setCellStyle(cellStyle1);
        for (Object obj : seet1Data.get("全省")) {
            cell = row.createCell(cellNum++);
            cell.setCellValue(Double.parseDouble(obj.toString()));
            cell.setCellStyle(cellStyle1);
        }
        // 写入最后一列的地市
        cell = row.createCell(cellNum++);
        cell.setCellValue("全省");
        cell.setCellStyle(cellStyle1);

        // 3-15行（2-14）dayOfMonth+2 - dayofMonth+6是浮点数，设置为显示小数点后2位
        for (int i = 2; i <= 14; i++) {
            row = sheet.getRow(i);
            for (int j = dayOfMonth + 2; j <= dayOfMonth + 6; j++) {
                cell = row.getCell(j);
                cell.setCellStyle(cellStyle3);
            }
        }

        // 添加条件格式B15-V15
        CellRangeAddress rangeAddress = new CellRangeAddress(rowNum, rowNum, 1, dayOfMonth);
        setConditionalFormatting(sheet, rangeAddress);
        // 添加条件格式(dayOfMonth+3)(3-14)
        rangeAddress = new CellRangeAddress(2, 13, dayOfMonth + 3, dayOfMonth + 3);
        setConditionalFormatting(sheet, rangeAddress);
        // 添加条件格式Z3-Z14
        rangeAddress = new CellRangeAddress(2, 13, dayOfMonth + 4, dayOfMonth + 4);
        setConditionalFormatting(sheet, rangeAddress);
        // 添加条件格式AB3-AB14
        rangeAddress = new CellRangeAddress(2, 13, dayOfMonth + 6, dayOfMonth + 6);
        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;
    }

    /**
     * 添加合并单元格并添加边框
     * 
     * @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);
    }

    /**
     * 条件格式 3色渐变
     * 绿 FF63BE7B 黄 FFFFEB84 红 FFF8696B
     * 
     * @return
     */
    private void setConditionalFormatting2(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("FFF8696B");
        colors[1].setARGBHex("FFFFEB84");
        colors[2].setARGBHex("FF63BE7B");

        rule.getColorScaleFormatting().setColors(colors);

        CellRangeAddress[] cellRangeAddresses = new CellRangeAddress[] {
                rangeAddress
        };

        conditionalFormatting.addConditionalFormatting(cellRangeAddresses, rule);
    }
}
