package digital.laboratory.platform.inspection.service.impl;
/*
 *@title TaskInfoServiceImpl
 *@description
 *@author xy
 *@version 1.0
 *@create 2023/12/8 11:10
 */

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.data.ChartSingleSeriesRenderData;
import com.deepoove.poi.data.Charts;
import digital.laboratory.platform.api.dto.UploadHairJobDTO;
import digital.laboratory.platform.api.dto.UploadSewageJobDTO;
import digital.laboratory.platform.api.entity.UploadHairJobDetailLite;
import digital.laboratory.platform.api.entity.UploadSewageJobDetailLite;
import digital.laboratory.platform.api.feign.RemoteUploadService;
import digital.laboratory.platform.common.core.constant.CommonConstants;
import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.feign.RemoteGenerateWordService;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspetion.api.enums.BusinessType;
import digital.laboratory.platform.inspection.enums.SewageReportColumn;
import digital.laboratory.platform.inspection.dto.*;
import digital.laboratory.platform.inspection.entity.AssignmentInfo;
import digital.laboratory.platform.inspection.entity.TaskInfo;
import digital.laboratory.platform.inspection.mapper.TaskInfoMapper;
import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper;
import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspetion.api.entity.MaterialDto;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.sewage.feign.RemoteSewageJobIdentificationMaterialService;
import digital.laboratory.platform.sewage.vo.SewageJobIdentificationMaterialVO;
import digital.laboratory.platform.sys.feign.RemoteDictionaryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@SuppressWarnings("all")
public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> implements TaskInfoService {

    @Resource
    private SampleInfoService sampleInfoService;

    @Resource
    private AssignmentInfoService assignmentInfoService;

    @Resource
    private TestRecordSampleDataService testRecordSampleDataService;

    @Resource
    private TestRecordSampleSolutionService testRecordSampleSolutionService;

    @Resource
    private TestRecordSampleDataMapper testRecordSampleDataMapper;

    @Resource
    private RemoteUploadService remoteUploadService;

    @Resource
    private RemoteDictionaryService remoteDictionaryService;

    @Resource
    private RemoteGenerateWordService remoteGenerateWordService;

    @Resource
    private RemoteSewageJobIdentificationMaterialService remoteSewageJobIdentificationMaterialService;

    @Resource
    private TestRecordInstrumentConditionService testRecordInstrumentConditionService;

    @Resource
    private OssFile ossFile;

    /**
     * 根据目标任务的开始时间进行排序 取4个任务的id
     *
     * @param targetTask
     * @return
     */
    @Override
    public List<TaskInfo> getTaskIdByOrderStartTimeLimit4(TaskInfo targetTask) {
        List<TaskInfo> list = this.list(Wrappers.<TaskInfo>lambdaQuery()
                .ne(TaskInfo::getOriginalId, "")
                .isNotNull(TaskInfo::getOriginalId)
                .lt(TaskInfo::getTaskStartDate, targetTask.getTaskStartDate())
                .orderByDesc(TaskInfo::getTaskStartDate)
                .last("limit 4")
        );

        return list;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public TaskInfo addTaskInfo(TaskInfoDto taskInfo) {
        String businessType = taskInfo.getBusinessType();
        if (businessType.equals("污水任务鉴定")) {
            taskInfo.setBusinessType("20002");
        } else {
            taskInfo.setBusinessType("20001");
        }
        String originalId = taskInfo.getOriginalId();
        //判断是否是从其他系统读取过来的数据
        if (StringUtils.isNotBlank(originalId)) {
            TaskInfo info = this.getOne(Wrappers.<TaskInfo>lambdaQuery().eq(TaskInfo::getOriginalId, originalId));
            //判断是否已经添加至本系统
            if (ObjectUtils.isNotNull(info)) {
                int index = 0;
                //已经添加过来了，update即可
                taskInfo.setId(info.getId());
                List<MaterialDto> materialList = taskInfo.getMaterialList();
                String distributionSituation = info.getDistributionSituation();

                //获取检材信息
                if (materialList != null && materialList.size() > 0) {
                    List<SampleInfo> oldSampleInfoList = sampleInfoService.list(Wrappers.<SampleInfo>lambdaQuery().eq(SampleInfo::getBusinessId, info.getId()));
                    List<SampleInfo> newSampleInfoList = new ArrayList<>();
                    List<String> oldSampleNoList = new ArrayList<>();
                    //获取已读取的检材信息
                    if (oldSampleInfoList != null && oldSampleInfoList.size() > 0) {
                        oldSampleInfoList.forEach(item -> oldSampleNoList.add(item.getAcceptNo()));
                    }
                    //去重处理
                    if (oldSampleNoList.size() > 0) {
                        for (MaterialDto material : materialList) {
                            if (taskInfo.getBusinessType().equals("20001")) {
                                material.setImNo(material.getSampleCode());
                            }
                            if (!oldSampleNoList.contains(material.getImNo())) {
                                SampleInfo sampleInfo = new SampleInfo();
                                sampleInfoService.copy(sampleInfo, material, 1);
                                sampleInfo.setBusinessType(taskInfo.getBusinessType());
                                sampleInfo.setBusinessId(taskInfo.getId());
                                newSampleInfoList.add(sampleInfo);
                                index = index + 1;
                            }
                        }
                    } else {
                        for (MaterialDto material : materialList) {
                            SampleInfo sampleInfo = new SampleInfo();
                            sampleInfoService.copy(sampleInfo, material, 1);
                            sampleInfo.setBusinessType(taskInfo.getBusinessType());
                            sampleInfo.setBusinessId(taskInfo.getId());
                            newSampleInfoList.add(sampleInfo);
                        }
                    }
                    sampleInfoService.saveBatch(newSampleInfoList);
                }
                //修改检材总数
                if (StringUtils.isNotBlank(distributionSituation)) {
                    int prefix = 0;
                    int suffix = 0;
                    String[] split = distributionSituation.split("/");
                    prefix = Integer.parseInt(split[0]);
                    suffix = Integer.parseInt(split[1]);
                    taskInfo.setDistributionSituation(prefix + "/" + (suffix + index));
                }
                this.updateById(taskInfo);
                return taskInfo;
            } else {
                taskInfo.setId(IdWorker.get32UUID().toUpperCase());
                List<MaterialDto> materialList = taskInfo.getMaterialList();
                if (materialList != null && materialList.size() > 0) {
                    List<SampleInfo> newSampleInfoList = new ArrayList<>();
                    for (MaterialDto material : materialList) {
                        if (taskInfo.getBusinessType().equals("20001")) {
                            material.setImNo(material.getSampleCode());
                        }
                        SampleInfo sampleInfo = new SampleInfo();
                        sampleInfoService.copy(sampleInfo, material, 1);
                        sampleInfo.setBusinessType(taskInfo.getBusinessType());
                        sampleInfo.setBusinessId(taskInfo.getId());
                        newSampleInfoList.add(sampleInfo);
                    }
                    sampleInfoService.saveBatch(newSampleInfoList);
                }
                this.save(taskInfo);
                return taskInfo;
            }

        }
        if (StringUtils.isBlank(taskInfo.getId())) {
            taskInfo.setId(IdWorker.get32UUID());
            log.info("保存对象entrustInfo的ID为空，由系统生成一个给它使用 {}", taskInfo.getId());
        }
        boolean ret = this.save(taskInfo);
        if (ret) {
            log.info("{} 保存成功", taskInfo);
            return taskInfo;
        } else {
            log.info("{} 保存失败", taskInfo);
            return null;
        }
    }


    @Override
    public TaskInfo updateTaskInfo(TaskInfo taskInfo) {
//        if (taskInfo.getSource() == 0) {
//            log.info("数据是其他系统推送录入的，不能修改");
//            return null;
//        }
        if (CollUtil.isNotEmpty(taskInfo.getCompoundsJsonArray())) {
            taskInfo.setCompounds(taskInfo.getCompoundsJsonArray().toJSONString());
        }
        boolean ret = this.updateById(taskInfo);
        if (ret) {
            return taskInfo;
        } else {
            return null;
        }
    }

    @Override
    public Boolean deleteTaskInfo(String id) {
        List<AssignmentInfo> assignmentInfos = assignmentInfoService.list(Wrappers.<AssignmentInfo>lambdaQuery().eq(AssignmentInfo::getBusinessId, id));
        if (assignmentInfos.size() > 0) {
            throw new RuntimeException(String.format("当前业务已被分配，无法删除!"));
        }
        return this.removeById(id);
    }

    @Override
    public IPage getTaskPageList(Page page, TaskInfo taskInfo, String keywords) {
        IPage ret = this.page(page, Wrappers.<TaskInfo>lambdaQuery()
                .like(StringUtils.isNotBlank(keywords), TaskInfo::getTaskName, keywords)
                .orderByDesc(TaskInfo::getCreateTime));
        List<TaskInfo> records = ret.getRecords();
        for (TaskInfo info : records) {
            List<AssignmentInfo> list = assignmentInfoService.list(Wrappers.<AssignmentInfo>lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId()));
            if (list.size() > 0) {
                info.setIsDistribution(true);
            } else {
                info.setIsDistribution(false);
            }
            if (info.getBusinessType().equals("20001")) {
                info.setBusinessTypeName("毛发任务");
            } else {
                info.setBusinessTypeName("污水任务");
            }
        }
        return ret;
    }

    @Override
    public List<TaskInfo> getTaskList(TaskInfo taskInfo, String keywords) {
        List<TaskInfo> retList = this.list(Wrappers.<TaskInfo>lambdaQuery()
                .like(StringUtils.isNotBlank(keywords), TaskInfo::getTaskName, keywords)
                .eq(StringUtils.isNotBlank(taskInfo.getId()), TaskInfo::getId, taskInfo.getId())
                .orderByDesc(TaskInfo::getCreateTime));
        for (TaskInfo info : retList) {
            List<AssignmentInfo> list = assignmentInfoService.list(Wrappers.<AssignmentInfo>lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId()));
            if (list.size() > 0) {
                info.setIsDistribution(true);
            } else {
                info.setIsDistribution(false);
            }
            if (info.getBusinessType().equals("20001")) {
                info.setBusinessTypeName("毛发任务");
            } else {
                info.setBusinessTypeName("污水任务");
            }
        }
        return retList;
    }

    @Override
    public Boolean checkExist(String id) {
        List<TaskInfo> retList = this.list(Wrappers.<TaskInfo>lambdaQuery()
                .eq(TaskInfo::getId, id));
        if (retList.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void createUploadItem(List<String> sampleNos) {
        List<TaskTestDataDTO> taskTestDataDTOList = testRecordSampleDataMapper.
                queryWaitApproveTaskTestDataList(Wrappers.<TaskTestDataDTO>query()
                        .in("ss.sample_no", sampleNos));
        // 获取当前数据的业务类型 毛发还是污水
        String businessType = taskTestDataDTOList.get(0).getBusinessType();
        //获取对应样本溶液编号的实验数据，按检材编号进行分组
        Map<String, List<TaskTestDataDTO>> map = taskTestDataDTOList
                .stream().collect(Collectors.groupingBy(item -> item.getAcceptNo()));

        if (businessType.equals(BusinessType.BOINT_JOB.getBusinessType())) {
            getUploadHairJobDTOS(map);
        } else {
            getUploadSewageJobDTOS(map);
        }

    }

    /**
     * 导出污水专项检测毒品分析报告
     *
     * @param dto
     * @return
     */
    @Override
    public R exportSewageAnalystReports(ExportSewageAnalystReportsDTO dto) {


//        String yearMonth = dto.getMonth().format(DateTimeFormatter.ofPattern("yyyy年MM月"));
        // 目前字典中的单位名称不统一，这里暂时写死，后期在改
        String organization = "国家毒品实验室陕西分中心";
        String generateDate = LocalDate.now().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日"));
        String province = dto.getProvinceName();
        R<List<SewageJobIdentificationMaterialVO>> voListByJobIdR = remoteSewageJobIdentificationMaterialService.getSewageJobIdentificationMaterialVOListByJobId(dto.getJobId());
        if (voListByJobIdR.getCode() == CommonConstants.FAIL) {
            log.error("根据任务id 获取检材失败！");
            return R.failed("根据任务id 获取检材失败！");
        }
        List<SewageJobIdentificationMaterialVO> data = voListByJobIdR
                .getData()
                .stream()
                .filter(vo ->
                        vo.getProvinceName()
                                .equals(dto.getProvinceName()) && vo.getAcceptTime() != null)  // 根据省编码筛选
                .collect(Collectors.toList());
        // 使用stream 流进行排序
        List<SewageJobIdentificationMaterialVO> dateSortedByAcceptTime = data.stream()
                .sorted((d1, d2) -> d1.getAcceptTime().compareTo(d2.getAcceptTime()))
                .collect(Collectors.toList());
        List<SewageJobIdentificationMaterialVO> dateSortedByCollectTime = data.stream()
                .sorted((d1, d2) -> d1.getCollectTime().compareTo(d2.getCollectTime()))
                .collect(Collectors.toList());
        String collectDate1 = dateSortedByAcceptTime.get(0).getAcceptTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日"));
        String collectDate2 = dateSortedByAcceptTime.get(dateSortedByAcceptTime.size() - 1).getAcceptTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日"));

        String samplingDate1 = dateSortedByCollectTime.get(0).getCollectTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日"));
        String samplingDate2 = dateSortedByCollectTime.get(dateSortedByCollectTime.size() - 1).getCollectTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日"));
        int materialNum = data.size(); // 本次样本数量

        // 常见的毒品及其代谢物 （先取检验鉴定中的样本表的目标物）和  TODO 人口标记物 还不知道怎么查
        List<String> noList = data.stream().map(SewageJobIdentificationMaterialVO::getImNo).collect(Collectors.toList());
        // 查询检验鉴定的样本表
        List<SampleInfo> sampleInfoList = sampleInfoService.list(Wrappers.<SampleInfo>lambdaQuery().in(SampleInfo::getAcceptNo, noList));
        // 取所有的筛查物 列表
//        Set<String> targetObjectSet = new HashSet<>();
//        for (SampleInfo sampleInfo : sampleInfoList) {
//            // 获取这个检材的筛查物列表
//            List<TargetObject> targetObjectList = sampleInfo.getTargetObject();
//            for (TargetObject targetObject : targetObjectList) {
//                targetObjectSet.add(targetObject.getName());
//            }
//        }
        String commonDrugAndMetabolite = "甲基苯丙胺、苯丙胺（甲基苯丙胺代谢物）；" +
                "氯胺酮、去甲氯胺酮（氯胺酮代谢物）；" +
                "吗啡（海洛因二级代谢产物）、O6-单乙酰吗啡（海洛因一级代谢产物）；" +
                "可待因；" +
                "可卡因、苯甲酰爱康宁（可卡因代谢物）；" +
                "3,4－亚甲基二氧甲基苯丙胺（摇头丸MDMA）、3,4－亚甲基二氧基苯丙胺（摇头丸代谢物）；" +
                "芬太尼。";
        String populationMarkers = "可替宁（烟草代谢物）";

        // 查询检验数据
        List<DataSolutionSampleDTO> dataSolutionSampleDTOS = testRecordSampleDataMapper.queryDataSolutionSampleDTOList(Wrappers.<DataSolutionSampleDTO>query()
                .in("si.id", sampleInfoList.stream().map(SampleInfo::getId).collect(Collectors.toList())));
        // 筛选出未检出的列表
        List<DataSolutionSampleDTO> undetectedList = dataSolutionSampleDTOS
                .stream()
                .filter(o -> o.getIsDetected() == 0)
                .collect(Collectors.toList());
        // 筛选出检出的列表
        List<DataSolutionSampleDTO> detectedList = dataSolutionSampleDTOS
                .stream()
                .filter(o -> o.getIsDetected() == 1)
                .collect(Collectors.toList());
        // 在根据检出的列表进行分类
        Map<String, List<DataSolutionSampleDTO>> groupByCompoundNameMap = detectedList
                .stream()
                .collect(Collectors.groupingBy(DataSolutionSampleDTO::getCompoundName));
        StringBuilder inspectResultAnalysis = new StringBuilder(); // 报告的检测结果分析
//        String commonDrugConsumeStructureChartInputStream = generateCommonDrugConsumeStructureChart(detectedList, groupByCompoundNameMap, inspectResultAnalysis);
        // 把未检出的数据也拼凑到结果分析中
        inspectResultAnalysis
                .append(
                        undetectedList
                                .stream()
                                .map(DataSolutionSampleDTO::getCompoundName)
                                .collect(Collectors.joining("、"))
                )
                .append("均未检出，暂未发现明显滥用。");

        // 获取陕西省各行政区主要毒品总消费量表数据
        List<RegionalDrugConsumptionDTO> regionalDrugConsumptionDTOList = fetchRegionalDrugConsumption(data);
        // 陕西省各行政区毒品千人均消费量统计图 输入流
//        ByteArrayInputStream drugConsumePerThousandPeopleByRegionChartInputStream = generateDrugConsumePerThousandPeopleByRegionChart(regionalDrugConsumptionDTOList, groupByCompoundNameMap.keySet());
        // 陕西省毒品千人均消费量变化趋势 统计图 输入流
//        generateDrugConsumePerThousandTrendChart();

        Map<String, Object> docMap = new HashMap<>();
        docMap.put("yearMonth", null);
        docMap.put("organization", organization);
        docMap.put("generateDate", generateDate);
        docMap.put("province", province);
        docMap.put("collectDate1", collectDate1);
        docMap.put("collectDate2", collectDate2);
        docMap.put("samplingDate1", samplingDate1);
        docMap.put("samplingDate2", samplingDate2);
        docMap.put("materialNum", materialNum);
        docMap.put("commonDrugAndMetabolite", commonDrugAndMetabolite);
        docMap.put("populationMarkers", populationMarkers);
        ChartSingleSeriesRenderData chartSingleSeriesRenderData = Charts
                .ofSingleSeries("", new String[]{"海洛因", "冰毒", "氯胺酮", "可卡因"})
                .series("", new Number[]{76, 12, 2, 10})
                .create();
        docMap.put("demo", chartSingleSeriesRenderData);

//        docMap.put("commonDrugConsumeStructure", chartSingleSeriesRenderData);
//        try {
//            ChartSingleSeriesRenderData chartSingleSeriesRenderData = Charts.ofPie("", new String[]{"海洛因", "冰毒", "氯胺酮", "可卡因"})
//                    .series("", new Number[]{76, 12, 2, 10}).create();
//            docMap.put("commonDrugConsumeStructure", chartSingleSeriesRenderData);
//            docMap.put("commonDrugConsumeStructure",
//                    new ImageEntity(commonDrugConsumeStructureChartInputStream, 450, 265));

//        } catch (Exception e) {
//            e.printStackTrace();
//            log.error(e.getMessage());
//        }
        docMap.put("abuseContent", inspectResultAnalysis.toString());
        docMap.put("regionalDrugConsumptionDTOList", regionalDrugConsumptionDTOList);

        String templatePath = OSSDirectoryConstants.DOCUMENT_SEWAGE_REPORTS_DIRECTORY + "/" + dto.getJobId() + "/" + "污水样品毒品检测分析报告-";
        String templateName = "污水样品毒品检测分析报告模板.docx";
        String fileType = ".docx";
        String originalFilename = "污水样品毒品检测分析报告-";
        List<String> listNameCollection = new ArrayList<>();
        listNameCollection.add("abuseStatusList");
        listNameCollection.add("regionalDrugConsumptionDTOList");
        R r = remoteGenerateWordService.generateWord(templateName, originalFilename, templatePath, fileType, null, listNameCollection, false, docMap);

        return null;
    }


    /**
     * 获取陕西省各行政区主要毒品总消费量表数据 列表
     *
     * @param data
     * @return
     */
    private List<RegionalDrugConsumptionDTO> fetchRegionalDrugConsumption(List<SewageJobIdentificationMaterialVO> data) {

        List<RegionalDrugConsumptionDTO> regionalDrugConsumptionDTOS = new ArrayList<>();

        List<SewageDataDto> sewageDataDtos = processSewageDataDtos(5.19, data);
        // 根据市级编码 分组
        Map<String, List<SewageDataDto>> sewageDataGroupByMap = sewageDataDtos
                .stream()
                .collect(Collectors
                        .groupingBy(SewageDataDto::getCityName));

        sewageDataGroupByMap.forEach((k, v) -> {
            RegionalDrugConsumptionDTO dto = getRegionalDrugConsumptionDTO(v);
            regionalDrugConsumptionDTOS.add(dto);
        });
        // TODO 全省平均/总计 计算方式目前还不清楚
        regionalDrugConsumptionDTOS.add(getAllProvinceAvgAndSumDataDTO(regionalDrugConsumptionDTOS));

        return regionalDrugConsumptionDTOS;
    }

    /**
     * 获取全省各种毒品的千人均消费量平均值和总消费量
     *
     * @param regionalDrugConsumptionDTOS
     * @return
     */
    private RegionalDrugConsumptionDTO getAllProvinceAvgAndSumDataDTO(List<RegionalDrugConsumptionDTO> regionalDrugConsumptionDTOS) {
        // 这部分是先计算全省各毒品平均消耗量
        double allProvinceHeroinAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccHeroin()));
        double allProvinceCocAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccCoc()));
        double allProvinceKAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccK()));
        double allProvinceMaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMa()));
        double allProvinceMdmaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMdma()));
        double allProvincePccTotalAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccTotal()));
        // 全省各毒品的总消耗量
        double allProvinceHeroinTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcHeroin()));
        double allProvinceMaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMa()));
        double allProvinceKTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcK()));
        double allProvinceMdmaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMdma()));
        double allProvinceCocTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcCoc()));
        double allProvinceTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcTotal()));

        // 对小数进行保留1位小数的操作
        DecimalFormat df = new DecimalFormat("#.#");
        RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO();
        dto.setRegional("全省平均/总计");
        // 平均
        dto.setPccHeroin(df.format(allProvinceHeroinAvg));
        dto.setPccMdma(df.format(allProvinceMdmaAvg));
        dto.setPccK(df.format(allProvinceKAvg));
        dto.setPccMa(df.format(allProvinceMaAvg));
        dto.setPccCoc(df.format(allProvinceCocAvg));
        dto.setPccTotal(df.format(allProvincePccTotalAvg));

        // 总计
        dto.setTcHeroin(df.format(allProvinceHeroinTotalSum));
        dto.setTcMdma(df.format(allProvinceMdmaTotalSum));
        dto.setTcCoc(df.format(allProvinceCocTotalSum));
        dto.setTcMa(df.format(allProvinceMaTotalSum));
        dto.setTcK(df.format(allProvinceKTotalSum));
        dto.setTcTotal(df.format(allProvinceTotalSum));

        return dto;
    }

    /**
     * 全省各毒品平均消耗量
     *
     * @param regionalDrugConsumptionDTOS
     * @param mapper
     * @return
     */
    private double calculateAverage(List<RegionalDrugConsumptionDTO> regionalDrugConsumptionDTOS, Function<RegionalDrugConsumptionDTO, Double> mapper) {
        return regionalDrugConsumptionDTOS.stream()
                .mapToDouble(mapper::apply)
                .average()
                .orElse(0.0);
    }

    /**
     * 全省各毒品总消耗量
     *
     * @param regionalDrugConsumptionDTOS
     * @param mapper
     * @return
     */
    private double calculateConsumeSum(List<RegionalDrugConsumptionDTO> regionalDrugConsumptionDTOS, Function<RegionalDrugConsumptionDTO, Double> mapper) {
        return regionalDrugConsumptionDTOS.stream().mapToDouble(mapper::apply).sum();
    }

    /**
     * 获取各行政区主要毒品总消费量 数据传输对象
     *
     * @param v
     * @return
     */
    private RegionalDrugConsumptionDTO getRegionalDrugConsumptionDTO(List<SewageDataDto> v) {
        // 对小数进行保留1位小数的操作
        DecimalFormat df = new DecimalFormat("#.#");

        RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO();
        SewageDataDto sewageDataDto = v.get(0);
        dto.setRegional(sewageDataDto.getCityName()); // 城市名称
        // 总测算人口
        double estimatedPopulationSum = v.stream().mapToDouble(SewageDataDto::getEstimatedPopulation).sum();
        // 各类毒品的总消耗量
        double pccHeroinSum = v.stream().mapToDouble(SewageDataDto::getPccHeroin).sum();
        double pccMaSum = v.stream().mapToDouble(SewageDataDto::getPccMa).sum();
        double pccKSum = v.stream().mapToDouble(SewageDataDto::getPccK).sum();
        double pccMdmaSum = v.stream().mapToDouble(SewageDataDto::getPccMdma).sum();
        double pccCocSum = v.stream().mapToDouble(SewageDataDto::getPccCoc).sum();
        double tcTotal = pccKSum + pccMaSum + pccHeroinSum + pccMdmaSum + pccCocSum;
        // 总消费量（克/天）, 因为算出来的单位是毫克，所以这里需要除以1000， 综合
        dto.setTcTotal(df.format(tcTotal / 1000));
        dto.setTcHeroin(df.format(pccHeroinSum / 1000));
        dto.setTcMa(df.format(pccMaSum / 1000));
        dto.setTcK(df.format(pccKSum / 1000));
        dto.setTcMdma(df.format(pccMdmaSum / 1000));
        dto.setTcCoc(df.format(pccCocSum / 1000));

        // 千人均消费量（毫克/千人/天）
        double pccHeroin = pccHeroinSum / estimatedPopulationSum;
        double pccK = pccKSum / estimatedPopulationSum;
        double pccCoc = pccCocSum / estimatedPopulationSum;
        double pccMa = pccMaSum / estimatedPopulationSum;
        double pccMdma = pccMdmaSum / estimatedPopulationSum;
        double pccTotal = pccCoc + pccHeroin + pccCoc + pccMa + pccMdma;
        dto.setPccHeroin(df.format(pccHeroin));
        dto.setPccK(df.format(pccK));
        dto.setPccCoc(df.format(pccCoc));
        dto.setPccMa(df.format(pccMa));
        dto.setPccMdma(df.format(pccMdma));
        dto.setPccTotal(df.format(pccTotal));
        return dto;
    }

