package com.bonus.hn.bearing.capacity.backstage.newpro.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bonus.hn.bearing.capacity.backstage.manager.utils.DateTimeHelper;
import com.bonus.hn.bearing.capacity.backstage.manager.utils.ExcelUtils;
import com.bonus.hn.bearing.capacity.backstage.manager.utils.StringHelper;
import com.bonus.hn.bearing.capacity.backstage.manager.utils.UserUtil;
import com.bonus.hn.bearing.capacity.backstage.newpro.dao.NewProDao;
import com.bonus.hn.bearing.capacity.backstage.newpro.entity.HistoryProBean;
import com.bonus.hn.bearing.capacity.backstage.newpro.entity.NewProBean;
import com.bonus.hn.bearing.capacity.backstage.newpro.entity.ReleaseBean;
import com.bonus.hn.bearing.capacity.backstage.newpro.entity.ReleaseViewBean;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.lang.System.*;
/**
 * @author bonus
 */
@Service("NewProService")
public class NewProServiceImpl implements NewProService {
    @Resource
    private NewProDao dao;

    @Override
    public List<NewProBean> getBasicDataList(NewProBean o) {
        o.setLevel(UserUtil.getLoginUser().getLevel());
        o.setOrgIds(UserUtil.getLoginUser().getOrgId());
        return dao.getBasicDataList(o);
    }

    @Override
    public int addInfo(NewProBean bean) {
        int num = dao.determineIfExists(bean.getProName(), "");
        if (num > 0) {
            return 3;
        } else {
            num = dao.insertData(bean);
        }
        return num;
    }

    @Override
    public NewProBean getListById(NewProBean o) {
        return dao.getListById(o);
    }

    @Override
    public int updateInfo(NewProBean bean) {
        int num = dao.determineIfExists(bean.getProName(), bean.getId());
        if (num > 0) {
            return 3;
        } else {
            num = dao.updateData(bean);
        }
        return num;
    }

    @Override
    public int delById(NewProBean bean) {
        return dao.delById(bean);
    }

    @Override
    public List<ReleaseBean> getReleaseDataList(ReleaseBean o) {
        o.setCurrentDay(DateTimeHelper.getNowDate());
        o.setLevel(UserUtil.getLoginUser().getLevel());
        o.setOrgIds(UserUtil.getLoginUser().getOrgId());
        return dao.getReleaseDataList(o);
    }

    @Override
    public List<ReleaseViewBean> getTeamTable(ReleaseViewBean o) {
        return dao.getTeamTable(o);
    }

    @Override
    public List<ReleaseViewBean> getSubTeamTable(ReleaseViewBean o) {
        return dao.getSubTeamTable(o);
    }

    @Override
    public List<ReleaseViewBean> getOwnTeamTable(ReleaseViewBean o) {
        return dao.getOwnTeamTable(o);
    }

    @Override
    public List<HistoryProBean> getHistoryProList(HistoryProBean o) {
        o.setLevel(UserUtil.getLoginUser().getLevel());
        o.setOrgIds(UserUtil.getLoginUser().getOrgId());
        return dao.getHistoryProList(o);
    }

