package cn.com.qmth.examcloud.core.questions.service.temp;

import cn.com.qmth.examcloud.core.questions.base.Model;
import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
import cn.com.qmth.examcloud.core.questions.dao.*;
import cn.com.qmth.examcloud.core.questions.dao.entity.*;
import cn.com.qmth.examcloud.core.questions.dao.entity.dto.PaperDetailUnitStructDto;
import cn.com.qmth.examcloud.core.questions.service.PaperDetailUnitService;
import cn.com.qmth.examcloud.core.questions.service.temp.vo.DdExcelDto;
import cn.com.qmth.examcloud.core.questions.service.temp.vo.DdPaperDto;
import cn.com.qmth.examcloud.core.questions.service.temp.vo.DdPaperStructDto;
import cn.com.qmth.examcloud.core.questions.service.temp.vo.SubQuestionDto;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

@Service("ddExcelService")
public class DdExcelService {
    private static final Logger log = LoggerFactory.getLogger(DdExcelService.class);
    private final String exportExcelPath = "D:/home/paper/exportExcel.xlsx";
    private final String xianExcelPath = "D:/home/paper/xianExcelNew.xlsx";
    private final String paperExcelPath = "D:/home/paper/paperExcel.xlsx";
    private final String paperExcelPathNew = "D:/home/paper/paperExcelNew.xlsx";
    private final String quesExcelPath = "D:/home/paper/quesExcel.xlsx";
    private final String quesExcelPathNew = "D:/home/paper/quesExcelNew.xlsx";
    private final String paperStructExcelPath = "D:/home/paper/paperStructExcel.xlsx";
    private final String paperStructExcelPathNew = "D:/home/paper/paperStructExcelNew.xlsx";
    @Autowired
    private QuesRepo quesRepo;
    @Autowired
    private PaperDetailUnitService paperDetailUnitService;
    @Autowired
    private PaperDetailUnitRepo paperDetailUnitRepo;
    @Autowired
    private PaperRepo paperRepo;
    @Autowired
    private CourseRepo courseRepo;
    @Autowired
    private QuesTypeNameRepo quesTypeRepo;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private PaperDetailRepo paperDetailRepo;

    public void insertQueryName(String orgId) {
        //查询所有课程
        long startCourseTime = System.currentTimeMillis();
        //List<Course> courses = courseRepo.findByOrgId(orgId);
        List<Course> courses = new ArrayList<>();
        long endCourseTime = System.currentTimeMillis();
        log.debug("查询课程耗时：" + (endCourseTime - startCourseTime) + "ms");
        if (courses != null && courses.size() > 0) {
            int i = 1;
            int j = 1;
            for (Course course : courses) {
                //根据课程查询试卷
                long startPaperTime = System.currentTimeMillis();
                List<Paper> papers = paperRepo.findByCourseNoAndOrgId(course.getCode(), orgId);
                long endPaperTime = System.currentTimeMillis();
                log.debug("查询第" + i + "个课程下所有试卷耗时耗时：" + (endPaperTime - startPaperTime) + "ms,课程代码为：" + course.getCode());
                if (papers != null && papers.size() > 0) {
                    //生成所有试卷的试题集合
                    List<PaperDetailUnit> allUnits = new ArrayList<>();
                    for (Paper paper : papers) {
                        //根据试卷查询paperDetailUnits
                        long startUnitTime = System.currentTimeMillis();
                        List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaper(paper);
                        long endUnitTime = System.currentTimeMillis();
                        log.debug("查询" + paper.getName() + "个试卷下所有试题耗时耗时：" + (endUnitTime - startUnitTime) + "ms");
                        if (paperDetailUnits != null && paperDetailUnits.size() > 0) {
                            for (PaperDetailUnit unit : paperDetailUnits) {
                                allUnits.add(unit);
                            }
                        }
                    }
                    log.debug("开始生成对象...总题数量：" + allUnits.size());
                    //生成需要保存的大题来源集合
                    List<QuesTypeName> quesTypeNames = new ArrayList<>();
                    Map<QuesStructType, List<String>> map = buildQuesTypeName(allUnits);
                    for (Map.Entry<QuesStructType, List<String>> entry : map.entrySet()) {
                        QuesTypeName quesTypeName = new QuesTypeName();
                        quesTypeName.setOrgId(orgId);
                        quesTypeName.setCourseNo(course.getCode());
                        quesTypeName.setQuestionType(entry.getKey());
                        quesTypeName.setQuesNames(entry.getValue());
                        quesTypeNames.add(quesTypeName);
                        log.debug("生成完第" + j + "个对象");
                        j++;
                    }
                    long endTime = System.currentTimeMillis();
                    log.debug("所有试题耗时耗时：" + (endTime - endPaperTime) + "ms");
                    quesTypeRepo.saveAll(quesTypeNames);
                    long ends = System.currentTimeMillis();
                    log.debug("第" + i + "个课程保存所有来源大题耗时：" + (ends - endTime) + "ms");
                }
                i++;
            }
            log.debug("对象生成完");
        }
    }