//    /**
//     * 生成常用毒品消费结构图， 返回其输入流
//     *
//     * @param detectedList
//     * @param groupByCompoundNameMap
//     * @param inspectResultAnalysis  通过引用来获取值
//     * @return
//     */
//    private String generateCommonDrugConsumeStructureChart(List<DataSolutionSampleDTO> detectedList,
//                                                           Map<String, List<DataSolutionSampleDTO>> groupByCompoundNameMap,
//                                                           StringBuilder inspectResultAnalysis) {
//        String masterDrug = ""; // 主要毒品
//        String secondlyDrug = ""; // 其次毒品
//
//        int size = detectedList.size();
//        // 图例名称
//        List<String> legendList = new ArrayList<>(groupByCompoundNameMap.keySet());
//        List<Object> dataList = new ArrayList<>();
//        // 图表背景
//        List<java.awt.Color> colorList = randomGetColorList(legendList.size());
//        // 偏离百分比数据
//        List<Double> explodePercentList = new ArrayList<>();
//        for (String key : legendList) {
//            List<DataSolutionSampleDTO> dataSolutionSampleDTOS = groupByCompoundNameMap.get(key);
//            // 对小数进行保留两位小数的操作
//            DecimalFormat df = new DecimalFormat("#.##");
//            double percent = (dataSolutionSampleDTOS.size() / (double) size) * 100;
//            dataList.add(df.format(percent));
//            // 设置偏离百分比
//            explodePercentList.add(0.01);
//            // 大于10%的为主要毒品
//            if (percent > 10) {
//                if (StrUtil.isNotBlank(masterDrug)) {
//                    masterDrug = "主要毒品为" + key;
//                } else {
//                    masterDrug = masterDrug + "、" + key;
//                }
//            } else {
//                if (StrUtil.isNotBlank(secondlyDrug)) {
//                    secondlyDrug = "其次为" + key;
//                } else {
//                    secondlyDrug = secondlyDrug + "、" + key;
//                }
//            }
//        }
//
//        // 合成最终的检测结果分析
//        inspectResultAnalysis
//                .append(masterDrug)
//                .append("，")
//                .append(secondlyDrug)
//                .append("。");
//
//        // 创建输出流
//        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        JFreeChart chart = null;
//        try {
////            GeneratePieChartUtil.createPieChart(
////                    byteArrayOutputStream,
////                    "",
////                    legendList,
////                    dataList,
////                    450,
////                    265,
////                    JFreeChartUtil.createChartTheme("宋体"),
////                    colorList,
////                    explodePercentList);
//            chart = GeneratePieChartUtil.createPieChart(
//                    "",
//                    legendList,
//                    dataList,
//                    JFreeChartUtil.createChartTheme("宋体"),
//                    colorList,
//                    explodePercentList);
//            File dirFile = new File(ResourceUtils.getURL("classpath:").getPath() +
//                    "chart/" +
//                    LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")) + "/");
//            if (!dirFile.exists()) {
//                dirFile.mkdirs();
//            }
//            String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒")) + "-饼图" + ".png";
//            File file = new File(dirFile.getPath() + "/" + fileName);
//            if (file.exists()) {
//                file.delete();
//            }
//            ChartUtils.saveChartAsPNG(file, chart, 800, 600);
//            return dirFile.getPath() + "/" + fileName;
//        } catch (Exception e) {
//            e.printStackTrace();
//            log.error(e.getMessage());
//        }
//        return null;
////        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
////        return byteArrayOutputStream.toByteArray();
//    }

    /**
     * 获取不同颜色的颜色列表
     *
     * @param count
     * @return
     */
    private List<java.awt.Color> randomGetColorList(int count) {
        Random random = new Random();

        Set<java.awt.Color> colors = new HashSet<>();

        while (colors.size() < count) {
            int red = random.nextInt(256);
            int green = random.nextInt(256);
            int blue = random.nextInt(256);

            java.awt.Color color = new java.awt.Color(red, green, blue);
            colors.add(color);
        }

        log.info("获取的颜色RGB: " + colors.toString());
        return new ArrayList<>(colors);
    }

    /**
     * 推送毛发任务检验数据到上传系统
     *
     * @param map
     * @return
     */
    private List<UploadHairJobDTO> getUploadHairJobDTOS(Map<String, List<TaskTestDataDTO>> map) {
        List<UploadHairJobDTO> uploadHairJobDTOList = new ArrayList<>();
        map.forEach((k, v) -> {
            UploadHairJobDTO uploadHairJobDTO = new UploadHairJobDTO();
            TaskTestDataDTO taskTestDataDTO = v.get(0);
            uploadHairJobDTO.setResultId(taskTestDataDTO.getSampleDataId());
            uploadHairJobDTO.setExperimentId(taskTestDataDTO.getTestId());
            uploadHairJobDTO.setSampleId(taskTestDataDTO.getMaterialId());
            uploadHairJobDTO.setAnalysisTime(LocalDateTimeUtil.format(taskTestDataDTO.getCreateTime(), "yyyy-MM-dd"));
            uploadHairJobDTO.setSampleCode(taskTestDataDTO.getAcceptNo()); // 样品编号
            uploadHairJobDTO.setEquipmentVendor("三重四极杆液质联用仪");
            uploadHairJobDTO.setEquipmentBrand("Waters TQ-S Micro");
            uploadHairJobDTO.setOrganizationName("国家毒品实验室陕西分中心");
            List<UploadHairJobDetailLite> uploadHairJobDetailLiteList = new ArrayList<>();
            // 取出每个检材中检测到的化合物浓度
            for (TaskTestDataDTO testDataDTO : v) {
                UploadHairJobDetailLite uploadHairJobDetailLite = getUploadHairJobDetailLite(testDataDTO);
                uploadHairJobDetailLiteList.add(uploadHairJobDetailLite);
            }
            uploadHairJobDTO.setDetails(uploadHairJobDetailLiteList);

            uploadHairJobDTOList.add(uploadHairJobDTO);
        });

        R hairJobUploadItem = remoteUploadService.createHairJobUploadItem(uploadHairJobDTOList);
        if (hairJobUploadItem.getCode() == CommonConstants.FAIL) {
            log.error("数据推送到上传系统失败！");
            throw new RuntimeException("数据推送到上传系统失败！");
        }

        return uploadHairJobDTOList;
    }

    /**
     * 生成毛发任务详细数据
     *
     * @param testDataDTO
     * @return
     */
    private UploadHairJobDetailLite getUploadHairJobDetailLite(TaskTestDataDTO testDataDTO) {
        UploadHairJobDetailLite uploadHairJobDetailLite = new UploadHairJobDetailLite();
        uploadHairJobDetailLite.setCompound(testDataDTO.getCompoundName());
        uploadHairJobDetailLite.setConcentration(testDataDTO.getSampleConcentration());
        // 检出限和定量限暂时设置
        uploadHairJobDetailLite.setExistLimit(0.01);
        uploadHairJobDetailLite.setLowerLimit(0.02);
        uploadHairJobDetailLite.setStatus(testDataDTO.getIsDetected() == 1 ? "detected" : "noDetected");
        return uploadHairJobDetailLite;
    }

    /**
     * 推送污水的检验数据到上传系统
     *
     * @param map
     * @return
     */
    private List<UploadSewageJobDTO> getUploadSewageJobDTOS(Map<String, List<TaskTestDataDTO>> map) {
        List<UploadSewageJobDTO> uploadSewageJobDTOS = new ArrayList<>();
        Set<String> keySet = map.keySet();
        for (String acceptNo : keySet) {
            UploadSewageJobDTO uploadSewageJobDTO = new UploadSewageJobDTO();
            uploadSewageJobDTO.setSampleCode(acceptNo);
            ArrayList<UploadSewageJobDetailLite> uploadSewageJobDetailLites = new ArrayList<>();
            List<TaskTestDataDTO> taskTestDataDTOS = map.get(acceptNo);
            TaskTestDataDTO dataDTO = taskTestDataDTOS.get(0);
            uploadSewageJobDTO.setResultId(taskTestDataDTOS.get(0).getSampleDataId());
            uploadSewageJobDTO.setExperimentId(taskTestDataDTOS.get(0).getTestId());
            uploadSewageJobDTO.setAnalysisTime(LocalDateTimeUtil.format(dataDTO.getCreateTime(), "yyyy-MM-dd"));
            uploadSewageJobDTO.setEquipmentVendor("三重四极杆液质联用仪");
            uploadSewageJobDTO.setEquipmentBrand("Waters TQ-S Micro");
            uploadSewageJobDTO.setOrganizationName("国家毒品实验室陕西分中心");
            //获得化合物的Map，用来存储大数据平台需要的化合物信息
            Map<String, Double> compoundMap = this.getSewageCompoundMap();
            Set<String> compoundKeySet = compoundMap.keySet();
            List<String> compoundList = new ArrayList<>(compoundKeySet);
            //组装上传数据的内容
            for (TaskTestDataDTO taskTestDataDTO : taskTestDataDTOS) {
                String compoundName = taskTestDataDTO.getCompoundName().toLowerCase();
                //如果检验数据属于大数据平台要求上传的数据，那么就将检验出来的浓度赋值过去
                if (compoundKeySet.contains(compoundName)) {
                    compoundMap.put(compoundName, taskTestDataDTO.getSampleConcentration());
                }
            }
            //根据大数据平台要求的化合物来封装数据对象
            for (String compoundName : compoundList) {
                UploadSewageJobDetailLite uploadSewageJobDetailLite = new UploadSewageJobDetailLite();
                uploadSewageJobDetailLite.setCompound(compoundName);
                uploadSewageJobDetailLite.setConcentration(compoundMap.get(compoundName));
                uploadSewageJobDetailLites.add(uploadSewageJobDetailLite);
            }
            uploadSewageJobDTO.setDetails(uploadSewageJobDetailLites);
            uploadSewageJobDTOS.add(uploadSewageJobDTO);
        }
        remoteUploadService.createUploadItem(uploadSewageJobDTOS);
        return uploadSewageJobDTOS;
    }

    //获得大数据平台要求的污水数据的化合物Map
    public Map<String, Double> getSewageCompoundMap() {
        Map<String, Double> map = new HashMap<>();
        map.put("cot", 0.0);
        map.put("cod", 0.0);
        map.put("mda", 0.0);
        map.put("mdma", 0.0);
        map.put("coc", 0.0);
        map.put("bze", 0.0);
        map.put("mor", 0.0);
        map.put("o6", 0.0);
        map.put("ma", 0.0);
        map.put("am", 0.0);
        map.put("k", 0.0);
        map.put("nk", 0.0);
        map.put("thc", 0.0);
        return map;
    }

    @Override
    public List<SewageDataDto> createSewageReportData(String taskId, Double dailySmokingPerCapita) {
        TaskInfo taskInfo = this.getById(taskId);
        String originalId = taskInfo.getOriginalId();
        if (!StringUtils.isNotBlank(originalId)) {
            throw new RuntimeException("当前任务不是污水系统推送任务，无法生成报表!");
        }
        R<List<SewageJobIdentificationMaterialVO>> r = remoteSewageJobIdentificationMaterialService.getSewageJobIdentificationMaterialVOListByJobId(originalId);
        List<SewageJobIdentificationMaterialVO> voList = r.getData();

        List<SewageDataDto> sewageDataDtos = processSewageDataDtos(dailySmokingPerCapita, voList);
        return sewageDataDtos;
    }

    /**
     * 根据污水任务检材列表和人均日吸烟 处理报表数据，最后返回数据列表
     *
     * @param dailySmokingPerCapita
     * @param voList
     * @return
     */
    @Override
    public List<SewageDataDto> processSewageDataDtos(Double dailySmokingPerCapita, List<SewageJobIdentificationMaterialVO> voList) {
        List<String> numList = new ArrayList<>();
        voList.forEach(item -> numList.add(item.getImNo()));
        //获得任务中进行实验检材的检出数据
        List<TaskTestDataDTO> taskTestDataDTOList = testRecordSampleDataMapper.
                queryWaitApproveTaskTestDataList(Wrappers.<TaskTestDataDTO>query()
                        .in("ss.sample_no", numList));

        Map<String, List<TaskTestDataDTO>> map = taskTestDataDTOList.stream().collect(Collectors.groupingBy(item -> item.getAcceptNo()));//按照检材编号生成的Map
        Set<String> keySet = map.keySet();
        List<SewageDataDto> sewageDataDtos = new ArrayList<>();
        //遍历每个检材，为检材添加化合物检测信息
        for (String key : keySet) {
            SewageDataDto sewageDataDto = new SewageDataDto();
            for (SewageJobIdentificationMaterialVO vo : voList) {
                if (vo.getImNo().equals(key)) {
                    BeanUtils.copyProperties(vo, sewageDataDto);
                    sewageDataDto.setDailySmokingPerCapita(dailySmokingPerCapita);
                }
            }

            List<TaskTestDataDTO> taskTestDataDTOS = map.get(key);//同一编号的一组化合物数据
            HashMap<String, Double> compoundMap = new HashMap<>();
            taskTestDataDTOS.forEach(item -> {
                compoundMap.put(item.getCompoundName().toLowerCase(), item.getSampleConcentration());
            });//把化合物的名称与浓度封装到map中
            sewageDataDto.setCotinineConcentration(compoundMap.get("cot") != null ? compoundMap.get("cot") : 0d);//可替宁
            sewageDataDto.setCodeineConcentration(compoundMap.get("codeine") != null ? compoundMap.get("codeine") : 0d);//可待因
            sewageDataDto.setMdaConcentration(compoundMap.get("mda") != null ? compoundMap.get("mda") : 0d);//mad
            sewageDataDto.setMdmaConcentration(compoundMap.get("mdma") != null ? compoundMap.get("mdma") : 0d);//mdma
            sewageDataDto.setCocaineConcentration(compoundMap.get("cocaine") != null ? compoundMap.get("cocaine") : 0d);//可卡因
            sewageDataDto.setBenzoylecgonineConcentration(compoundMap.get("benzoylecgonine") != null ? compoundMap.get("benzoylecgonine") : 0d);//苯甲酰爱康宁
            sewageDataDto.setMorphineConcentration(compoundMap.get("morphine") != null ? compoundMap.get("morphine") : 0d);//吗啡
            sewageDataDto.setAcetylmorphineConcentration(compoundMap.get("6-acetylmorphine") != null ? compoundMap.get("6-acetylmorphine") : 0d);//O6-单乙酰吗啡
            sewageDataDto.setMethamphetamineConcentration(compoundMap.get("methamphetamine") != null ? compoundMap.get("methamphetamine") : 0d);//甲基苯丙胺
            sewageDataDto.setAmphetamineConcentration(compoundMap.get("amphetamine") != null ? compoundMap.get("amphetamine") : 0d);//苯丙胺
            sewageDataDto.setKetamineConcentration(compoundMap.get("ketamine") != null ? compoundMap.get("ketamine") : 0d);//氯胺酮
            sewageDataDto.setNorketamineConcentration(compoundMap.get("norketamine") != null ? compoundMap.get("norketamine") : 0d);//去甲氯胺酮
            sewageDataDto.setThcConcentration(compoundMap.get("thc") != null ? compoundMap.get("thc") : 0d);//四氢大麻酸
            sewageDataDto.setFenConcentration(compoundMap.get("fentanyl") != null ? compoundMap.get("fentanyl") : 0d);//芬太尼
            sewageDataDto.setEtomidateConcentration(compoundMap.get("etomidate") != null ? compoundMap.get("etomidate") : 0d);//依托咪酯

//            for (TaskTestDataDTO taskTestDataDTO : taskTestDataDTOS) {
//                switch (taskTestDataDTO.getCompoundName().toLowerCase()) {
//                    case "cot":
//                    case "cotinine": {
//                        sewageDataDto.setCotinineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "codeine": {
//                        sewageDataDto.setCodeineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "mda": {
//                        sewageDataDto.setMdaConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "mdma": {
//                        sewageDataDto.setMdmaConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "cocaine": {
//                        sewageDataDto.setCocaineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "benzoylecgonine": {
//                        sewageDataDto.setBenzoylecgonineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "morphine": {
//                        sewageDataDto.setMorphineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "6-acetylmorphine": {
//                        sewageDataDto.setAcetylmorphineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "methamphetamine": {
//                        sewageDataDto.setMethamphetamineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "amphetamine": {
//                        sewageDataDto.setAmphetamineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "ketamine": {
//                        sewageDataDto.setKetamineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "norketamine": {
//                        sewageDataDto.setNorketamineConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "thc": {
//                        sewageDataDto.setThcConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "fentanyl": {
//                        sewageDataDto.setFenConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                    case "etomidate": {
//                        sewageDataDto.setEtomidateConcentration(taskTestDataDTO.getSampleConcentration());
//                        break;
//                    }
//                }
//            }
            calculatedConsumption(sewageDataDto, dailySmokingPerCapita);
            sewageDataDtos.add(sewageDataDto);
        }
        return sewageDataDtos;
    }

    /**
     * 把计算消费量的方法封装一下，此时sewageDataDto中已经保存了检验鉴定系统检出的化合物数据，此方法是用来计算消费量的
     *
     * @param sewageDataDto
     * @param dailySmokingPerCapita
     */
    public void calculatedConsumption(SewageDataDto sewageDataDto, Double dailySmokingPerCapita) {
        Double dailyFlow = sewageDataDto.getDailyFlow(); // 当前检材对应的日流
        sewageDataDto.setCotinineExcretion(dailySmokingPerCapita * 0.14 * 1000);//可替宁排泄量
        sewageDataDto.setEstimatedPopulation(sewageDataDto.getCotinineConcentration() * dailyFlow * 10 * sewageDataDto.getDomesticSewageProportion() / 100 / sewageDataDto.getCotinineExcretion());//测算人口

        Double estimatedPopulation = sewageDataDto.getEstimatedPopulation(); // 当前检材对应的测算人口数量， 后面需要频繁使用到这个值，防止后面频繁调用get消耗时间这里提前存在一个变量里
        Double norketamineConcentration = sewageDataDto.getNorketamineConcentration(); // 去甲氯胺酮的浓度
        Double methamphetamineConcentration = sewageDataDto.getMethamphetamineConcentration(); // 甲基苯丙胺浓度
        Double morphineConcentration = sewageDataDto.getMorphineConcentration(); // 吗啡浓度
        Double amphetamineConcentration = sewageDataDto.getAmphetamineConcentration(); // 苯丙胺浓度
        Double ketamineConcentration = sewageDataDto.getKetamineConcentration(); // 氯胺酮浓度
        Double codeineConcentration = sewageDataDto.getCodeineConcentration(); // 可待因 浓度
        Double thcConcentration = sewageDataDto.getThcConcentration(); // 四氢大麻粉浓度
        Double mdmaConcentration = sewageDataDto.getMdmaConcentration(); // 摇头丸mdma浓度
        Double benzoylecgonineConcentration = sewageDataDto.getBenzoylecgonineConcentration(); // 苯甲酰爱康宁 浓度

        sewageDataDto.setMorphineLoad(morphineConcentration == 0.0 ? 0 : morphineConcentration * dailyFlow * 10 / estimatedPopulation);//吗啡负荷量(mg/千人﹒天）
        sewageDataDto.setCodeineLoad(codeineConcentration == 0.0 ? 0 : codeineConcentration * dailyFlow * 10 / estimatedPopulation);//可待因负荷量(mg/千人﹒天）
        sewageDataDto.setCodeineIsConvertedToMorphineLoad(sewageDataDto.getCodeineLoad() * 0.065 / (0.3 * 1.05));//可待因转化为吗啡负荷量(mg/千人﹒天）
        sewageDataDto.setMedicalMorphineLoad(1.0);//医用吗啡负荷量(mg/千人﹒天）

        if (amphetamineConcentration == 0.0) {
            sewageDataDto.setMA_AM(0.0);//MA/AM
        } else {
            sewageDataDto.setMA_AM(methamphetamineConcentration / amphetamineConcentration);//MA/AM
        }
        if (norketamineConcentration == 0.0) {
            sewageDataDto.setK_NK(0.0);//K/NK 除数为0了，我们直接把结果赋为0
        } else {
            sewageDataDto.setK_NK(ketamineConcentration / norketamineConcentration);//K/NK
        }
        sewageDataDto.setPccHeroin((sewageDataDto.getMorphineLoad() - sewageDataDto.getCodeineIsConvertedToMorphineLoad() - sewageDataDto.getMedicalMorphineLoad()) * 3.07);//人均消耗量(mg/千人﹒天）Heroin

        if (amphetamineConcentration == 0.0 || (amphetamineConcentration != 0.0 && sewageDataDto.getMA_AM() <= 20)) {
            sewageDataDto.setPccMa(methamphetamineConcentration == 0.0 ? 0 : methamphetamineConcentration * dailyFlow * 10 * 2.33 / estimatedPopulation);//人均消耗量(mg/千人﹒天）MA
        } else {
            sewageDataDto.setPccMa(amphetamineConcentration == 0.0 ? 0 : amphetamineConcentration * dailyFlow * 10 * 46.6 / estimatedPopulation);//人均消耗量(mg/千人﹒天）MA
        }
        if (norketamineConcentration == 0.0 || (norketamineConcentration != 0.0 && sewageDataDto.getK_NK() <= 6)) {
            sewageDataDto.setPccK(ketamineConcentration == 0 ? 0 : ketamineConcentration * dailyFlow * 10 * 5 / estimatedPopulation);//人均消耗量(mg/千人﹒天）K
        } else {
            sewageDataDto.setPccK(norketamineConcentration == 0 ? 0 : norketamineConcentration * dailyFlow * 10 * 26.6 / estimatedPopulation);//人均消耗量(mg/千人﹒天）K
        }
        sewageDataDto.setPccFen(0d);
        sewageDataDto.setTcFen(0d);

        sewageDataDto.setPccK(ketamineConcentration == 0.0 ? 0 : ketamineConcentration * dailyFlow * 10 * 5 / estimatedPopulation);//人均消耗量(mg/千人﹒天）K
        sewageDataDto.setPccMdma(mdmaConcentration == 0.0 ? 0 : mdmaConcentration * dailyFlow * 10 * 4.44 / estimatedPopulation);//人均消耗量(mg/千人﹒天）MDMA
        sewageDataDto.setPccCoc(benzoylecgonineConcentration == 0.0 ? 0 : benzoylecgonineConcentration * dailyFlow * 10 * 2.33 / estimatedPopulation);//人均消耗量(mg/千人﹒天）COC
        sewageDataDto.setPccThc(thcConcentration == 0.0 ? 0 : thcConcentration * dailyFlow * 10 * 152 / estimatedPopulation);//人均消耗量(mg/千人﹒天）THC
        // 在这里对计算结果为非数值的数据，防止对后续的使用造成影响
        processNaNAndInfinityData(sewageDataDto);
        sewageDataDto.setTcHeroin(sewageDataDto.getPccHeroin() * estimatedPopulation);//总消耗量Heroin
        sewageDataDto.setTcMa(sewageDataDto.getPccMa() * estimatedPopulation);//总消耗量MA
        sewageDataDto.setTcK(sewageDataDto.getPccK() * estimatedPopulation);//总消耗量K
        sewageDataDto.setTcMdma(sewageDataDto.getPccMdma() * estimatedPopulation);//总消耗量MDMA
        sewageDataDto.setTcCoc(sewageDataDto.getPccCoc() * estimatedPopulation);//总消耗量COC
        sewageDataDto.setTcThc(sewageDataDto.getPccThc() * estimatedPopulation);//总消耗量THC
    }

    /**
     * 在这里对计算结果为非数值的数据，防止对后续的使用造成影响 Double.isFinite() 这个的方法作用是判断当前数字是不是在规定的有限数值范围内，是返回true， 不是返回false
     *
     * @param sewageDataDto
     */
    private void processNaNAndInfinityData(SewageDataDto sewageDataDto) {
        if (!Double.isFinite(sewageDataDto.getPccCoc()) || sewageDataDto.getPccCoc() < 0d) {
            sewageDataDto.setPccCoc(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccHeroin()) || sewageDataDto.getPccHeroin() < 0d) {
            sewageDataDto.setPccHeroin(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccK()) || sewageDataDto.getPccK() < 0d) {
            sewageDataDto.setPccK(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccMdma()) || sewageDataDto.getPccMdma() < 0d) {
            sewageDataDto.setPccMdma(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccCoc()) || sewageDataDto.getPccCoc() < 0d) {
            sewageDataDto.setPccMa(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccThc()) || sewageDataDto.getPccThc() < 0d) {
            sewageDataDto.setPccThc(0d);
        }
        if (!Double.isFinite(sewageDataDto.getPccFen()) || sewageDataDto.getPccFen() < 0d) {
            sewageDataDto.setPccFen(0d);
        }
    }

    @Override
    public String createSewageReportExcel(List<SewageDataDto> sewageDataDtos, String id) throws IOException {
        String temporarilyPath = "C:\\tmp\\upload\\";//用来临时存储生成的文件，用于OSS上传，待OSS上传成功后将这个路径下的文件删除
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFCellStyle redCellStyle = workbook.createCellStyle();//表头样式
        HSSFCellStyle cellStyle = workbook.createCellStyle();//表格样式
        HSSFCellStyle redBackdropStyle = workbook.createCellStyle();//红色背景样式
        HSSFCellStyle pinkBackgroundStyle = workbook.createCellStyle();//粉色背景样式

        HSSFFont redBackdropFont = workbook.createFont();
        HSSFFont font = workbook.createFont();
        HSSFFont redFont = workbook.createFont();

        redFont.setFontHeightInPoints((short) 9);
        redFont.setFontName("黑体");
        redFont.setColor(IndexedColors.RED.getIndex());
        redBackdropFont.setFontHeightInPoints((short) 9);
        redBackdropFont.setFontName("黑体");
        redBackdropFont.setColor(IndexedColors.MAROON.getIndex());
        font.setFontName("黑体");
        font.setFontHeightInPoints((short) 9);
        //红色背景填充
        redBackdropStyle.setFillForegroundColor(IndexedColors.CORAL.getIndex());//填充颜色
        redBackdropStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//填充类型
        redBackdropStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        redBackdropStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        //粉色背景填充
        pinkBackgroundStyle.setFillForegroundColor(IndexedColors.TAN.getIndex());
        pinkBackgroundStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        pinkBackgroundStyle.setAlignment(HorizontalAlignment.CENTER);
        pinkBackgroundStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        redCellStyle.setAlignment(HorizontalAlignment.CENTER);
        redCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        cellStyle.setFont(font);
        redCellStyle.setFont(redFont);
        redBackdropStyle.setFont(redBackdropFont);
        pinkBackgroundStyle.setFont(font);


        Map<String, List<SewageDataDto>> map = sewageDataDtos.stream().collect(Collectors.groupingBy(item -> item.getCityName()));//按市名称进行分组
        Set<String> cityNameList = map.keySet();

        //组装每个市检材的数据
        for (String cityName : cityNameList) {
            List<SewageDataDto> sewageDataDtoList = map.get(cityName);
            Collections.sort(sewageDataDtoList, new Comparator<SewageDataDto>() {
                @Override
                public int compare(SewageDataDto o1, SewageDataDto o2) {
                    return o1.getImNo().compareTo(o2.getImNo());
                }
            });
            //工作表名称
            HSSFSheet sheet = workbook.createSheet(sewageDataDtoList.get(0).getJobYear() + "-" + sewageDataDtoList.get(0).getJobSeason() + "-" + cityName.substring(0, cityName.length() - 1));
            for (int i = 0; i < 49; i++) {
                sheet.setColumnWidth(i, 5000);
            }
            //给特殊的单元格设置长一点的宽度
            sheet.setColumnWidth(1, 10000);
            sheet.setColumnWidth(10, 5800);
            sheet.setColumnWidth(26, 5500);
            sheet.setColumnWidth(27, 5800);
            sheet.setColumnWidth(28, 6500);
            sheet.setColumnWidth(29, 6500);
            sheet.setColumnWidth(33, 5500);
            sheet.setColumnWidth(50, 3500);

            //获得表头数据
            List<SewageReportColumn> columns = Arrays.asList(SewageReportColumn.values());

            //开始构建表头
            HSSFRow row0 = sheet.createRow(0);//创建第一行
            row0.setHeight((short) 1200);
            for (int i = 0; i < columns.size(); i++) {
                HSSFCell cell = row0.createCell(i);
                //有些列字体颜色会有变化，且会有背景填充，这边将逻辑写在枚举类中，用于传入单独的style样式
                SewageReportColumn sewageReportColumn = columns.get(i);
                if (sewageReportColumn.getBackgroundColor().equals("red")) {
                    cell.setCellStyle(redBackdropStyle);
                } else if (sewageReportColumn.getBackgroundColor().equals("pink")) {
                    cell.setCellStyle(pinkBackgroundStyle);
                } else if (sewageReportColumn.getFontColor().equals("red") && sewageReportColumn.getBackgroundColor().equals("")) {
                    cell.setCellStyle(redCellStyle);
                } else {
                    cell.setCellStyle(cellStyle);
                }
                cell.setCellValue(sewageReportColumn.getColumnName());
            }
            //总消耗量与总测算人口
            double sumEstimatedPopulation = 0;
            double sumHeroin = 0;
            double sumMa = 0;
            double sumK = 0;
            double sumMDMA = 0;
            double sumCoc = 0;
            double sumThc = 0;

            for (int i = 0; i < sewageDataDtoList.size() + 1; i++) {
                //构建最后两行中的消费量总量和人均量消费量数据
                if (i == sewageDataDtoList.size()) {
                    HSSFRow lastTwoRow = sheet.createRow(i + 1);
                    HSSFRow lastOneRow = sheet.createRow(i + 2);
                    lastTwoRow.setHeight((short) 300);
                    lastOneRow.setHeight((short) 300);

                    HSSFCell lastTwoRowCell42 = lastTwoRow.createCell(42);
                    lastTwoRowCell42.setCellValue("总和");
                    lastTwoRowCell42.setCellStyle(cellStyle);

                    HSSFCell twoRowCell11 = lastTwoRow.createCell(11);
                    twoRowCell11.setCellValue(String.format("%.2f", sumEstimatedPopulation));
                    twoRowCell11.setCellStyle(cellStyle);

                    HSSFCell lastRowCell = lastOneRow.createCell(42);
                    lastRowCell.setCellValue("人均消耗量");
                    lastRowCell.setCellStyle(pinkBackgroundStyle);

                    HSSFCell lastRowCell50 = lastOneRow.createCell(50);
                    lastRowCell50.setCellValue("人均总消耗量");
                    lastRowCell50.setCellStyle(pinkBackgroundStyle);

                    HSSFCell lastTwoRowCell43 = lastTwoRow.createCell(43);
                    lastTwoRowCell43.setCellValue(String.format("%.1f", sumHeroin));
                    lastTwoRowCell43.setCellStyle(cellStyle);

                    HSSFCell lastTwoRowCell44 = lastTwoRow.createCell(44);
                    lastTwoRowCell44.setCellValue(String.format("%.1f", sumMa));
                    lastTwoRowCell44.setCellStyle(cellStyle);

                    HSSFCell lastTwoRowCell45 = lastTwoRow.createCell(45);
                    lastTwoRowCell45.setCellValue(String.format("%.1f", sumK));
                    lastTwoRowCell45.setCellStyle(cellStyle);

                    HSSFCell lastTwoRowCell46 = lastTwoRow.createCell(46);
                    lastTwoRowCell46.setCellValue(String.format("%.1f", sumMDMA));
                    lastTwoRowCell46.setCellStyle(cellStyle);

                    HSSFCell lastTwoRowCell47 = lastTwoRow.createCell(47);
                    lastTwoRowCell47.setCellValue(String.format("%.1f", sumCoc));
                    lastTwoRowCell47.setCellStyle(cellStyle);

                    HSSFCell lastTwoRowCell48 = lastTwoRow.createCell(48);
                    lastTwoRowCell48.setCellValue(String.format("%.1f", sumThc));
                    lastTwoRowCell48.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell43 = lastOneRow.createCell(43);
                    lastOneRowCell43.setCellValue(String.format("%.1f", (sumHeroin / sumEstimatedPopulation)));
                    lastOneRowCell43.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell44 = lastOneRow.createCell(44);
                    lastOneRowCell44.setCellValue(String.format("%.1f", (sumMa / sumEstimatedPopulation)));
                    lastOneRowCell44.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell45 = lastOneRow.createCell(45);
                    lastOneRowCell45.setCellValue(String.format("%.1f", (sumK / sumEstimatedPopulation)));
                    lastOneRowCell45.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell46 = lastOneRow.createCell(46);
                    lastOneRowCell46.setCellValue(String.format("%.1f", (sumMDMA / sumEstimatedPopulation)));
                    lastOneRowCell46.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell47 = lastOneRow.createCell(47);
                    lastOneRowCell47.setCellValue(String.format("%.1f", (sumCoc / sumEstimatedPopulation)));
                    lastOneRowCell47.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell48 = lastOneRow.createCell(48);
                    lastOneRowCell48.setCellValue(String.format("%.1f", (sumThc / sumEstimatedPopulation)));
                    lastOneRowCell48.setCellStyle(cellStyle);

                    HSSFCell lastOneRowCell51 = lastOneRow.createCell(51);
                    lastOneRowCell51.setCellValue(String.format("%.2f", sumHeroin / sumEstimatedPopulation + sumCoc / sumEstimatedPopulation + sumK / sumEstimatedPopulation * 0.1 + sumMa / sumEstimatedPopulation + sumMDMA / sumEstimatedPopulation * 0.5 + sumThc / sumEstimatedPopulation));
                    lastOneRowCell51.setCellStyle(cellStyle);
                    break;
                }

                //构建检材数据
                SewageDataDto sewageDataDto = sewageDataDtoList.get(i);
                HSSFRow rowi = sheet.createRow(i + 1);
                rowi.setHeight((short) 300);

                HSSFCell celli0 = rowi.createCell(0);
                celli0.setCellValue(sewageDataDto.getImNo());
                celli0.setCellStyle(cellStyle);

                HSSFCell celli1 = rowi.createCell(1);
                celli1.setCellValue(sewageDataDto.getSampleName());
                celli1.setCellStyle(cellStyle);

                HSSFCell celli2 = rowi.createCell(2);
                celli2.setCellValue(sewageDataDto.getProvinceName());
                celli2.setCellStyle(cellStyle);

                HSSFCell celli3 = rowi.createCell(3);
                celli3.setCellValue(sewageDataDto.getCityName());
                celli3.setCellStyle(cellStyle);

                HSSFCell celli4 = rowi.createCell(4);
                celli4.setCellValue(sewageDataDto.getDistrictName());
                celli4.setCellStyle(cellStyle);

                HSSFCell celli5 = rowi.createCell(5);
                celli5.setCellValue(LocalDateTimeUtil.format(sewageDataDto.getCollectTime(), "yyyy/MM/dd"));
                celli5.setCellStyle(cellStyle);

                HSSFCell celli6 = rowi.createCell(6);
                celli6.setCellValue(sewageDataDto.getServicePopulation());
                celli6.setCellStyle(cellStyle);

                HSSFCell celli7 = rowi.createCell(7);
                celli7.setCellValue(sewageDataDto.getDomesticSewageProportion() + "%");
                celli7.setCellStyle(cellStyle);

                HSSFCell celli8 = rowi.createCell(8);
                celli8.setCellValue(sewageDataDto.getDailyFlow());
                celli8.setCellStyle(cellStyle);

                HSSFCell celli9 = rowi.createCell(9);
                celli9.setCellValue(sewageDataDto.getDailySmokingPerCapita());
                celli9.setCellStyle(cellStyle);

                HSSFCell celli10 = rowi.createCell(10);
                celli10.setCellValue(sewageDataDto.getCotinineExcretion());
                celli10.setCellStyle(cellStyle);

                HSSFCell celli11 = rowi.createCell(11);
                celli11.setCellValue(String.format("%.2f", sewageDataDto.getEstimatedPopulation()));
                celli11.setCellStyle(cellStyle);
                sumEstimatedPopulation += sewageDataDto.getEstimatedPopulation();

                HSSFCell celli12 = rowi.createCell(12);
                celli12.setCellStyle(cellStyle);
                celli12.setCellValue(String.format("%.1f", sewageDataDto.getCotinineConcentration()));

                HSSFCell celli13 = rowi.createCell(13);
                celli13.setCellStyle(cellStyle);
                celli13.setCellValue(sewageDataDto.getCodeineConcentration());

                HSSFCell celli14 = rowi.createCell(14);
                celli14.setCellStyle(cellStyle);
                celli14.setCellValue(String.format("%.1f", sewageDataDto.getMdaConcentration()));

                HSSFCell celli15 = rowi.createCell(15);
                celli15.setCellStyle(cellStyle);
                celli15.setCellValue(String.format("%.1f", sewageDataDto.getMdmaConcentration()));

                HSSFCell celli16 = rowi.createCell(16);
                celli16.setCellStyle(cellStyle);
                celli16.setCellValue(String.format("%.1f", sewageDataDto.getCocaineConcentration()));

                HSSFCell celli17 = rowi.createCell(17);
                celli17.setCellStyle(cellStyle);
                celli17.setCellValue(String.format("%.1f", sewageDataDto.getBenzoylecgonineConcentration()));

                HSSFCell celli18 = rowi.createCell(18);
                celli18.setCellStyle(cellStyle);
                celli18.setCellValue(String.format("%.1f", sewageDataDto.getMorphineConcentration()));

                HSSFCell celli19 = rowi.createCell(19);
                celli19.setCellStyle(cellStyle);
                celli19.setCellValue(String.format("%.1f", sewageDataDto.getAcetylmorphineConcentration()));

                HSSFCell celli20 = rowi.createCell(20);
                celli20.setCellStyle(cellStyle);
                celli20.setCellValue(String.format("%.1f", sewageDataDto.getMethamphetamineConcentration()));

                HSSFCell celli21 = rowi.createCell(21);
                celli21.setCellStyle(cellStyle);
                celli21.setCellValue(String.format("%.1f", sewageDataDto.getAmphetamineConcentration()));

                HSSFCell celli22 = rowi.createCell(22);
                celli22.setCellStyle(cellStyle);
                celli22.setCellValue(String.format("%.1f", sewageDataDto.getKetamineConcentration()));

                HSSFCell celli23 = rowi.createCell(23);
                celli23.setCellStyle(cellStyle);
                celli23.setCellValue(String.format("%.1f", sewageDataDto.getNorketamineConcentration()));

                HSSFCell celli24 = rowi.createCell(24);
                celli24.setCellStyle(cellStyle);
                celli24.setCellValue(String.format("%.1f", sewageDataDto.getThcConcentration()));

                HSSFCell celli25 = rowi.createCell(25);
                celli25.setCellStyle(cellStyle);
                celli25.setCellValue("");


                HSSFCell celli26 = rowi.createCell(26);
                celli26.setCellStyle(cellStyle);
                celli26.setCellValue(String.format("%.1f", sewageDataDto.getMorphineLoad()));

                HSSFCell celli27 = rowi.createCell(27);
                celli27.setCellStyle(cellStyle);
                celli27.setCellValue(String.format("%.1f", sewageDataDto.getCodeineLoad()));

                HSSFCell celli28 = rowi.createCell(28);
                celli28.setCellStyle(cellStyle);
                celli28.setCellValue(String.format("%.1f", sewageDataDto.getCodeineIsConvertedToMorphineLoad()));

                HSSFCell celli29 = rowi.createCell(29);
                celli29.setCellValue(sewageDataDto.getMedicalMorphineLoad());
                celli29.setCellStyle(cellStyle);

                HSSFCell celli30 = rowi.createCell(30);
                celli30.setCellStyle(cellStyle);
                celli30.setCellValue(String.format("%.1f", sewageDataDto.getMA_AM()));

                HSSFCell celli31 = rowi.createCell(31);
                celli31.setCellStyle(cellStyle);
                celli31.setCellValue(String.format("%.1f", sewageDataDto.getK_NK()));

                HSSFCell celli32 = rowi.createCell(32);
                celli32.setCellValue("");
                HSSFCell celli33 = rowi.createCell(33);
                celli33.setCellValue("");

                HSSFCell celli34 = rowi.createCell(34);
                celli34.setCellStyle(cellStyle);
                celli34.setCellValue(String.format("%.1f", sewageDataDto.getPccHeroin()));

                HSSFCell celli35 = rowi.createCell(35);
                celli35.setCellStyle(pinkBackgroundStyle);
                celli35.setCellValue(String.format("%.1f", sewageDataDto.getPccMa()));

                HSSFCell celli36 = rowi.createCell(36);
                celli36.setCellStyle(cellStyle);
                celli36.setCellValue(String.format("%.1f", sewageDataDto.getPccK()));

                HSSFCell celli37 = rowi.createCell(37);
                celli37.setCellStyle(cellStyle);
                celli37.setCellValue(String.format("%.1f", sewageDataDto.getPccMdma()));

                HSSFCell celli38 = rowi.createCell(38);
                celli38.setCellStyle(cellStyle);
                celli38.setCellValue(String.format("%.1f", sewageDataDto.getPccCoc()));

                HSSFCell celli39 = rowi.createCell(39);
                celli39.setCellStyle(cellStyle);
                celli39.setCellValue(String.format("%.1f", sewageDataDto.getPccThc()));

                HSSFCell celli40 = rowi.createCell(40);
                celli40.setCellValue("");
                HSSFCell celli41 = rowi.createCell(41);
                celli41.setCellValue("");
                HSSFCell celli42 = rowi.createCell(42);
                celli42.setCellValue("");

                HSSFCell celli43 = rowi.createCell(43);
                celli43.setCellStyle(cellStyle);
                celli43.setCellValue(String.format("%.1f", sewageDataDto.getTcHeroin()));
                sumHeroin += sewageDataDto.getTcHeroin();

                HSSFCell celli44 = rowi.createCell(44);
                celli44.setCellStyle(cellStyle);
                celli44.setCellValue(String.format("%.1f", sewageDataDto.getTcMa()));
                sumMa += sewageDataDto.getTcMa();

                HSSFCell celli45 = rowi.createCell(45);
                celli45.setCellStyle(cellStyle);
                celli45.setCellValue(String.format("%.1f", sewageDataDto.getTcK()));
                sumK += sewageDataDto.getTcK();

                HSSFCell celli46 = rowi.createCell(46);
                celli46.setCellStyle(cellStyle);
                celli46.setCellValue(String.format("%.1f", sewageDataDto.getTcMdma()));
                sumMDMA += sewageDataDto.getTcMdma();

                HSSFCell celli47 = rowi.createCell(47);
                celli47.setCellStyle(cellStyle);
                celli47.setCellValue(String.format("%.1f", sewageDataDto.getTcCoc()));
                sumCoc += sewageDataDto.getTcCoc();

                HSSFCell celli48 = rowi.createCell(48);
                celli48.setCellStyle(cellStyle);
                celli48.setCellValue(String.format("%.1f", sewageDataDto.getTcThc()));
                sumThc += sewageDataDto.getTcThc();
            }
        }
        String fileName = sewageDataDtos.get(0).getJobYear() + "年" + sewageDataDtos.get(0).getJobSeason() + "月污水" + "消费量报表.xls";
        FileOutputStream fileOutputStream = new FileOutputStream(temporarilyPath + fileName);
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        File file = new File(temporarilyPath, fileName);
        FileItem fileItem = testRecordInstrumentConditionService.getMultipartFile(file, file.getName());
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        String ossPath = "document/sewageReport/" + id;
        boolean ret = ossFile.fileUpload(multipartFile, "document/sewageReport/" + id);
        if (ret) {
            Files.delete(Paths.get(temporarilyPath, fileName));
        }
        workbook.close();
        return ossPath + "/" + fileName;
    }
}
