package cn.com.countrygarden.bi.main.service.extension;

import cn.com.countrygarden.bi.main.dto.extension.ExtensionJointInfoDTO;
import cn.com.countrygarden.bi.main.dto.extension.ExtensionProjectLeaderDTO;
import cn.com.countrygarden.bi.main.dto.extension.ExtensionPropertyCompositionDTO;
import cn.com.countrygarden.bi.main.dto.extension.ExtensionReportDTO;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * @ClassName: ExtensionExportServiceTask
 * @Description $
 * @Author sjiang
 * @Date 14:47
 * @VERSION 1.0.0
 **/
public class ExtensionExportServiceTask implements Runnable {

    private int start;
    private int end;
    private CountDownLatch countDownLatch;
    private List<ExtensionReportDTO> list;
    private XSSFWorkbook workbook;

    public ExtensionExportServiceTask(int start, int end, CountDownLatch countDownLatch, List<ExtensionReportDTO> list, XSSFWorkbook workbook) {
        this.start = start;
        this.end = end;
        this.countDownLatch = countDownLatch;
        this.list = list;
        this.workbook = workbook;
    }

    public ExtensionExportServiceTask(int start, int end, CountDownLatch countDownLatch, List<ExtensionReportDTO> list) {
        this.start = start;
        this.end = end;
        this.countDownLatch = countDownLatch;
        this.list = list;

    }