    //quesTypeRepo.save(quesTypeNames);
    public Map<QuesStructType, List<String>> buildQuesTypeName(List<PaperDetailUnit> paperDetailUnits) {
        Map<QuesStructType, List<String>> map = new HashMap<>();
        for (PaperDetailUnit paperDetailUnit : paperDetailUnits) {
            String name = paperDetailUnit.getPaperDetail().getName();
            QuesStructType questionType = paperDetailUnit.getQuestion().getQuestionType();
            List<String> names = map.get(questionType);
            if (names == null) {
                List<String> nameList = new ArrayList<>();
                nameList.add(name);
                map.put(questionType, nameList);
            } else {
                if (names.contains(name)) {
                    continue;
                } else {
                    names.add(name);
                    map.put(questionType, names);
                }
            }
        }
        return map;
    }

    /**
     * 导出按大题名称统计分布
     */
    @SuppressWarnings("resource")
    public void exporExcel(String orgId) {
        //导出Excel集合
        List<DdExcelDto> ddExcelDtos = new ArrayList<>();
        //查询所有课程
        long startCourseTime = System.currentTimeMillis();
        //List<Course> courses = courseRepo.findByOrgId(orgId);
        List<Course> courses = new ArrayList<>();
        long endCourseTime = System.currentTimeMillis();
        log.debug("查询课程耗时：" + (endCourseTime - startCourseTime) + "ms");
        if (courses != null && courses.size() > 0) {
            int i = 0;
            for (Course course : courses) {
                //查询该课程下的所有question
                long startQuestionTime = System.currentTimeMillis();
                List<Question> questions = quesRepo.findByCourseAndOrgId(course, orgId);
                long endQuestionTime = System.currentTimeMillis();
                log.debug("查询第" + i + "个课程试题耗时：" + (endQuestionTime - startQuestionTime) + "ms");
                List<String> oIds = new ArrayList<>();
                for (Question question : questions) {
                    oIds.add(question.getId());
                }
                //根据question查询paperDetailUnit
                long startUnitTime = System.currentTimeMillis();
                List<PaperDetailUnit> oDetailUnits = paperDetailUnitService.findByDDQuestionsAndPaperType(oIds, PaperType.IMPORT, questions);
                long endUnitTime = System.currentTimeMillis();
                log.debug("查询第" + i + "个课程试题耗时：" + (endUnitTime - startUnitTime) + "ms");
                Map<String, Long> map = new HashMap<>();
                if (oDetailUnits != null && oDetailUnits.size() > 0) {
                    for (PaperDetailUnit unit : oDetailUnits) {
                        //大题名称
                        String quesName = unit.getPaperDetail().getName();
                        if (map.get(quesName) == null) {
                            map.put(quesName, 1L);
                        } else {
                            Long number = map.get(quesName);
                            number++;
                            map.put(quesName, number);
                        }
                    }
                }
                DdExcelDto ddExcelDto = new DdExcelDto(course.getName(), course.getCode(), map);
                ddExcelDtos.add(ddExcelDto);
                log.debug("已经处理完：" + i + "个课程...");
                i++;
            }
        }

        //生成Excel对象
        File ddExcelFile = new File(exportExcelPath);
        File file = new File(xianExcelPath);

        try (Workbook workBook = new XSSFWorkbook(ddExcelFile);
             OutputStream out = new FileOutputStream(file);) {

            //获取第一个工作页
            Sheet sheet = workBook.getSheetAt(0);
            log.debug(sheet.getSheetName());

            //向Excel中写入数据，从第2行开始
            for (int i = 0; i < ddExcelDtos.size(); i++) {
                //创建一行：从第1行开始，跳过表头
                Row row = sheet.createRow(i + 1);
                DdExcelDto ddExcelDto = ddExcelDtos.get(i);
                //每列赋值
                row.createCell(0).setCellValue(ddExcelDto.getCourseName());
                row.createCell(1).setCellValue(ddExcelDto.getCourseCode());

                if (ddExcelDto.getMap() != null && ddExcelDto.getMap().size() > 0) {
                    if (ddExcelDto.getMap().get("单选题") == null) {
                        row.createCell(2).setCellValue(0);
                    } else {
                        row.createCell(2).setCellValue(ddExcelDto.getMap().get("单选题"));
                    }

                    if (ddExcelDto.getMap().get("多选题") == null) {
                        row.createCell(3).setCellValue(0);
                    } else {
                        row.createCell(3).setCellValue(ddExcelDto.getMap().get("多选题"));
                    }

                    if (ddExcelDto.getMap().get("填空题") == null) {
                        row.createCell(4).setCellValue(0);
                    } else {
                        row.createCell(4).setCellValue(ddExcelDto.getMap().get("填空题"));
                    }

                    if (ddExcelDto.getMap().get("选词填空") == null) {
                        row.createCell(5).setCellValue(0);
                    } else {
                        row.createCell(5).setCellValue(ddExcelDto.getMap().get("选词填空"));
                    }

                    if (ddExcelDto.getMap().get("完型填空") == null) {
                        row.createCell(6).setCellValue(0);
                    } else {
                        row.createCell(6).setCellValue(ddExcelDto.getMap().get("完型填空"));
                    }

                    if (ddExcelDto.getMap().get("判断题") == null) {
                        row.createCell(7).setCellValue(0);
                    } else {
                        row.createCell(7).setCellValue(ddExcelDto.getMap().get("判断题"));
                    }

                    if (ddExcelDto.getMap().get("阅读理解") == null) {
                        row.createCell(8).setCellValue(0);
                    } else {
                        row.createCell(8).setCellValue(ddExcelDto.getMap().get("阅读理解"));
                    }

                    if (ddExcelDto.getMap().get("问答题") == null) {
                        row.createCell(9).setCellValue(0);
                    } else {
                        row.createCell(9).setCellValue(ddExcelDto.getMap().get("问答题"));
                    }

                    if (ddExcelDto.getMap().get("名词解释") == null) {
                        row.createCell(10).setCellValue(0);
                    } else {
                        row.createCell(10).setCellValue(ddExcelDto.getMap().get("名词解释"));
                    }

                    //额外大题名称
                    if (ddExcelDto.getMap().get("案例分析") == null) {
                        row.createCell(11).setCellValue(0);
                    } else {
                        row.createCell(11).setCellValue(ddExcelDto.getMap().get("案例分析"));
                    }

                    if (ddExcelDto.getMap().get("作文题") == null) {
                        row.createCell(12).setCellValue(0);
                    } else {
                        row.createCell(12).setCellValue(ddExcelDto.getMap().get("作文题"));
                    }

                    if (ddExcelDto.getMap().get("交际英语") == null) {
                        row.createCell(13).setCellValue(0);
                    } else {
                        row.createCell(13).setCellValue(ddExcelDto.getMap().get("交际英语"));
                    }

                    if (ddExcelDto.getMap().get("简答题") == null) {
                        row.createCell(14).setCellValue(0);
                    } else {
                        row.createCell(14).setCellValue(ddExcelDto.getMap().get("简答题"));
                    }

                    if (ddExcelDto.getMap().get("一、单选题") == null) {
                        row.createCell(15).setCellValue(0);
                    } else {
                        row.createCell(15).setCellValue(ddExcelDto.getMap().get("一、单选题"));
                    }

                    if (ddExcelDto.getMap().get("名称解释") == null) {
                        row.createCell(16).setCellValue(0);
                    } else {
                        row.createCell(16).setCellValue(ddExcelDto.getMap().get("名称解释"));
                    }

                    if (ddExcelDto.getMap().get("综合题") == null) {
                        row.createCell(17).setCellValue(0);
                    } else {
                        row.createCell(17).setCellValue(ddExcelDto.getMap().get("综合题"));
                    }

                    if (ddExcelDto.getMap().get("设计题") == null) {
                        row.createCell(18).setCellValue(0);
                    } else {
                        row.createCell(18).setCellValue(ddExcelDto.getMap().get("设计题"));
                    }

                    if (ddExcelDto.getMap().get("二、名词解释") == null) {
                        row.createCell(19).setCellValue(0);
                    } else {
                        row.createCell(19).setCellValue(ddExcelDto.getMap().get("二、名词解释"));
                    }

                    if (ddExcelDto.getMap().get("分析题") == null) {
                        row.createCell(20).setCellValue(0);
                    } else {
                        row.createCell(20).setCellValue(ddExcelDto.getMap().get("分析题"));
                    }

                    if (ddExcelDto.getMap().get("英汉翻译") == null) {
                        row.createCell(21).setCellValue(0);
                    } else {
                        row.createCell(21).setCellValue(ddExcelDto.getMap().get("英汉翻译"));
                    }

                    if (ddExcelDto.getMap().get("作文") == null) {
                        row.createCell(22).setCellValue(0);
                    } else {
                        row.createCell(22).setCellValue(ddExcelDto.getMap().get("作文"));
                    }

                    if (ddExcelDto.getMap().get("二、计算题") == null) {
                        row.createCell(23).setCellValue(0);
                    } else {
                        row.createCell(23).setCellValue(ddExcelDto.getMap().get("二、计算题"));
                    }

                    if (ddExcelDto.getMap().get("作图题") == null) {
                        row.createCell(24).setCellValue(0);
                    } else {
                        row.createCell(24).setCellValue(ddExcelDto.getMap().get("作图题"));
                    }

                    if (ddExcelDto.getMap().get("论述题") == null) {
                        row.createCell(25).setCellValue(0);
                    } else {
                        row.createCell(25).setCellValue(ddExcelDto.getMap().get("论述题"));
                    }

                    if (ddExcelDto.getMap().get("三、计算题") == null) {
                        row.createCell(26).setCellValue(0);
                    } else {
                        row.createCell(26).setCellValue(ddExcelDto.getMap().get("三、计算题"));
                    }

                    if (ddExcelDto.getMap().get("计算题") == null) {
                        row.createCell(27).setCellValue(0);
                    } else {
                        row.createCell(27).setCellValue(ddExcelDto.getMap().get("计算题"));
                    }

                    if (ddExcelDto.getMap().get("算法设计题") == null) {
                        row.createCell(28).setCellValue(0);
                    } else {
                        row.createCell(28).setCellValue(ddExcelDto.getMap().get("算法设计题"));
                    }

                    if (ddExcelDto.getMap().get("翻译题") == null) {
                        row.createCell(29).setCellValue(0);
                    } else {
                        row.createCell(29).setCellValue(ddExcelDto.getMap().get("翻译题"));
                    }

                } else {
                    log.debug("课程：" + ddExcelDto.getCourseName());
                }
            }

            workBook.write(out);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidFormatException e) {
            log.error(e.getMessage(), e);
        }

        log.debug("结束...");
    }