    @Override
    public NewProBean getHistoryListById(NewProBean o) throws ParseException {
        //获取基本信息
        NewProBean bean = dao.getHisotryListById(o);
        //查询每个月基础,组塔,架线班组数量
        //开工-竣工总月份分为每一个月
        List<String> uniqueList = DateTimeHelper.getAllMonth(bean.getStartTime().substring(0, 7), bean.getEndTime().substring(0, 7));
        Map<String, Object>[] basicArr = new HashMap[uniqueList.size()];
        Map<String, Object>[] towerArr = new HashMap[uniqueList.size()];
        Map<String, Object>[] lineArr = new HashMap[uniqueList.size()];
        //对每个月的基础，组塔，架线进行赋值，作为根数据
        for (int i = 0; i < uniqueList.size(); i++) {
            Map<String, Object> map1 = new HashMap<>(100);
            Map<String, Object> map2 = new HashMap<>(100);
            Map<String, Object> map3 = new HashMap<>(100);
            map1.put("jc", 0);
            map2.put("zt", 0);
            map3.put("jx", 0);
            basicArr[i] = map1;
            towerArr[i] = map2;
            lineArr[i] = map3;
        }
        //获取此工程所有分包班组及绑定-解绑时间
        List<NewProBean> list = dao.getEveryMonthNum(o.getId());
        //获取此工程所有自有班组及绑定-解绑时间
        List<NewProBean> ownTimeList = dao.getOwnTeamEveryMonthNum(o.getId());
        //查询此工程下所有的分包班组id
        List<String> teamIdList = dao.getTeamIdList(o.getId());
        //查询此工程下所有的自有班组id
        List<String> ownTeamIdList = dao.getOwnTeamIdList(o.getId());
        //循环获取分包班组中基础,组塔,架线每个月的班组个数
        for (int i = 0; i < list.size(); i++) {
            for (String item : teamIdList) {
                if (list.get(i).getSubTeamId().equals(item)) {
                    List<String> oneTeamTimeList = new ArrayList<>();
                    //根据是否有解绑时间判定最后的时间维度
                    if (StringHelper.isEmpty(list.get(i).getUnBindTime())) {
                        oneTeamTimeList = DateTimeHelper.getAllMonth(list.get(i).getBindTime().substring(0, 7), DateTimeHelper.getNowDate().substring(0, 7));
                    } else {
                        oneTeamTimeList = DateTimeHelper.getAllMonth(list.get(i).getBindTime().substring(0, 7), list.get(i).getUnBindTime().substring(0, 7));
                    }
                    //取第二组数据之后的每一组与前一组对比(条件:两组之间的班组id相同,第二组的绑定时间和第一组的解绑时间相同) 则 删除第二组时间组中的第一个时间
                    if (i > 0 && list.get(i).getSubTeamId().equals(list.get(i - 1).getSubTeamId()) && !StringHelper.isEmpty(list.get(i - 1).getUnBindTime()) && list.get(i).getBindTime().substring(0, 7).equals(list.get(i - 1).getUnBindTime().substring(0, 7))) {
                        // 删除第一个元素
                        oneTeamTimeList.remove(0);
                    }
                    for (String s : oneTeamTimeList) {
                        for (int l = 0; l < uniqueList.size(); l++) {
                            if (s.substring(0, 7).equals(uniqueList.get(l))) {
                                Map<String, Object> map = new HashMap<>(100);
                                if ("1".equals(list.get(i).getType())) {
                                    Map<String, Object> thisMap = basicArr[l];
                                    int value = (int) thisMap.get("jc");
                                    value++;
                                    map.put("jc", value);
                                    basicArr[l] = map;
                                } else if ("2".equals(list.get(i).getType())) {
                                    Map<String, Object> thisMap = towerArr[l];
                                    int value = (int) thisMap.get("zt");
                                    value++;
                                    map.put("zt", value);
                                    towerArr[l] = map;
                                } else if ("3".equals(list.get(i).getType())) {
                                    Map<String, Object> thisMap = lineArr[l];
                                    int value = (int) thisMap.get("jx");
                                    value++;
                                    map.put("jx", value);
                                    lineArr[l] = map;
                                }
                            }
                        }
                    }
                }
            }
        }
        //循环获取自有班组中基础,组塔,架线每个月的班组个数
        for (int i = 0; i < ownTimeList.size(); i++) {
            for (String item : ownTeamIdList) {
                if (ownTimeList.get(i).getOwnTeamId().equals(item)) {
                    List<String> oneTeamTimeList = new ArrayList<>();
                    if (StringHelper.isEmpty(ownTimeList.get(i).getUnBindTime())) {
                        oneTeamTimeList = DateTimeHelper.getAllMonth(ownTimeList.get(i).getBindTime().substring(0, 7), DateTimeHelper.getNowDate().substring(0, 7));
                    } else {
                        oneTeamTimeList = DateTimeHelper.getAllMonth(ownTimeList.get(i).getBindTime().substring(0, 7), ownTimeList.get(i).getUnBindTime().substring(0, 7));
                    }
                    if (i > 0 && ownTimeList.get(i).getOwnTeamId().equals(ownTimeList.get(i - 1).getOwnTeamId()) && !StringHelper.isEmpty(ownTimeList.get(i - 1).getUnBindTime()) && ownTimeList.get(i).getBindTime().substring(0, 7).equals(ownTimeList.get(i - 1).getUnBindTime().substring(0, 7))) {
                        // 删除第一个元素
                        oneTeamTimeList.remove(0);
                    }
                    for (String s : oneTeamTimeList) {
                        for (int l = 0; l < uniqueList.size(); l++) {
                            if (s.substring(0, 7).equals(uniqueList.get(l))) {
                                Map<String, Object> map = new HashMap<>(100);
                                if ("1".equals(ownTimeList.get(i).getType())) {
                                    Map<String, Object> thisMap = basicArr[l];
                                    int value = (int) thisMap.get("jc");
                                    value++;
                                    map.put("jc", value);
                                    basicArr[l] = map;
                                } else if ("2".equals(ownTimeList.get(i).getType())) {
                                    Map<String, Object> thisMap = towerArr[l];
                                    int value = (int) thisMap.get("zt");
                                    value++;
                                    map.put("zt", value);
                                    towerArr[l] = map;
                                } else if ("3".equals(ownTimeList.get(i).getType())) {
                                    Map<String, Object> thisMap = lineArr[l];
                                    int value = (int) thisMap.get("jx");
                                    value++;
                                    map.put("jx", value);
                                    lineArr[l] = map;
                                }
                            }
                        }
                    }
                }
            }
        }
        Map<String, Object[]> map = new HashMap<>(100);
        map.put("jcObj", basicArr);
        map.put("ztObj", towerArr);
        map.put("jxObj", lineArr);
        String resParams = JSONArray.toJSON(map).toString();
        out.println(resParams);
        bean.setJsonData(resParams);
        return bean;
    }