    @Override
    public void run() {
        try {
                String title = "拓后管理报表";
                String sheetName = "sheet1";
                // 表头
                String[] titles1 = {"物业区域", "物业区域编号", "物业项目", "项目性质", "物业项目编号", "省级行政区",
                        "地级行政区域", "县级行政区", "乡级行政区域", "项目类型", "项目营业执照的\r\n物业公司全称", "项目营业执照的\r\n母公司全称", "NC账套全称",
                        "NC账套编码", "NC人力组织编码", "物业公司资金类型", "开发主体\r\n（房产核算全称）"};
                String[] titles2 = {"业委会成立情况", "项目开发主体", "物业业态", "项目开发状态", "接管状态", "拓展人员信息", "", "合同性质",
                        "签约日期", "合同生效日期", "合同终止时间", "实际进驻时间", "收楼状态", "常规物业收费模式", "常规物业服务模式", "销售案场收费模式",
                        "销售案场服务模式", "计划开盘时间(首期)", "实际开盘时间(首期)", "合同收楼时间(首批)", "实际收楼时间(首批)", "案场结束时间",
                        "常规物业管理退场时间", "接管时间", "规划户数", "合同签约面积（㎡)", "物业构成情况", "", "", "", "上会年饱和\r\n收入(万元）",
                        "上会经营指标", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "合同特殊约定", "", "", ""};
                int jointSize = 1;
                int leaderSize = 1;

                for (int i = start; i < end; i++) {
                    ExtensionReportDTO reportDTO = list.get(i);
                    List<ExtensionJointInfoDTO> jointDTO = reportDTO.getJointDTO();
                    List<ExtensionProjectLeaderDTO> leaderDTO = reportDTO.getLeaderDTO();
                    jointSize = jointDTO != null && jointDTO.size() > jointSize ? jointDTO.size() : jointSize;
                    leaderSize = leaderDTO != null && leaderDTO.size() > leaderSize ? leaderDTO.size() : leaderSize;
                }

                // 数组总大小
                int size = titles1.length + titles2.length + jointSize * 2 + leaderSize * 2;
                ArrayList<String> targetList = new ArrayList<>(size);
                // 合并的计数器
                HashMap<String, Integer> mergeMap = Maps.newHashMap();
                // 甲方对接人前半部分标题
                for (int i = 0; i < titles1.length; i++) {
                    targetList.add(titles1[i]);
                }
                for (int i = 0; i < jointSize; i++) {
                    targetList.add("甲方对接人" + i);
                    targetList.add("联系方式" + i );
                }
                for (int i = 0; i < titles2.length; i++) {
                    targetList.add(titles2[i]);
                    if ("规划户数".equals(titles2[i])) {
                        mergeMap.put("规划户数", targetList.indexOf(titles2[i]));
                    }
                }
                for (int i = 0; i < leaderSize; i++) {
                    targetList.add("项目负责人");
                    targetList.add("");
                }
                List<ArrayList<Object>> data = new ArrayList<>(end - start);

                // 创建工作表
                XSSFSheet sheet = workbook.createSheet(sheetName);
                // 设置宽度
                for (int i = 0; i < size; i++) {
                    sheet.setColumnWidth(i, 16 * 330);
                }
                if (StringUtils.isNotBlank(title)) {
                    // 合并单元格
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, size - 1);
                    // 设置单元格格式
                    sheet.addMergedRegion(setCellRangAddress(0, 0, 0, size - 1, cellRangeAddress));
                    /*  第一行标题处理 */
                    XSSFRow row01 = sheet.createRow(0);
                    XSSFCell cell01 = row01.createCell(0);
                    // 设置单元格内容
                    cell01.setCellValue(title);
                    // 通过工作簿创建样式
                    XSSFCellStyle cellStyle = createCellStyle(workbook, "Courier New", (short) 15, true, true);
                    // 设置单元格样式
                    cell01.setCellStyle(cellStyle);
                    /*  第一行标题处理  END */

                    /*  第二行标题处理 */

                    // 通过工作簿创建样式
                    XSSFCellStyle cellStyle2 = createCellStyle(workbook, "Courier New", (short) 15, true, true);
                    XSSFRow row02 = sheet.createRow(StringUtils.isNotBlank(title) ? 1 : 0);
                    XSSFRow row03 = sheet.createRow(StringUtils.isNotBlank(title) ? 2 : 1);
                    XSSFRow row04 = sheet.createRow(StringUtils.isNotBlank(title) ? 3 : 2);


                    /*  第二行标题处理  END */
                    // 获取 物业构成情况所在列 为后面的合并单元格做准备
                    int propertyCol = 0;
                    for (int i = 0; i < size; i++) {
                        String val = targetList.get(i);
                        XSSFCell titleCell = row02.createCell(i);
                        titleCell.setCellValue(val);
                        titleCell.setCellStyle(cellStyle2);
                        if ("拓展人员信息".equals(val)) {
                            XSSFCell cell = row03.createCell(i);
                            cell.setCellValue("姓名");
                            cell.setCellStyle(cellStyle2);
                            XSSFCell cell1 = row03.createCell(i + 1);
                            cell1.setCellValue("联系电话");
                            cell1.setCellStyle(cellStyle2);
                            // 合并单元格CellRangeAddress构造参数依次表示起始行，截至行，起始列， 截至列
                            // 设置单元格格式
                            sheet.addMergedRegion(setCellRangAddress(1, 1, i, i + 1, cellRangeAddress));
//                    sheet.addMergedRegion(new CellRangeAddress(2, 3, i, i));
                            sheet.addMergedRegion(setCellRangAddress(2, 3, i, i, cellRangeAddress));
                            sheet.addMergedRegion(setCellRangAddress(2, 3, i + 1, i + 1, cellRangeAddress));
//                    sheet.addMergedRegion(new CellRangeAddress(2, 3, i + 1, i + 1));
                            row04.createCell(i).setCellStyle(cellStyle2);
                            i++;
                        } else if ("物业构成情况".equals(val)) {
                            propertyCol = i;
                            XSSFCell cell = row03.createCell(i);
                            cell.setCellValue("业态名称");
                            cell.setCellStyle(cellStyle2);
                            XSSFCell cell1 = row03.createCell(i + 1);
                            cell1.setCellValue("可收费面积㎡");
                            cell1.setCellStyle(cellStyle2);
                            XSSFCell cell2 = row03.createCell(i + 2);
                            cell2.setCellValue("单价（元/㎡/个）");
                            cell2.setCellStyle(cellStyle2);
                            XSSFCell cell3 = row03.createCell(i + 3);
                            cell3.setCellValue("月饱和收入（元）");
                            cell3.setCellStyle(cellStyle2);
                            sheet.addMergedRegion(setCellRangAddress(1, 1, i, i + 3, cellRangeAddress));
                            for (int j = 0; j < 4; j++) {
                                sheet.addMergedRegion(setCellRangAddress(2, 3, i + j, i + j, cellRangeAddress));
                            }
                            row04.createCell(i).setCellStyle(cellStyle2);
                            i += 3;
                        } else if ("上会经营指标".equals(val)) {
                            XSSFCell cell = row03.createCell(i);
                            cell.setCellValue("第一年");
                            cell.setCellStyle(cellStyle2);
                            XSSFCell cell1 = row03.createCell(i + 6);
                            cell1.setCellValue("第二年");
                            cell1.setCellStyle(cellStyle2);
                            XSSFCell cell2 = row03.createCell(i + 6 + 6);
                            cell2.setCellValue("第三年");
                            cell2.setCellStyle(cellStyle2);
                            for (int j = 0; j < 19; j += 6) {
                                XSSFCell cell3 = row04.createCell(i + j);
                                cell3.setCellValue("主营收缴率（%）");
                                cell3.setCellStyle(cellStyle2);
                                XSSFCell cell4 = row04.createCell(i + j + 1);
                                cell4.setCellValue("主营收入（元）");
                                cell4.setCellStyle(cellStyle2);
                                XSSFCell cell5 = row04.createCell(i + j + 2);
                                cell5.setCellValue("主营利润（元）");
                                cell5.setCellStyle(cellStyle2);
                                XSSFCell cell8 = row04.createCell(i + j + 3);
                                cell8.setCellValue("补贴(元)");
                                cell8.setCellStyle(cellStyle2);
                                XSSFCell cell6 = row04.createCell(i + j + 4);
                                cell6.setCellValue("总成本（元）");
                                cell6.setCellStyle(cellStyle2);
                                XSSFCell cell7 = row04.createCell(i + j + 5);
                                cell7.setCellValue("综合净利润（%）");
                                cell7.setCellStyle(cellStyle2);
                            }

                            sheet.addMergedRegion(setCellRangAddress(1, 1, i, i + 17, cellRangeAddress));

                            sheet.addMergedRegion(setCellRangAddress(2, 2, i, i + 5, cellRangeAddress));
                            sheet.addMergedRegion(setCellRangAddress(2, 2, i + 6, i + 6 + 5, cellRangeAddress));
                            sheet.addMergedRegion(setCellRangAddress(2, 2, i + 6 + 6, i + 6 + 6 + 5, cellRangeAddress));
                            i += 17;
                        } else if ("合同特殊约定".equals(val)) {
                            XSSFCell cell = row03.createCell(i);
                            cell.setCellValue("空置房费用\r\n打折收取约定");
                            cell.setCellStyle(cellStyle2);
                            XSSFCell cell1 = row03.createCell(i + 1);
                            cell1.setCellValue("物业费单价约定");
                            cell1.setCellStyle(cellStyle2);
                            XSSFCell cell2 = row03.createCell(i + 2);
                            cell2.setCellValue("开办费用约定");
                            cell2.setCellStyle(cellStyle2);
                            XSSFCell cell3 = row03.createCell(i + 3);
                            cell3.setCellValue("其他特殊约定");
                            cell3.setCellStyle(cellStyle2);
                            sheet.addMergedRegion(setCellRangAddress(1, 1, i, i + 3, cellRangeAddress));
                            for (int j = 0; j < 4; j++) {
                                sheet.addMergedRegion(setCellRangAddress(2, 3, i + j, i + j, cellRangeAddress));
                            }
                            row04.createCell(i).setCellStyle(cellStyle2);
                            i += 3;
                        } else if ("项目负责人".equals(val)) {
                            XSSFCell cell = row03.createCell(i);
                            cell.setCellValue("姓名");
                            cell.setCellStyle(cellStyle2);
                            XSSFCell cell1 = row03.createCell(i + 1);
                            cell1.setCellValue("联系方式");
                            cell1.setCellStyle(cellStyle2);

                            sheet.addMergedRegion(setCellRangAddress(1, 1, i, i + 1, cellRangeAddress));
                            sheet.addMergedRegion(setCellRangAddress(2, 3, i, i, cellRangeAddress));
                            sheet.addMergedRegion(setCellRangAddress(2, 3, i + 1, i + 1, cellRangeAddress));
                            row04.createCell(i).setCellStyle(cellStyle2);
                            i += 1;
                        } else {
                            sheet.addMergedRegion(setCellRangAddress(1, 3, i, i, cellRangeAddress));
                            row03.createCell(i).setCellStyle(cellStyle2);
                            row04.createCell(i).setCellStyle(cellStyle2);
                        }


                    }
                    // 合并之后的数据
                    //     规划户数
                    Map<Long, BigDecimal> planNumberMergeData = Maps.newHashMap();
                    //     合同签约面积
                    Map<Long, BigDecimal> contractAreaMergeData = Maps.newHashMap();
                    //     可收费面积
                    Map<Long, BigDecimal> ratesAreaMergeData = Maps.newHashMap();
                    //     月饱和收入
                    Map<Long, BigDecimal> monthIncomeMergeData = Maps.newHashMap();
                    //     上会年饱和收入
                    Map<Long, BigDecimal> yearIncomeMergeData = Maps.newHashMap();
                    //     第一年 主营收入
                    Map<Long, BigDecimal> firstSalesRevenueMergeData = Maps.newHashMap();
                    //     第一年 主营利润
                    Map<Long, BigDecimal> firstMainBusinessProfitMergeData = Maps.newHashMap();
                    //     第一年 补贴
                    Map<Long, BigDecimal> firstSubsidyMergeData = Maps.newHashMap();
                    //     第一年 总成本
                    Map<Long, BigDecimal> firstTotalCostMergeData = Maps.newHashMap();

                    //     第二年 主营收入
                    Map<Long, BigDecimal> secondSalesRevenueMergeData = Maps.newHashMap();
                    //     第二年 主营利润
                    Map<Long, BigDecimal> secondMainBusinessProfitMergeData = Maps.newHashMap();
                    //     第二年 补贴
                    Map<Long, BigDecimal> secondSubsidyMergeData = Maps.newHashMap();
                    //     第二年 总成本
                    Map<Long, BigDecimal> secondTotalCostMergeData = Maps.newHashMap();

                    //     第三年 主营收入
                    Map<Long, BigDecimal> thirdlySalesRevenueMergeData = Maps.newHashMap();
                    //     第三年 主营利润
                    Map<Long, BigDecimal> thirdlyMainBusinessProfitMergeData = Maps.newHashMap();
                    //     第三年 补贴
                    Map<Long, BigDecimal> thirdlySubsidyMergeData = Maps.newHashMap();
                    //     第三年 总成本
                    Map<Long, BigDecimal> thirdlyTotalCostMergeData = Maps.newHashMap();

                    /** 中间行的处理  */
                    // 数据处理
                    if (!list.isEmpty()) {
                        for (int k = start; k < end; k++) {
                            ExtensionReportDTO d = list.get(k);
                            List<ExtensionPropertyCompositionDTO> propertyCompositionDTOS = d.getPropertyCompositionDTOS();
                            int propertySize = 0;
                            if (propertyCompositionDTOS != null && propertyCompositionDTOS.size() > 0){
                                propertySize = propertyCompositionDTOS.size();
                            }
                            if (propertySize > 1) {
                                for (int i = 0; i < propertySize; i++) {
                                    ArrayList<Object> rowData = new ArrayList<>();
                                    // 物业区域
                                    rowData.add(d.getPropertyArea());
                                    // 物业区域编号
                                    rowData.add(d.getAreaNumber());
                                    // 物业项目
                                    rowData.add(d.getPropertyProject());
                                    // 项目性质
                                    rowData.add(d.getCommKind());
                                    // 物业项目编号
                                    rowData.add(d.getProjectNumber());
                                    // 省级行政区
                                    rowData.add(d.getProvince());
                                    // 市级行政区域
                                    rowData.add(d.getCity());
                                    // 县级行政区
                                    rowData.add(d.getBorough());
                                    // 乡级行政区
                                    rowData.add(d.getRegion());
                                    // 项目类型
                                    rowData.add(d.getProjectType());
                                    // 项目营业执照的物业公司全称
                                    rowData.add(d.getPropertyName());
                                    // 项目营业执照的母公司全称
                                    rowData.add(d.getParentCompany());
                                    // NC 账套全称
                                    rowData.add(d.getNcSystemAccount());
                                    // NC 账套编码
                                    rowData.add(d.getNcSystemNumber());
                                    // NC 人力组织编码
                                    rowData.add(d.getNcPersonNumber());
                                    // 物业公司资金类型
                                    rowData.add(d.getFundType());
                                    // 开发主体（房产核算全称）
                                    rowData.add(d.getDevelopmentSubjectNames());

                                    // 甲方对接人
                                    List<ExtensionJointInfoDTO> jointDTOList = d.getJointDTO();
                                    //     遍历最大的 子对象
                                    for (int j = 0; j < jointSize; j++) {
                                        if (null != jointDTOList && !jointDTOList.isEmpty() && jointDTOList.size() > j) {
                                            rowData.add(jointDTOList.get(j).getJointName());
                                            rowData.add(jointDTOList.get(j).getJointTel());
                                        }
                                        // 表示无子对象或子对象数量不足  需要填空
                                        else {
                                            rowData.add("");
                                            rowData.add("");
                                        }
                                    }

                                    // 业委会成立情况 0=是 ,1= 否
                                    if ("0".equals(d.getCommitteeStatus())) {
                                        rowData.add("是");
                                    } else if ("1".equals(d.getCommitteeStatus())){
                                        rowData.add("否");
                                    }else {
                                        rowData.add("");
                                    }
                                    // 项目开发主体
                                    rowData.add(d.getDevelopmentSubject());
                                    // 物业业态
                                    rowData.add(d.getPropertyForm());
                                    // 项目开发状态
                                    rowData.add(d.getDevelopmentState());
                                    // 接管状态
                                    rowData.add(d.getTakeoverState());
                                    //  拓展人员信息 姓名
                                    rowData.add(d.getExtensionPerson());
                                    // 拓展人员信息 联系方式
                                    rowData.add(d.getExtensionPersonTel());
                                    // 合同性质
                                    rowData.add(d.getContractProperty());
                                    // 签约日期
                                    rowData.add(d.getSignTime());
                                    // 合同生效日期
                                    rowData.add(d.getContractCommencementDate());
                                    // 合同终止时间
                                    rowData.add(d.getContractEndDate());
                                    // 实际进驻时间
                                    rowData.add(d.getActualEnterTime());
                                    // 收楼状态
                                    rowData.add(d.getStateProperty());
                                    // 常规物业收费模式
                                    rowData.add(d.getConventionalCharges());
                                    // 常规物业服务模式
                                    rowData.add(d.getConventionalService());
                                    // 销售案场收费模式
                                    rowData.add(d.getSalesFieldCharges());
                                    // 销售案场服务模式
                                    rowData.add(d.getSalesFieldService());
                                    // 计划开盘时间(首期)
                                    rowData.add(d.getPlannedOpen());
                                    // 实际开盘时间(首期)
                                    rowData.add(d.getActualOpen());
                                    // 合同收楼时间(首批)
                                    rowData.add(d.getContractPropertyDate());
                                    // 实际收楼时间(首批)
                                    rowData.add(d.getActualProperty());
                                    // 案场结束时间
                                    rowData.add(d.getEndCaseDate());
                                    // 常规物业管理退场时间
                                    rowData.add(d.getEndEstateManagementDate());
                                    // 合同接管时间
                                    rowData.add(d.getManageTime());
                                    // 规划户数
                                    rowData.add(d.getPlanNumber());
                                    planNumberMergeData.put(d.getId(), new BigDecimal(d.getPlanNumber() != null ? d.getPlanNumber():0));
                                    // 合同签约面积
                                    rowData.add(d.getContractArea());
                                    contractAreaMergeData.put(d.getId(), d.getContractArea());
                                    // 物业构成情况
                                    //     业态名称
                                    ExtensionPropertyCompositionDTO compositionDTO = d.getPropertyCompositionDTOS().get(i);
                                    rowData.add(compositionDTO.getBusinessTypeName());
                                    //     可收费面积 ㎡
                                    rowData.add(compositionDTO.getRatesArea());
                                    ratesAreaMergeData.put(compositionDTO.getId(), compositionDTO.getRatesArea());
                                    //     单价（元/㎡/个）
                                    rowData.add(compositionDTO.getPrice());
                                    //     月饱和收入（元）
                                    rowData.add(compositionDTO.getMonthIncome());
                                    monthIncomeMergeData.put(compositionDTO.getId(), compositionDTO.getMonthIncome());
                                    //     年饱和收入（元）
                                    rowData.add(compositionDTO.getYearIncome());
                                    yearIncomeMergeData.put(compositionDTO.getId(), compositionDTO.getYearIncome());

                                    // 上会经营
                                    //     第一年
                                    //        主营收缴率（%）
                                    rowData.add(d.getFirstMainCollectionRate());
                                    //        主营收入（元）
                                    rowData.add(d.getFirstSalesRevenue());
                                    firstSalesRevenueMergeData.put(d.getId(), d.getFirstSalesRevenue());
                                    //        主营利润（元）
                                    rowData.add(d.getFirstMainBusinessProfit());
                                    firstMainBusinessProfitMergeData.put(d.getId(), d.getFirstMainBusinessProfit());
                                    //        补贴（元）
                                    rowData.add(d.getFirstSubsidy());
                                    firstSubsidyMergeData.put(d.getId(), d.getFirstSubsidy());
                                    //        总成本（元）
                                    rowData.add(d.getFirstTotalCost());
                                    firstTotalCostMergeData.put(d.getId(), d.getFirstTotalCost());
                                    //        综合净利润（%）
                                    rowData.add(d.getFirstNetProfit());
                                    //     第二年
                                    rowData.add(d.getSecondMainCollectionRate());
                                    //        主营收入（元）
                                    rowData.add(d.getSecondSalesRevenue());
                                    secondSalesRevenueMergeData.put(d.getId(), d.getSecondSalesRevenue());
                                    //        主营利润（元）
                                    rowData.add(d.getSecondMainBusinessProfit());
                                    secondMainBusinessProfitMergeData.put(d.getId(), d.getSecondMainBusinessProfit());
                                    //        补贴（元）
                                    rowData.add(d.getSecondSubsidy());
                                    secondSubsidyMergeData.put(d.getId(), d.getSecondSubsidy());
                                    //        总成本（元）
                                    rowData.add(d.getSecondTotalCost());
                                    secondTotalCostMergeData.put(d.getId(), d.getSecondTotalCost());
                                    //         综合净利润（%）
                                    rowData.add(d.getSecondNetProfit());
                                    //     第三年
                                    rowData.add(d.getThirdlyMainCollectionRate());
                                    //        主营收入（元）
                                    rowData.add(d.getThirdlySalesRevenue());
                                    thirdlySalesRevenueMergeData.put(d.getId(), d.getThirdlySalesRevenue());
                                    //        主营利润（元）
                                    rowData.add(d.getThirdlyMainBusinessProfit());
                                    thirdlyMainBusinessProfitMergeData.put(d.getId(), d.getThirdlyMainBusinessProfit());
                                    //        补贴（元）
                                    rowData.add(d.getThirdlySubsidy());
                                    thirdlySubsidyMergeData.put(d.getId(), d.getThirdlySubsidy());
                                    //        总成本（元）
                                    rowData.add(d.getThirdlyTotalCost());
                                    thirdlyTotalCostMergeData.put(d.getId(), d.getThirdlyTotalCost());
                                    //         综合净利润（%）
                                    rowData.add(d.getThirdlyNetProfit());

                                    // 合同特殊约定
                                    //     空置房费用打折收取约定
                                    rowData.add(d.getEmptyRoomFeesAgreement());
                                    //     物业费单价约定
                                    rowData.add(d.getPropertyFeesPriceAgreement());
                                    //     开办费用约定
                                    rowData.add(d.getStartUpFeesAgreement());
                                    //     其他特殊约定
                                    rowData.add(d.getOtherAgreement());

                                    // 项目负责人信息  不用做特殊处理 因为是最后一个
                                    List<ExtensionProjectLeaderDTO> leaderDTOList = d.getLeaderDTO();
                                    for (int j = 0; j < leaderSize; j++) {
                                        if (null != leaderDTOList && !leaderDTOList.isEmpty() && leaderDTOList.size() > j) {
                                            rowData.add(leaderDTOList.get(j).getLeaderName());
                                            rowData.add(leaderDTOList.get(j).getLeaderTel());
                                        }
                                        // 表示无子对象或子对象数量不足  需要填空
                                        else {
                                            rowData.add("");
                                            rowData.add("");
                                        }
                                    }
                                    data.add(rowData);


                                }
                            }
                            // 表示 物业构成情况只有一行
                            else {
                                ArrayList<Object> rowData = new ArrayList<>();
                                // 物业区域
                                rowData.add(d.getPropertyArea());
                                // 物业区域编号
                                rowData.add(d.getAreaNumber());
                                // 物业项目
                                rowData.add(d.getPropertyProject());
                                // 项目性质
                                rowData.add(d.getCommKind());
                                // 物业项目编号
                                rowData.add(d.getProjectNumber());
                                // 省级行政区
                                rowData.add(d.getProvince());
                                // 市级行政区域
                                rowData.add(d.getCity());
                                // 县级行政区
                                rowData.add(d.getBorough());
                                // 乡级行政区
                                rowData.add(d.getRegion());
                                // 项目类型
                                rowData.add(d.getProjectType());
                                // 项目营业执照的物业公司全称
                                rowData.add(d.getPropertyName());
                                // 项目营业执照的母公司全称
                                rowData.add(d.getParentCompany());
                                // NC 账套全称
                                rowData.add(d.getNcSystemAccount());
                                // NC 账套编码
                                rowData.add(d.getNcSystemNumber());
                                // NC 人力组织编码
                                rowData.add(d.getNcPersonNumber());
                                // 物业公司资金类型
                                rowData.add(d.getFundType());
                                // 开发主体（房产核算全称）
                                rowData.add(d.getDevelopmentSubjectNames());

                                // 甲方对接人
                                List<ExtensionJointInfoDTO> jointDTOList = d.getJointDTO();
                                //     遍历最大的 子对象
                                for (int j = 0; j < jointSize; j++) {
                                    if (null != jointDTOList && !jointDTOList.isEmpty() && jointDTOList.size() > j) {
                                        rowData.add(jointDTOList.get(j).getJointName());
                                        rowData.add(jointDTOList.get(j).getJointTel());
                                    }
                                    // 表示无子对象或子对象数量不足  需要填空
                                    else {
                                        rowData.add("");
                                        rowData.add("");
                                    }
                                }

                                // 业委会成立情况 0=是 ,1= 否
                                if ("0".equals(d.getCommitteeStatus())) {
                                    rowData.add("是");
                                } else if ("1".equals(d.getCommitteeStatus())){
                                    rowData.add("否");
                                }else {
                                    rowData.add("");
                                }
                                // 项目开发主体
                                rowData.add(d.getDevelopmentSubject());
                                // 物业业态
                                rowData.add(d.getPropertyForm());
                                // 项目开发状态
                                rowData.add(d.getDevelopmentState());
                                // 接管状态
                                rowData.add(d.getTakeoverState());
                                //  拓展人员信息 姓名
                                rowData.add(d.getExtensionPerson());
                                // 拓展人员信息 联系方式
                                rowData.add(d.getExtensionPersonTel());
                                // 合同性质
                                rowData.add(d.getContractProperty());
                                // 签约日期
                                rowData.add(d.getSignTime());
                                // 合同生效日期
                                rowData.add(d.getContractCommencementDate());
                                // 合同终止时间
                                rowData.add(d.getContractEndDate());
                                // 实际进驻时间
                                rowData.add(d.getActualEnterTime());
                                // 收楼状态
                                rowData.add(d.getStateProperty());
                                // 常规物业收费模式
                                rowData.add(d.getConventionalCharges());
                                // 常规物业服务模式
                                rowData.add(d.getConventionalService());
                                // 销售案场收费模式
                                rowData.add(d.getSalesFieldCharges());
                                // 销售案场服务模式
                                rowData.add(d.getSalesFieldService());
                                // 计划开盘时间(首期)
                                rowData.add(d.getPlannedOpen());
                                // 实际开盘时间(首期)
                                rowData.add(d.getActualOpen());
                                // 合同收楼时间(首批)
                                rowData.add(d.getContractPropertyDate());
                                // 实际收楼时间(首批)
                                rowData.add(d.getActualProperty());
                                // 案场结束时间
                                rowData.add(d.getEndCaseDate());
                                // 常规物业管理退场时间
                                rowData.add(d.getEndEstateManagementDate());
                                // 合同接管时间
                                rowData.add(d.getManageTime());
                                // 规划户数
                                rowData.add(d.getPlanNumber());
                                planNumberMergeData.put(d.getId(), new BigDecimal(d.getPlanNumber() != null ? d.getPlanNumber():0));
                                // 合同签约面积
                                rowData.add(d.getContractArea());
                                contractAreaMergeData.put(d.getId(), d.getContractArea());
                                // 物业构成情况
                                //     业态名称
                                if (propertySize > 0){
                                    ExtensionPropertyCompositionDTO compositionDTO = propertyCompositionDTOS.get(0);
                                    rowData.add(compositionDTO.getBusinessTypeName());
                                    //     可收费面积 ㎡
                                    rowData.add(compositionDTO.getRatesArea());
                                    ratesAreaMergeData.put(compositionDTO.getId(), compositionDTO.getRatesArea());
                                    //     单价（元/㎡/个）
                                    rowData.add(compositionDTO.getPrice());
                                    //     月饱和收入（元）
                                    rowData.add(compositionDTO.getMonthIncome());
                                    monthIncomeMergeData.put(compositionDTO.getId(), compositionDTO.getMonthIncome());
                                    //     年饱和收入（元）
                                    rowData.add(compositionDTO.getYearIncome());
                                    yearIncomeMergeData.put(compositionDTO.getId(), compositionDTO.getYearIncome());
                                } else {
                                    rowData.add("");
                                    //     可收费面积 ㎡
                                    rowData.add("");
                                    //     单价（元/㎡/个）
                                    rowData.add("");
                                    //     月饱和收入（元）
                                    rowData.add("");
                                    //     年饱和收入（元）
                                    rowData.add("");
                                }
                                // 上会经营
                                //     第一年
                                //        主营收缴率（%）
                                rowData.add(d.getFirstMainCollectionRate());
                                //        主营收入（元）
                                rowData.add(d.getFirstSalesRevenue());
                                firstSalesRevenueMergeData.put(d.getId(), d.getFirstSalesRevenue());
                                //        主营利润（元）
                                rowData.add(d.getFirstMainBusinessProfit());
                                firstMainBusinessProfitMergeData.put(d.getId(), d.getFirstMainBusinessProfit());
                                //        补贴（元）
                                rowData.add(d.getFirstSubsidy());
                                firstSubsidyMergeData.put(d.getId(), d.getFirstSubsidy());
                                //        总成本（元）
                                rowData.add(d.getFirstTotalCost());
                                firstTotalCostMergeData.put(d.getId(), d.getFirstTotalCost());
                                //        综合净利润（%）
                                rowData.add(d.getFirstNetProfit());
                                //     第二年
                                rowData.add(d.getSecondMainCollectionRate());
                                //        主营收入（元）
                                rowData.add(d.getSecondSalesRevenue());
                                secondSalesRevenueMergeData.put(d.getId(), d.getSecondSalesRevenue());
                                //        主营利润（元）
                                rowData.add(d.getSecondMainBusinessProfit());
                                secondMainBusinessProfitMergeData.put(d.getId(), d.getSecondMainBusinessProfit());
                                //        补贴（元）
                                rowData.add(d.getSecondSubsidy());
                                secondSubsidyMergeData.put(d.getId(), d.getSecondSubsidy());
                                //        总成本（元）
                                rowData.add(d.getSecondTotalCost());
                                secondTotalCostMergeData.put(d.getId(), d.getSecondTotalCost());
                                //         综合净利润（%）
                                rowData.add(d.getSecondNetProfit());
                                //     第三年
                                rowData.add(d.getThirdlyMainCollectionRate());
                                //        主营收入（元）
                                rowData.add(d.getThirdlySalesRevenue());
                                thirdlySalesRevenueMergeData.put(d.getId(), d.getThirdlySalesRevenue());
                                //        主营利润（元）
                                rowData.add(d.getThirdlyMainBusinessProfit());
                                thirdlyMainBusinessProfitMergeData.put(d.getId(), d.getThirdlyMainBusinessProfit());
                                //        补贴（元）
                                rowData.add(d.getThirdlySubsidy());
                                thirdlySubsidyMergeData.put(d.getId(), d.getThirdlySubsidy());
                                //        总成本（元）
                                rowData.add(d.getThirdlyTotalCost());
                                thirdlyTotalCostMergeData.put(d.getId(), d.getThirdlyTotalCost());
                                //         综合净利润（%）
                                rowData.add(d.getThirdlyNetProfit());

                                // 合同特殊约定
                                //     空置房费用打折收取约定
                                rowData.add(d.getEmptyRoomFeesAgreement());
                                //     物业费单价约定
                                rowData.add(d.getPropertyFeesPriceAgreement());
                                //     开办费用约定
                                rowData.add(d.getStartUpFeesAgreement());
                                //     其他特殊约定
                                rowData.add(d.getOtherAgreement());

                                // 项目负责人信息  不用做特殊处理 因为是最后一个
                                List<ExtensionProjectLeaderDTO> leaderDTOList = d.getLeaderDTO();
                                for (int j = 0; j < leaderSize; j++) {
                                    if (null != leaderDTOList && !leaderDTOList.isEmpty() && leaderDTOList.size() > j) {
                                        rowData.add(leaderDTOList.get(j).getLeaderName());
                                        rowData.add(leaderDTOList.get(j).getLeaderTel());
                                    }
                                    // 表示无子对象或子对象数量不足  需要填空
                                    else {
                                        rowData.add("");
                                        rowData.add("");
                                    }
                                }
                                data.add(rowData);
                            }
                        }
                    }
                    // 创建单元格样式
                    XSSFCellStyle cellStyle03 = createCellStyle(workbook, "微软雅黑", (short) 12, false, true);
                    int temp = StringUtils.isNotBlank(title) ? 4 : 3;
                    // for循环处理
                    int dataSize = data.size();
                    for (int i = 0; i < dataSize; i++) {
                        XSSFRow row = sheet.createRow(i + temp);
                        int sizeForData = data.get(i).size();
                        for (int j = 0; j < sizeForData; j++) {
                            XSSFCell cell = row.createCell(j);
                            Object value = data.get(i).get(j);
                            cell.setCellValue(value == null ? "" : value.toString());
                            cell.setCellStyle(cellStyle03);
                        }
                    }
                    // 合并 有多行物业构成情况 单元格
                    if (!list.isEmpty()) {
                        // 已占行数
                        int rowExist = 4;
//                        int sizeList = end - start;
                        for (int i = start; i < end; i++) {
                            int propertySize = list.get(i).getPropertyCompositionDTOS().size();
                            if (propertySize > 1) {
                                for (int j = 0; j < propertyCol; j++) {
                                    sheet.addMergedRegion(setCellRangAddress(rowExist, rowExist + propertySize - 1, j, j, cellRangeAddress));
                                }
                                int sizeDataGet = data.get(0).size();
                                for (int j = propertyCol + 5; j < sizeDataGet + 5; j++) {
                                    sheet.addMergedRegion(setCellRangAddress(rowExist, rowExist + propertySize - 1, j, j, cellRangeAddress));
                                }
                                rowExist += propertySize;
                            } else {
                                rowExist++;
                            }
                        }
                    }
                    // 合计
                    XSSFRow row = sheet.createRow(dataSize + temp);
                    for (int i = 0; i < size; i++) {
                        XSSFCell cell = row.createCell(i);
                        cell.setCellStyle(cellStyle);
                    }
                    XSSFCell cell = row.createCell(0);
                    cell.setCellValue("合计");
                    cell.setCellStyle(cellStyle);
//            // 规划户数
                    Integer number = mergeMap.get("规划户数");
                    mergeSum(row, number, cellStyle, planNumberMergeData);

                    // 合同签约面积
                    mergeSum(row, number + 1, cellStyle, contractAreaMergeData);
                    // 可收费面积
                    mergeSum(row, number + 3, cellStyle, ratesAreaMergeData);
                    // 月饱和收入
                    mergeSum(row, number + 5, cellStyle, monthIncomeMergeData);
                    // 年饱和收入
                    mergeSum(row, number + 6, cellStyle, yearIncomeMergeData);

                    // 第一年 主营收入
                    mergeSum(row, number + 8, cellStyle, firstSalesRevenueMergeData);
                    // 第一年 主营利润
                    mergeSum(row, number + 8 + 1, cellStyle, firstMainBusinessProfitMergeData);
                    // 第一年 补贴
                    mergeSum(row, number + 8 + 2, cellStyle, firstSubsidyMergeData);
                    // 第一年 总成本
                    mergeSum(row, number + 8 + 3, cellStyle, firstTotalCostMergeData);
                    // 第二年 主营收入
                    mergeSum(row, number + 14, cellStyle, secondSalesRevenueMergeData);
                    // 第二年 主营利润
                    mergeSum(row, number + 14 + 1, cellStyle, secondMainBusinessProfitMergeData);
                    // 第二年 补贴
                    mergeSum(row, number + 14 + 2, cellStyle, secondSubsidyMergeData);
                    // 第二年 总成本
                    mergeSum(row, number + 14 + 3, cellStyle, secondTotalCostMergeData);
                    // 第三年 主营收入
                    mergeSum(row, number + 20, cellStyle, thirdlySalesRevenueMergeData);
                    // 第三年 主营利润
                    mergeSum(row, number + 20 + 1, cellStyle, secondMainBusinessProfitMergeData);
                    // 第三年 补贴
                    mergeSum(row, number + 20 + 2, cellStyle, thirdlySubsidyMergeData);
                    // 第三年 总成本
                    mergeSum(row, number + 20 + 3, cellStyle, thirdlyTotalCostMergeData);
                }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            countDownLatch.countDown();
        }

    }


    // 设置单元格格式
    private CellRangeAddress setCellRangAddress(int firstRow, int lastRow, int firstCol, int lastCol, CellRangeAddress cellRangeAddress) {
        cellRangeAddress.setFirstRow(firstRow);
        cellRangeAddress.setLastRow(lastRow);
        cellRangeAddress.setFirstColumn(firstCol);
        cellRangeAddress.setLastColumn(lastCol);
        return cellRangeAddress;
    }

    private XSSFCellStyle createCellStyle(XSSFWorkbook workbook, String fontName, short fontSize,
                                          boolean isBlod, boolean isBorder) {
        // 通过工作簿创建样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        // 设置水平和垂直居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        if (isBorder) {
            cellStyle.setBorderBottom(BorderStyle.THIN); // 下边框
            cellStyle.setBorderLeft(BorderStyle.THIN);// 左边框
            cellStyle.setBorderTop(BorderStyle.THIN);// 上边框
            cellStyle.setBorderRight(BorderStyle.THIN);// 右边框
        }
        // 通过工作簿创建字体
        XSSFFont font = workbook.createFont();
        // 设置字体
        if (null != fontName && !"".equals(fontName)) {
            font.setFontName(fontName);
        }
        // 设置字体大小
        font.setFontHeightInPoints(fontSize);
        // 设置字体是否加粗
        font.setBold(isBlod);
        // 把字体set到样式中
        cellStyle.setFont(font);

        return cellStyle;
    }

    private void mergeSum(XSSFRow row, int number, XSSFCellStyle cellStyle, Map<Long, BigDecimal> params) {
        XSSFCell cell = row.createCell(number);
        cell.setCellStyle(cellStyle);
        BigDecimal sum = new BigDecimal(0);
        for (Long aLong : params.keySet()) {
            if (params.get(aLong) != null) {
                sum = sum.add(params.get(aLong));
            }
        }
        cell.setCellValue(sum.toString());
    }

}