    /**
     * 导出试卷详情
     */
    @SuppressWarnings("resource")
    public void exportPaperExcel(String orgId) throws Exception {
        log.debug("开始导出试卷具体信息。。。。");
        //导出Excel对象集合
        List<DdPaperDto> excelDtoList = new ArrayList<>();
        //根据课程查询试卷
        Query query = new Query();
        query.addCriteria(Criteria.where("orgId").is(orgId));
        query.addCriteria(Criteria.where("paperType").is(PaperType.IMPORT));
        List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);
        if (paperList != null && paperList.size() > 0) {
            int j = 1;
            for (Paper paper : paperList) {
                //查询大题集合
                List<PaperDetail> details = paperDetailRepo.findByPaperOrderByNumber(paper);
                if (details != null && details.size() > 0) {
                    for (PaperDetail detail : details) {
                        DdPaperDto ddPaperDto = new DdPaperDto();
                        ddPaperDto.setCode(paper.getCourse().getCode());
                        ddPaperDto.setDetailName(detail.getName());
                        ddPaperDto.setName(paper.getCourse().getName());
                        ddPaperDto.setNumber(detail.getUnitCount());
                        ddPaperDto.setPaperName(paper.getName());
                        excelDtoList.add(ddPaperDto);
                    }
                }
                log.debug("处理完第" + j + "套试卷。。。");
                j++;
            }
        }
        //查询所有课程
        //List<Course> courses = courseRepo.findByOrgId(orgId);
        //List<Course> courses = new ArrayList<Course>();
        //log.debug("查询课程总数："+ courses.size());
		/*if(courses != null && courses.size()>0){
			int i = 1;
			for(Course course : courses){
				//根据课程查询试卷
			    Query query = new Query();
		        query.addCriteria(Criteria.where("orgId").is(orgId));
		        query.addCriteria(Criteria.where("paperType").is(PaperType.GENERATE));
		        query.addCriteria(Criteria.where("course.enable").is("true"));
		        query.addCriteria(Criteria.where("course.code").is(course.getCode()));
		        List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);
		        log.debug(course.getCode() + "课程下的组卷试卷数量：" + paperList.size());
		        if(paperList != null && paperList.size()>0){
		        	int j = 1;
		        	for(Paper paper : paperList){
		        		//查询大题集合
		        		List<PaperDetail> details = paperDetailRepo.findByPaperOrderByNumber(paper);
		        		if(details != null && details.size()>0){
		        			for(PaperDetail detail:details){
		        				DdPaperDto ddPaperDto = new DdPaperDto();
			        			ddPaperDto.setCode(paper.getCourse().getCode());
			        			ddPaperDto.setDetailName(detail.getName());
			        			ddPaperDto.setName(paper.getCourse().getName());
			        			ddPaperDto.setNumber(detail.getUnitCount());
			        			ddPaperDto.setPaperName(paper.getName());
			        			excelDtoList.add(ddPaperDto);
		        			}
		        		}
		        		log.debug("处理完第"+ j + "套试卷。。。");
		        		j++;
		        	}
		        }
		        log.debug("处理完第"+ i + "个课程。。。");
        		i++;
			}
		}*/