    /**
     * list  去重
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<T> removeDuplicates(List<T> list) {
        Set<T> set = new HashSet<>(list);
        return new ArrayList<>(set);
    }

    /**
     * 导出数据
     *
     * @param o
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public int export(NewProBean o, HttpServletResponse response, HttpServletRequest request) throws JsonProcessingException {
        int resCodes = 1;
        try {
            /**---------------------------------------获取导出表格中的部分基础数据-------------------------------------------------------*/
            //查询符合条件的工程中-工程开始最早日期和工程结束最晚时间
            o.setLevel(UserUtil.getLoginUser().getLevel());
            o.setOrgIds(UserUtil.getLoginUser().getOrgId());
            NewProBean timeBean = dao.getMinAndMaxTimeBeans(o);
            //根据开始-结束时间 获取时间list(格式年-月)
            List<String> timeList = DateTimeHelper.getAllMonth(timeBean.getStartTime().substring(0, 7), timeBean.getEndTime().substring(0, 7));
            //月份所需要的表格列数量
            int monthColumn = timeList.size();
            //统计年份包含的所有月份个数
            Map<String, Long> countMap = timeList.stream()
                    .map(time -> time.split("-")[0])
                    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            //开始-结束时间包含的所有年份
            List<String> yearList = timeList.stream()
                    .map(time -> time.split("-")[0])
                    .distinct()
                    .collect(Collectors.toList());
            //开始-结束时间包含的所有月份
            List<String> monthList = timeList.stream()
                    .map(time -> time.split("-")[1])
                    .collect(Collectors.toList());

            /**----------------------------------------开始组建  导出表格的标题-------------------------------------------------------*/

            // 第一步，创建一个Workbook，对应一个Excel文件
            XSSFWorkbook wb = new XSSFWorkbook();
            // 第二步，在Workbook中添加一个sheet,对应Excel文件中的sheet
            XSSFSheet sheet = wb.createSheet("预安排工程信息清单");
            // 第三步，设置样式以及字体样式
            XSSFCellStyle titleStyle = createTitleCellStyle(wb);
            XSSFCellStyle headerStyle = createHeadCellStyle(wb);
            XSSFCellStyle contentStyle = createContentCellStyle(wb);
            // 行号
            int rowNum = 0;
            // 创建第一页的第一行，索引从0开始
            XSSFRow row0 = sheet.createRow(rowNum++);
            // 设置行高
            row0.setHeight((short) 600);
            //第二行
            XSSFRow row2 = sheet.createRow(rowNum++);
            row2.setHeight((short) 700);
            //第三行
            XSSFRow row3 = sheet.createRow(rowNum++);
            row3.setHeight((short) 700);
            String[] row_one = null;
            String[] row_two = null;
            String[] row_three = null;
            int cellSize = 0;

            row_one = new String[]{"序号", "分公司", "工程名称", "规模（km）", "电压等级（kV）", "开竣工日期", "预安排承接分包商及班组需求数量",
                    "工序", "班组计划数量", "班组和", "功效", "计数(月数)转化为天数", "公里数", "布距", "塔基数", "总施工天数"};
            List<String> arrayOneList = new ArrayList<>(Arrays.asList(row_one));
            for (int i = 0; i < timeList.size() - 1; i++) {
                arrayOneList.add(9, "");
            }
            // 将 ArrayList 转换回数组
            String[] new_row_one = arrayOneList.toArray(new String[0]);

            // 创建包含七个空字符串的列表
            List<String> emptyList = Collections.nCopies(7, "");
            row_two = new String[]{"", "", "", "", "", "", "", ""};
            List<String> arrayTwoList = new ArrayList<>(Arrays.asList(row_two));
            for (String year : yearList) {
                arrayTwoList.add(year);
                for (int j = 0; j < countMap.get(year) - 1; j++) {
                    arrayTwoList.add("");
                }
            }
            arrayTwoList.addAll(emptyList);
            // 将 ArrayList 转换回数组
            String[] new_row_two = arrayTwoList.toArray(new String[0]);

            row_three = new String[]{"", "", "", "", "", "", "", ""};
            List<String> arrayThreeList = new ArrayList<>(Arrays.asList(row_three));
            arrayThreeList.addAll(monthList);
            arrayThreeList.addAll(emptyList);
            String[] new_row_three = arrayThreeList.toArray(new String[0]);
            // 合并单元格
            extracted(sheet, monthColumn, countMap, yearList, 1);

            // 创建第一行单元格
            for (int i = 0; i < new_row_one.length; i++) {
                XSSFCell c00 = row0.createCell(i);
                c00.setCellValue(new_row_one[i]);
                c00.setCellStyle(headerStyle);
            }
            // 创建第二行单元格
            for (int i = 0; i < new_row_two.length; i++) {
                XSSFCell tempCell = row2.createCell(i);
                tempCell.setCellValue(new_row_two[i]);
                tempCell.setCellStyle(headerStyle);
            }
            // 创建第三行单元格
            for (int i = 0; i < new_row_three.length; i++) {
                XSSFCell tempCell = row3.createCell(i);
                tempCell.setCellValue(new_row_three[i]);
                tempCell.setCellStyle(headerStyle);
            }

            // 设置表头单元格的宽度
            tableTitleStyleColumnwidth(sheet, 1);