        //生成Excel对象
        File ddExcelFile = new File(paperExcelPath);
        File file = new File(paperExcelPathNew);

        try (Workbook workBook = new XSSFWorkbook(ddExcelFile);
             OutputStream out = new FileOutputStream(file);) {

            //获取第一个工作页
            Sheet sheet = workBook.getSheetAt(0);

            //向Excel中写入数据，从第2行开始
            for (int i = 0; i < excelDtoList.size(); i++) {
                //创建一行：从第1行开始，跳过表头
                Row row = sheet.createRow(i + 1);
                DdPaperDto excelDto = excelDtoList.get(i);
                //每列赋值
                row.createCell(0).setCellValue(excelDto.getCode());
                row.createCell(1).setCellValue(excelDto.getName());
                row.createCell(2).setCellValue(excelDto.getPaperName());
                row.createCell(3).setCellValue(excelDto.getDetailName());
                row.createCell(4).setCellValue(excelDto.getNumber());
            }

            workBook.write(out);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidFormatException e) {
            log.error(e.getMessage(), e);
        }

        log.debug("结束...");
    }

    /**
     * 导出课程下的精确试卷结构
     */
    @SuppressWarnings("resource")
    public void exportPaperStructExcel(String orgId) throws Exception {
        log.debug("开始导出试卷结构");
        //导出Excel对象集合
        List<DdPaperStructDto> excelDtoList = new ArrayList<>();
        //查询所有课程
        List<Course> courses = courseRepo.findByOrgId(orgId);
        //List<Course> courses = new ArrayList<>();
        log.debug("查询课程总数：" + courses.size());

        if (courses != null && courses.size() > 0) {
            int i = 1;
            for (Course course : courses) {
                Query query = new Query();
                query.addCriteria(Criteria.where("orgId").is(orgId));
                query.addCriteria(Criteria.where("type").is("EXACT"));
                query.addCriteria(Criteria.where("courseNo").is(course.getCode()));
                List<PaperStruct> paperStructList = this.mongoTemplate.find(query, PaperStruct.class);
                log.debug(course.getCode() + "课程下的试卷结构数量：" + paperStructList.size());
                if (paperStructList != null && paperStructList.size() > 0) {
                    for (PaperStruct paperStruct : paperStructList) {
                        //得到大题集合
                        List<PaperDetailStruct> paperDetailStructs = paperStruct.getPaperDetailStructs();
                        if (paperDetailStructs != null && paperDetailStructs.size() > 0) {
                            for (PaperDetailStruct paperDetailStruct : paperDetailStructs) {
                                //得到大题下的小题集合
                                List<PaperDetailUnitStructDto> unitStructs = paperDetailStruct.getUnitStructs();
                                if (unitStructs != null && unitStructs.size() > 0) {
                                    for (PaperDetailUnitStructDto unitStructDto : unitStructs) {
                                        DdPaperStructDto excelDto = new DdPaperStructDto();
                                        excelDto.setCode(paperStruct.getCourseNo());
                                        excelDto.setDetailName(paperDetailStruct.getName());
                                        excelDto.setName(course.getName());
                                        excelDto.setNumber(unitStructDto.getCount());
                                        excelDto.setQuesNames(unitStructDto.getQuesNames().toString());
                                        excelDto.setQuesType(unitStructDto.getQuestionType().getName());
                                        excelDtoList.add(excelDto);
                                    }
                                }
                            }
                        }
                    }
                }
                log.debug("处理完第：" + i + "个课程。");
                log.debug("生成对象个数：" + excelDtoList.size());
                i++;
            }
        }

        //生成Excel对象
        File ddExcelFile = new File(paperStructExcelPath);
        File file = new File(paperStructExcelPathNew);

        try (Workbook workBook = new XSSFWorkbook(ddExcelFile);
             OutputStream out = new FileOutputStream(file);) {

            //获取第一个工作页
            Sheet sheet = workBook.getSheetAt(0);

            //向Excel中写入数据，从第2行开始
            for (int i = 0; i < excelDtoList.size(); i++) {
                //创建一行：从第1行开始，跳过表头
                Row row = sheet.createRow(i + 1);
                DdPaperStructDto excelDto = excelDtoList.get(i);
                //每列赋值
                row.createCell(0).setCellValue(excelDto.getCode());
                row.createCell(1).setCellValue(excelDto.getName());
                row.createCell(2).setCellValue(excelDto.getDetailName());
                row.createCell(3).setCellValue(excelDto.getQuesNames());
                row.createCell(4).setCellValue(excelDto.getNumber());
                row.createCell(5).setCellValue(excelDto.getQuesType());
            }

            workBook.write(out);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidFormatException e) {
            log.error(e.getMessage(), e);
        }

        log.debug("结束...");
    }

    /**
     * 给定考试和课程集合，查询所有试卷中的主观题，导出一个Excel（课程名称，课程代码，试卷名称，试卷id,试题题干）
     */
    @SuppressWarnings("resource")
    public void exportSubQues(String orgId, Long examId, List<String> codes) throws Exception {
        log.debug(String.format("共%s门课程的调卷规则", codes.size()));

        int index = 1;
        List<SubQuestionDto> subjectQuestions = new ArrayList<>();
        for (String code : codes) {
            log.debug("开始处理第" + index + "门课程的调卷规则");
            index++;

            Query query = new Query();
            query.addCriteria(Criteria.where("orgId").is(orgId));
            query.addCriteria(Criteria.where("examId").is(examId));
            query.addCriteria(Criteria.where("courseCode").is(code));
            ExtractConfig tempConfig = this.mongoTemplate.findOne(query, ExtractConfig.class);
            if (tempConfig == null) {
                log.debug(String.format("课程-%s：没有调卷规则", code));
                continue;
            }

            //定义试卷集合
            Set<String> ids = new HashSet<>();

            //获取试卷
            List<ExamPaper> examPaperList = tempConfig.getExamPaperList();
            log.debug("原试卷数量：" + examPaperList.size());

            for (ExamPaper examPaper : examPaperList) {
                ids.add(examPaper.getPaper().getId());
            }
            log.debug("去重后的试卷数量：" + ids.size());

            //循环去重后的试卷
            for (String id : ids) {
                Paper basePaper = Model.of(paperRepo.findById(id));
                //根据试卷查询所有小题
                List<PaperDetailUnit> allPaperDetailUnits = paperDetailUnitRepo.findByPaper(basePaper);
                //循环所有小题，寻找主观题
                for (PaperDetailUnit paperDetailUnit : allPaperDetailUnits) {
                    Question question = paperDetailUnit.getQuestion();
                    //填空或问答
                    if (question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION
                            || question.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
                        String body = question.getQuesBody();
                        String clearBody = body.replace("<p>", "").replace("</p>", "").replace("<span>", "").replace("</span>", "").replace("###", "___");
                        String answer = question.getQuesAnswer();
                        String clearAnswer = answer.replace("<p>", "").replace("</p>", "").replace("<span>", "").replace("</span>", "");
                        SubQuestionDto dto = new SubQuestionDto();
                        dto.setAnswer(answer);
                        dto.setBody(body);
                        dto.setClearAnswer(clearAnswer);
                        dto.setClearBody(clearBody);
                        dto.setCourseCode(tempConfig.getCourseCode());
                        dto.setCourseName(tempConfig.getCourseName());
                        dto.setDetailName(paperDetailUnit.getPaperDetail().getName());//大题名称
                        dto.setdNumber(paperDetailUnit.getDetailNumber());
                        dto.setNumber(paperDetailUnit.getNumber());
                        dto.setPaperId(basePaper.getId());
                        dto.setPaperName(basePaper.getName());
                        dto.setScore(paperDetailUnit.getScore());
                        subjectQuestions.add(dto);
                    }
                }
            }
        }

        //生成Excel对象
        File ddExcelFile = new File(quesExcelPath);
        File file = new File(quesExcelPathNew);

        try (Workbook workBook = new XSSFWorkbook(ddExcelFile);
             OutputStream out = new FileOutputStream(file);) {

            //获取第一个工作页
            Sheet sheet = workBook.getSheetAt(0);

            //标题
            Row titleRow = sheet.createRow(0);
            titleRow.createCell(0).setCellValue("课程代码");
            titleRow.createCell(1).setCellValue("课程名称");
            titleRow.createCell(2).setCellValue("试卷名称");
            titleRow.createCell(3).setCellValue("原始试卷ID");
            titleRow.createCell(4).setCellValue("大题号");
            titleRow.createCell(5).setCellValue("小题号");
            titleRow.createCell(6).setCellValue("标准分");
            titleRow.createCell(7).setCellValue("大题名称");
            titleRow.createCell(8).setCellValue("题干");
            titleRow.createCell(9).setCellValue("题干(含标签)");
            titleRow.createCell(10).setCellValue("标答");
            titleRow.createCell(11).setCellValue("标答(含标签)");

            //向Excel中写入数据，从第2行开始
            for (int i = 0; i < subjectQuestions.size(); i++) {
                //创建一行：从第1行开始，跳过表头
                Row row = sheet.createRow(i + 1);
                SubQuestionDto dto = subjectQuestions.get(i);
                //每列赋值
                row.createCell(0).setCellValue(dto.getCourseCode());
                row.createCell(1).setCellValue(dto.getCourseName());
                row.createCell(2).setCellValue(dto.getPaperName());
                row.createCell(3).setCellValue(dto.getPaperId());
                row.createCell(4).setCellValue(dto.getdNumber());
                row.createCell(5).setCellValue(dto.getNumber());
                row.createCell(6).setCellValue(dto.getScore());
                row.createCell(7).setCellValue(dto.getDetailName());
                row.createCell(8).setCellValue(dto.getClearBody());
                row.createCell(9).setCellValue(dto.getBody());
                if (dto.getClearAnswer().length() < 32767) {
                    row.createCell(10).setCellValue(dto.getClearAnswer());
                }
                if (dto.getAnswer().length() < 32767) {
                    row.createCell(11).setCellValue(dto.getAnswer());
                }
            }

            workBook.write(out);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidFormatException e) {
            log.error(e.getMessage(), e);
        }

        log.debug("结束...");
    }

}