            /**-----------------------------------表头搭建完毕-------------------------------------------------*/
            //基础数据
            List<NewProBean> basicList = dao.getBasicDataList(o);
            List<Map<String, Object>> listData = new ArrayList<>();
            //班组数据
            for (NewProBean newProBean : basicList) {
                String jsonData = newProBean.getJsonData();
                JSONObject dObject = JSON.parseObject(jsonData);
                String jcObj = dObject.getString("jcObj");
                String ztObj = dObject.getString("ztObj");
                String jxObj = dObject.getString("jxObj");

                //获取开始时间的index
                int startIndex = timeList.indexOf(newProBean.getStartTime().substring(0, 7));
                //获取结束时间的index
                int endIndex = timeList.indexOf(newProBean.getEndTime().substring(0, 7));

                for (int j = 0; j < 3; j++) {
                    Map<String, Object> rowData = new LinkedHashMap<>();
                    rowData.put("clo0", newProBean.getOrgName());
                    rowData.put("clo1", newProBean.getProName());
                    rowData.put("clo2", newProBean.getScale());
                    rowData.put("clo3", newProBean.getVoltageLevel());
                    rowData.put("clo4", newProBean.getTime());
                    rowData.put("clo5", newProBean.getTheQuantityRequiredNum());
                    if (j == 0) {
                        rowData.put("clo6", "基础");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(jcObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (7 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("jc"));
                            rowData.put("clo" + (7 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (7 + monthColumn + k), "");
                        }
                    }
                    if (j == 1) {
                        rowData.put("clo6", "组塔");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(ztObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (7 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("zt"));
                            rowData.put("clo" + (7 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (7 + monthColumn + k), "");
                        }
                    }
                    if (j == 2) {
                        rowData.put("clo6", "架线");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(jxObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (7 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("jx"));
                            rowData.put("clo" + (7 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (7 + monthColumn + k), "");
                        }
                    }
                    rowData.put("col" + (7 + monthColumn), newProBean.getTeamNum());
                    rowData.put("col" + (8 + monthColumn), newProBean.getEfficacy());
                    rowData.put("col" + (9 + monthColumn), newProBean.getPlanToDay());
                    rowData.put("col" + (10 + monthColumn), newProBean.getKilometers());
                    rowData.put("col" + (11 + monthColumn), newProBean.getClothSpacing());
                    rowData.put("col" + (12 + monthColumn), newProBean.getBaseNumberOfTowers());
                    rowData.put("col" + (13 + monthColumn), newProBean.getTotalConstructionDays());
                    listData.add(rowData);
                }
            }

            for (int i = 0; i < listData.size(); i++) {
                XSSFRow tempRow = sheet.createRow(rowNum++);
                tempRow.setHeight((short) 500);
                Map<String, Object> rowData = listData.get(i);
                Cell cells = tempRow.createCell(0);
                if ((rowNum + 1) % 3 != 0) {
                    cells.setCellValue(i / 3 + 1);
                    cells.setCellStyle(contentStyle);
                }


                if (rowNum + 1 > 2 && (rowNum + 1) % 3 == 0) {
                    // 合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowNum - 2, rowNum, 0, 0));

                }
                int colIdx = 1;
                for (String key : rowData.keySet()) {
                    Cell cell = tempRow.createCell(colIdx);
                    cell.setCellValue(rowData.get(key).toString());
                    if (rowNum + 1 > 2 && (rowNum + 1) % 3 == 0 && (colIdx < 7 || colIdx > (7 + monthColumn))) {
                        // 合并单元格
                        sheet.addMergedRegion(new CellRangeAddress(rowNum - 2, rowNum, colIdx, colIdx));
                    }
                    colIdx++;
                    cell.setCellStyle(contentStyle);
                }
            }
            buildExcelDocument("预安排工程信息" + DateTimeHelper.getNowDateToSecond() + ".xlsx", wb, response, request);
        } catch (Exception e) {
            resCodes = 0;
            e.printStackTrace();
        }
        return resCodes;
    }

    @Override
    public int exportHistoryPro(HistoryProBean bean, HttpServletResponse response, HttpServletRequest request) {
        int resCodes = 1;
        try {
            bean.setLevel(UserUtil.getLoginUser().getLevel());
            bean.setOrgIds(UserUtil.getLoginUser().getOrgId());

            /**---------------------------------------获取导出表格中的部分基础数据-------------------------------------------------------*/
            //查询符合条件的工程中-工程开始最早日期和工程结束最晚时间
            HistoryProBean timeBean = dao.getHistoryMinAndMaxTimeBeans(bean);
            //根据开始-结束时间 获取时间list(格式年-月)
            List<String> timeList = DateTimeHelper.getAllMonth(timeBean.getStartTime().substring(0, 7), timeBean.getEndTime().substring(0, 7));
            //月份所需要的表格列数量
            int monthColumn = timeList.size();
            //统计年份包含的所有月份个数
            Map<String, Long> countMap = timeList.stream()
                    .map(time -> time.split("-")[0])
                    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            //开始-结束时间包含的所有年份
            List<String> yearList = timeList.stream()
                    .map(time -> time.split("-")[0])
                    .distinct()
                    .collect(Collectors.toList());
            //开始-结束时间包含的所有月份
            List<String> monthList = timeList.stream()
                    .map(time -> time.split("-")[1])
                    .collect(Collectors.toList());
            //根据条件查询所有符合的工程数据
            List<NewProBean> list = getHistoryExportData(bean);

            /**----------------------------------------开始组建  导出表格的标题-------------------------------------------------------*/

            // 第一步，创建一个Workbook，对应一个Excel文件
            XSSFWorkbook wb = new XSSFWorkbook();
            // 第二步，在Workbook中添加一个sheet,对应Excel文件中的sheet
            XSSFSheet sheet = wb.createSheet("历史工程信息清单");
            // 第三步，设置样式以及字体样式
            XSSFCellStyle headerStyle = createHeadCellStyle(wb);
            XSSFCellStyle contentStyle = createContentCellStyle(wb);
            // 行号
            int rowNum = 0;
            // 创建第一页的第一行，索引从0开始
            XSSFRow row0 = sheet.createRow(rowNum++);
            // 设置行高
            row0.setHeight((short) 600);
            //第二行
            XSSFRow row2 = sheet.createRow(rowNum++);
            row2.setHeight((short) 700);
            //第三行
            XSSFRow row3 = sheet.createRow(rowNum++);
            row3.setHeight((short) 700);
            String[] row_one = null;
            String[] row_two = null;
            String[] row_three = null;
            int cellSize = 0;

            row_one = new String[]{"序号", "分公司", "工程名称", "规模（km）", "电压等级（kV）", "开竣工日期", "工序", "班组计划数量"};
            List<String> arrayOneList = new ArrayList<>(Arrays.asList(row_one));
            for (int i = 0; i < timeList.size() - 1; i++) {
                arrayOneList.add(8, "");
            }
            // 将 ArrayList 转换回数组
            String[] new_row_one = arrayOneList.toArray(new String[0]);

            row_two = new String[]{"", "", "", "", "", "", ""};
            List<String> arrayTwoList = new ArrayList<>(Arrays.asList(row_two));
            for (String year : yearList) {
                arrayTwoList.add(year);
                for (int j = 0; j < countMap.get(year) - 1; j++) {
                    arrayTwoList.add("");
                }
            }
            // 将 ArrayList 转换回数组
            String[] new_row_two = arrayTwoList.toArray(new String[0]);

            row_three = new String[]{"", "", "", "", "", "", ""};
            List<String> arrayThreeList = new ArrayList<>(Arrays.asList(row_three));
            arrayThreeList.addAll(monthList);
            String[] new_row_three = arrayThreeList.toArray(new String[0]);
            // 合并单元格
            extracted(sheet, monthColumn, countMap, yearList, 2);

            // 创建第一行单元格
            for (int i = 0; i < new_row_one.length; i++) {
                XSSFCell c00 = row0.createCell(i);
                c00.setCellValue(new_row_one[i]);
                c00.setCellStyle(headerStyle);
            }
            // 创建第二行单元格
            for (int i = 0; i < new_row_two.length; i++) {
                XSSFCell tempCell = row2.createCell(i);
                tempCell.setCellValue(new_row_two[i]);
                tempCell.setCellStyle(headerStyle);
            }
            // 创建第三行单元格
            for (int i = 0; i < new_row_three.length; i++) {
                XSSFCell tempCell = row3.createCell(i);
                tempCell.setCellValue(new_row_three[i]);
                tempCell.setCellStyle(headerStyle);
            }

            // 设置表头单元格的宽度
            tableTitleStyleColumnwidth(sheet, 2);

            /**-----------------------------------表头搭建完毕-------------------------------------------------*/
            //基础数据
            List<Map<String, Object>> listData = new ArrayList<>();
            //班组数据
            for (NewProBean newProBean : list) {
                String jsonData = newProBean.getJsonData();
                JSONObject dObject = JSON.parseObject(jsonData);
                String jcObj = dObject.getString("jcObj");
                String ztObj = dObject.getString("ztObj");
                String jxObj = dObject.getString("jxObj");

                //获取开始时间的index
                int startIndex = timeList.indexOf(newProBean.getStartTime().substring(0, 7));
                //获取结束时间的index
                int endIndex = timeList.indexOf(newProBean.getEndTime().substring(0, 7));

                for (int j = 0; j < 3; j++) {
                    Map<String, Object> rowData = new LinkedHashMap<>();
                    rowData.put("clo0", newProBean.getOrgName());
                    rowData.put("clo1", newProBean.getProName());
                    rowData.put("clo2", newProBean.getScale());
                    rowData.put("clo3", newProBean.getVoltageLevel());
                    rowData.put("clo4", newProBean.getTime());
                    if (j == 0) {
                        rowData.put("clo5", "基础");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(jcObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (6 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("jc"));
                            rowData.put("clo" + (6 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (6 + monthColumn + k), "");
                        }
                    }
                    if (j == 1) {
                        rowData.put("clo5", "组塔");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(ztObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (6 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("zt"));
                            rowData.put("clo" + (6 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (6 + monthColumn + k), "");
                        }
                    }
                    if (j == 2) {
                        rowData.put("clo5", "架线");
                        JSONArray jcArray = JSON.parseArray(String.valueOf(jxObj));
                        for (int k = 0; k < startIndex; k++) {
                            rowData.put("clo" + (6 + k), "");
                        }
                        for (int l = 0; l < jcArray.size(); l++) {
                            JSONObject jcNode = JSON.parseObject(jcArray.get(l).toString());
                            String value = String.valueOf(jcNode.get("jx"));
                            rowData.put("clo" + (6 + startIndex + l), value);
                        }
                        for (int k = endIndex + 1; k < monthColumn; k++) {
                            rowData.put("clo" + (6 + monthColumn + k), "");
                        }
                    }
                    listData.add(rowData);
                }
            }

            for (int i = 0; i < listData.size(); i++) {
                XSSFRow tempRow = sheet.createRow(rowNum++);
                tempRow.setHeight((short) 500);
                Map<String, Object> rowData = listData.get(i);
                Cell cells = tempRow.createCell(0);
                if ((rowNum + 1) % 3 != 0) {
                    cells.setCellValue(i / 3 + 1);
                    cells.setCellStyle(contentStyle);
                }


                if (rowNum + 1 > 2 && (rowNum + 1) % 3 == 0) {
                    // 合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowNum - 2, rowNum, 0, 0));
                }
                int colIdx = 1;
                for (String key : rowData.keySet()) {
                    Cell cell = tempRow.createCell(colIdx);
                    cell.setCellValue("0".equals(rowData.get(key).toString()) ? "" : rowData.get(key).toString());
                    if (rowNum + 1 > 2 && (rowNum + 1) % 3 == 0) {
                        if (colIdx < 6) {
                            // 合并单元格
                            sheet.addMergedRegion(new CellRangeAddress(rowNum - 2, rowNum, colIdx, colIdx));
                        }
                    }
                    colIdx++;
                    cell.setCellStyle(contentStyle);
                }
            }
            buildExcelDocument("历史工程工程信息" + DateTimeHelper.getNowDateToSecond() + ".xlsx", wb, response, request);
        } catch (Exception e) {
            resCodes = 0;
            e.printStackTrace();
        }
        return resCodes;
    }

    private List<NewProBean> getHistoryExportData(HistoryProBean bean) throws ParseException {
        List<NewProBean> list = new ArrayList<>();
        List<HistoryProBean> proList = dao.getHistoryProList(bean);
        for (int i = 0; i < proList.size(); i++) {
            NewProBean n = new NewProBean();
            n.setId(proList.get(i).getProId());
            list.add(getHistoryListById(n));
        }
        return list;
    }

    /**
     * 设置某列的宽度
     *
     * @param sheet
     */
    private static void tableTitleStyleColumnwidth(XSSFSheet sheet, int type) {
        sheet.setColumnWidth(1, 8000);
        sheet.setColumnWidth(2, 8000);
        sheet.setColumnWidth(3, 5000);
        sheet.setColumnWidth(4, 5000);
        sheet.setColumnWidth(5, 8000);
        if (type == 1) {
            sheet.setColumnWidth(6, 8000);
        }
    }

    /**
     * 设置合并的行列
     *
     * @param sheet
     * @param monthColumn
     * @param countMap
     * @param yearList
     */
    private static void extracted(XSSFSheet sheet, int monthColumn, Map<String, Long> countMap, List<String> yearList, int type) {
        // todo: 合并参数分别为： 起始行，结束行，起始列，结束列
        // 将第一列 的 第一行到第三行合并
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 0, 0));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 1, 1));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 2, 2));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 3, 3));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 4, 4));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 5, 5));
        sheet.addMergedRegion(new CellRangeAddress(0, 2, 6, 6));
        int num = 0;
        int firstColumn = 7;
        int lastColumn = 7;
        if (type == 1) {
            sheet.addMergedRegion(new CellRangeAddress(0, 2, 7, 7));
            for (int i = 0; i < 7; i++) {
                sheet.addMergedRegion(new CellRangeAddress(0, 2, 8 + monthColumn + i, 8 + monthColumn + i));
            }
            // 班组
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 8, 7 + monthColumn));
        } else {
            // 班组
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 7, 6 + monthColumn));
            firstColumn = 6;
            lastColumn = 6;
        }
        // 班组下的单元格
        for (String year : yearList) {
            num = Integer.parseInt(String.valueOf(countMap.get(year)));
            out.println("num:" + num);
            lastColumn += num;
            if (num > 1) {
                sheet.addMergedRegion(new CellRangeAddress(1, 1, firstColumn + 1, lastColumn));
            }
            firstColumn = lastColumn;
        }
    }

    /**
     * 创建标题样式
     *
     * @param wb
     * @return
     */
    private static XSSFCellStyle createTitleCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        //水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        //垂直对齐
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 创建字体样式
        XSSFFont headerFont1 = (XSSFFont) wb.createFont();
        //字体加粗
        headerFont1.setBold(true);
        // 设置字体类型
        headerFont1.setFontName("黑体");
        // 设置字体大小
        headerFont1.setFontHeightInPoints((short) 15);
        // 为标题样式设置字体样式
        cellStyle.setFont(headerFont1);
        return cellStyle;
    }

    /**
     * 创建表头样式
     *
     * @param wb
     * @return
     */
    private static XSSFCellStyle createHeadCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        // 设置自动换行
        cellStyle.setWrapText(true);
        // 创建自定义 RGB 值
        // 紫色
        byte[] rgb = new byte[]{(byte) 110, 48, (byte) 164};

        // 创建一个颜色对象，并设置为紫色
        XSSFColor color = new XSSFColor(rgb, null);
        //背景颜色
        cellStyle.setFillForegroundColor(color);
        //水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        //垂直对齐
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.index);
        //下边框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //左边框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //右边框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //上边框
        cellStyle.setBorderTop(BorderStyle.THIN);
        // 创建字体样式
        XSSFFont headerFont = (XSSFFont) wb.createFont();
        //字体加粗
        headerFont.setBold(true);
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        // 设置字体类型
        headerFont.setFontName("黑体");
        // 设置字体大小
        headerFont.setFontHeightInPoints((short) 12);
        // 为标题样式设置字体样式
        cellStyle.setFont(headerFont);

        return cellStyle;
    }

    /**
     * 创建内容样式
     *
     * @param wb
     * @return
     */
    private static XSSFCellStyle createContentCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        // 垂直居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 水平居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        // 设置自动换行
        cellStyle.setWrapText(true);
        //下边框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //左边框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //右边框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //上边框
        cellStyle.setBorderTop(BorderStyle.THIN);

        // 生成12号字体
        XSSFFont font = wb.createFont();
        font.setColor((short) 8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }

    /**
     * 导出excel 设置文件名称等
     *
     * @param fileName
     * @param wb
     * @param response
     * @param request
     */
    private static void buildExcelDocument(String fileName, Workbook wb, HttpServletResponse response, HttpServletRequest request) {
        try {
            String filename = "";
            try {
                filename = ExcelUtils.encodeChineseDownloadFileName(request, fileName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            response.setHeader("Content-disposition", filename);
//            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=" + filename);
            response.setHeader("Pragma", "No-cache");
            OutputStream ouputStream = response.getOutputStream();
            wb.write(ouputStream);
            ouputStream.flush();
            ouputStream.close();
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(wb);
        }
    }
}
