package com.xjrsoft.module.base.service.impl; import cn.hutool.core.bean.BeanUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.xjrsoft.common.enums.ArchivesStatusEnum; import com.xjrsoft.common.enums.DeleteMark; import com.xjrsoft.common.enums.UseSemesterTypeEnum; import com.xjrsoft.common.exception.MyException; import com.xjrsoft.common.utils.VoToColumnUtil; import com.xjrsoft.module.base.dto.*; import com.xjrsoft.module.base.entity.*; import com.xjrsoft.module.base.mapper.BaseClassAdminCourseMapper; import com.xjrsoft.module.base.mapper.BaseClassCourseMapper; import com.xjrsoft.module.base.mapper.BaseClassMapper; import com.xjrsoft.module.base.service.IBaseClassCourseService; import com.xjrsoft.module.base.vo.*; import com.xjrsoft.module.generator.entity.ImportConfig; import com.xjrsoft.module.organization.entity.Department; import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll; import com.xjrsoft.module.student.mapper.BaseStudentSchoolRollMapper; import com.xjrsoft.module.system.entity.DictionaryDetail; import com.xjrsoft.module.textbook.entity.Textbook; import com.xjrsoft.module.textbook.entity.TextbookStudentClaim; import com.xjrsoft.module.textbook.mapper.TextbookStudentClaimMapper; import lombok.AllArgsConstructor; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import static com.xjrsoft.module.veb.util.ImportExcelUtil.allFields; import static com.xjrsoft.module.veb.util.ImportExcelUtil.createHead; /** * @title: 班级课程 * @Author brealinxx * @Date: 2024-06-04 * @Version 1.0 */ @Service @AllArgsConstructor public class BaseClassCourseServiceImpl extends MPJBaseServiceImpl implements IBaseClassCourseService { private final BaseClassCourseMapper baseClassCourseMapper; private final BaseStudentSchoolRollMapper baseStudentSchoolRollMapper; private final TextbookStudentClaimMapper textbookStudentClaimMapper; private final BaseClassMapper baseClassMapper; private final BaseClassAdminCourseMapper baseClassAdminCourseMapper; @Override public Page getPage(Page page, BaseClassCoursePageDto dto) { return baseClassCourseMapper.getPage(page, dto); } @Override public List oneClassClassCourseList(BaseClassCourseListDto dto) { MPJLambdaWrapper baseClassCourseMPJLambdaWrapper = new MPJLambdaWrapper<>(); baseClassCourseMPJLambdaWrapper .disableSubLogicDel() .select(BaseClassCourse::getId) .selectAs(BaseClass::getName, BaseClassCourseListVo::getClassIdCn) .selectAs(BaseCourseSubject::getName, BaseClassCourseListVo::getCourseIdCn) .selectAs(Textbook::getBookName, BaseClassCourseListVo::getTextbookIdCn) .selectAs(BaseSemester::getName, BaseClassCourseListVo::getBaseSemesterIdCn) .select(BaseClassCourse.class, x -> VoToColumnUtil.fieldsToColumns(BaseClassCourseListVo.class).contains(x.getProperty())) .innerJoin(BaseClassCourse.class, BaseClassCourse::getClassId, BaseClassAdminCourse::getId) .leftJoin(BaseClass.class, BaseClass::getId, BaseClassAdminCourse::getClassId) .leftJoin(BaseSemester.class, BaseSemester::getId, BaseClassAdminCourse::getBaseSemesterId) .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, BaseClassCourse::getCourseId) .leftJoin(Textbook.class, Textbook::getId, BaseClassCourse::getTextbookId) .eq(dto.getBaseSemesterId() != null && dto.getBaseSemesterId() > 0, BaseClassAdminCourse::getBaseSemesterId, dto.getBaseSemesterId()) .eq(dto.getClassId() != null && dto.getClassId() > 0, BaseClassAdminCourse::getClassId, dto.getClassId()) .eq(BaseClassCourse::getDeleteMark, DeleteMark.NODELETE.getCode()) ; return baseClassAdminCourseMapper.selectJoinList(BaseClassCourseListVo.class, baseClassCourseMPJLambdaWrapper); } @Override public List mobileOneClassClassCourseList(BaseClassCourseListDto dto) { MPJLambdaWrapper baseClassCourseMPJLambdaWrapper = new MPJLambdaWrapper<>(); baseClassCourseMPJLambdaWrapper .disableSubLogicDel() .select(BaseClassCourse::getId) .selectAs(BaseCourseSubject::getName, BaseClassCourseMobileListVo::getCourseName) .selectAs(Textbook::getBookName, BaseClassCourseMobileListVo::getBookName) .selectAs(Textbook::getPrice, BaseClassCourseMobileListVo::getPrice) .selectAs(DictionaryDetail::getName, BaseClassCourseMobileListVo::getTextbookTypeName) .select(BaseClassCourse.class, x -> VoToColumnUtil.fieldsToColumns(BaseClassCourseMobileListVo.class).contains(x.getProperty())) .innerJoin(BaseClassCourse.class, BaseClassCourse::getClassId, BaseClassAdminCourse::getId) .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, BaseClassCourse::getCourseId) .leftJoin(Textbook.class, Textbook::getId, BaseClassCourse::getTextbookId) .leftJoin(DictionaryDetail.class,DictionaryDetail::getCode,Textbook::getTextbookType) .eq(dto.getBaseSemesterId() != null && dto.getBaseSemesterId() > 0, BaseClassAdminCourse::getBaseSemesterId, dto.getBaseSemesterId()) .eq(dto.getClassId() != null && dto.getClassId() > 0, BaseClassAdminCourse::getClassId, dto.getClassId()) .eq(BaseClassCourse::getDeleteMark, DeleteMark.NODELETE.getCode()) ; return baseClassAdminCourseMapper.selectJoinList(BaseClassCourseMobileListVo.class, baseClassCourseMPJLambdaWrapper); } @Override public List getAllCourseBook(Long[] classIds, Long subjectGroupId, Long semester){ return baseClassCourseMapper.getAllCourseBook(classIds, subjectGroupId, semester); } @Override public List getSelectedCourseBook(Long[] classIds, Long semester){ return baseClassCourseMapper.getSelectedCourseBook(classIds, semester); } @Override @Transactional public Boolean oneUpdateClassCoursesAndTextbooks(ClassCourseTextbook dto) { return updateAddCourseBook(dto); } @Override @Transactional public Boolean updateAddCourseBook(ClassCourseTextbook dto){ if (ObjectUtils.isEmpty(dto.getBaseClassAdminCourseIds())) { throw new MyException("添加课程的班级无效,请刷新重试"); } // 根据班级id查出班级已经存在的课程和教程 LambdaQueryWrapper baseClassCourseLambdaQueryWrapper = new LambdaQueryWrapper<>(); baseClassCourseLambdaQueryWrapper .in(BaseClassCourse::getClassId, dto.getBaseClassAdminCourseIds()) .eq(BaseClassCourse::getDeleteMark, DeleteMark.NODELETE.getCode()) ; List oldList = this.list(baseClassCourseLambdaQueryWrapper); // 使用Stream API和Lambda表达式生成所需的字符串列表 Map> courseIdTextbookIdMap = oldList.stream() .collect(Collectors.groupingBy( BaseClassCourse::getClassId, Collectors.mapping( course -> course.getCourseId() + "_" + course.getTextbookId(), Collectors.toList() ) )); // 处理所有需要新增的教材 Map newClassCourseTextbookMap = new HashMap<>(); for (String id : dto.getIds()) { String[] idArr = id.split("_"); if (idArr[0].isEmpty() || idArr[1].isEmpty()) { continue; } Long courseId = Long.parseLong(idArr[0]); Long textbookId = Long.parseLong(idArr[1]); newClassCourseTextbookMap.put(id, new BaseClassCourse() {{ setCourseId(courseId); setTextbookId(textbookId); setCreateDate(new Date()); }}); } // 处理每一个班需要新增的课程 List baseClassCourseList = new ArrayList<>(); for (Long classId : dto.getBaseClassAdminCourseIds()) { // 判断当前的班级是否已经有了该课程和教材 List tourseIdTextbookIdList = null; if(ObjectUtils.isNotEmpty(courseIdTextbookIdMap)){ tourseIdTextbookIdList = courseIdTextbookIdMap.get(classId); } for (Map.Entry entry : newClassCourseTextbookMap.entrySet()) { String key = entry.getKey(); BaseClassCourse value = entry.getValue(); if(ObjectUtils.isNotEmpty(tourseIdTextbookIdList) && !tourseIdTextbookIdList.isEmpty() && tourseIdTextbookIdList.contains(key)){ continue; } value.setClassId(classId); baseClassCourseList.add(value); } } return this.saveBatch(baseClassCourseList); } @Override @Transactional public Boolean updateRemoveCourseBook(ClassCourseTextbook dto){ if (ObjectUtils.isEmpty(dto.getBaseClassAdminCourseIds())) { throw new MyException("移除课程的班级无效,请刷新重试"); } Map newClassCourseTextbookMap = new HashMap<>(); for (String id : dto.getIds()) { String[] idArr = id.split("_"); if (idArr[0].isEmpty() || idArr[1].isEmpty()) { continue; } Long courseId = Long.parseLong(idArr[0]); Long textbookId = Long.parseLong(idArr[1]); newClassCourseTextbookMap.put(id, new BaseClassCourse() {{ setCourseId(courseId); setTextbookId(textbookId); }}); } for (Long classId : dto.getBaseClassAdminCourseIds()) { for (Map.Entry entry : newClassCourseTextbookMap.entrySet()) { BaseClassCourse value = entry.getValue(); if(ObjectUtils.isNotEmpty(value)){ // 移除 LambdaUpdateWrapper baseClassCourseLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); baseClassCourseLambdaUpdateWrapper .eq(BaseClassCourse::getClassId, classId) .eq(BaseClassCourse::getCourseId, value.getCourseId()) .eq(BaseClassCourse::getTextbookId, value.getTextbookId()) ; this.remove(baseClassCourseLambdaUpdateWrapper); } } } return true; } @Override public void markExistingRecordsAsDeleted(Long newClassId, Long sourceClassId){ baseClassCourseMapper.markExistingRecordsAsDeleted(newClassId, sourceClassId); } @Override @Transactional public Boolean duplicateCourseBook(ClassCourseReuseDto dto){ // 根据旧的学期和班级找到所有的课程 MPJLambdaWrapper baseClassCourseLambdaQueryWrapper = new MPJLambdaWrapper<>(); baseClassCourseLambdaQueryWrapper .select(BaseClassCourse.class, x -> VoToColumnUtil.fieldsToColumns(BaseClassCourse.class).contains(x.getProperty())) .innerJoin(BaseClassCourse.class, BaseClassCourse::getClassId, BaseClassAdminCourse::getId) .eq(BaseClassAdminCourse::getClassId, dto.getOldClassId()) .eq(BaseClassAdminCourse::getBaseSemesterId, dto.getOldBaseSemesterId()) ; List baseClassCourseList = baseClassAdminCourseMapper.selectJoinList(BaseClassCourse.class, baseClassCourseLambdaQueryWrapper); if(baseClassCourseList == null || baseClassCourseList.isEmpty()){ throw new MyException("被复用的学期的被复用班级没有可以复用的课程!"); } // 已经维护了课程教材信息的班级和所在学期 List baseClassAdminCourses = baseClassAdminCourseMapper.selectList( Wrappers.lambdaQuery(BaseClassAdminCourse.class) .eq(BaseClassAdminCourse::getDeleteMark, DeleteMark.NODELETE.getCode()) ); Map classSemester = new HashMap<>(); for (BaseClassAdminCourse baseClassAdminCourse : baseClassAdminCourses) { classSemester.put(baseClassAdminCourse.getClassId() + "_" + baseClassAdminCourse.getBaseSemesterId(), baseClassAdminCourse.getId()); } // 判断复用的学期复用的班级是否已经进入了班级课程列表 // 判断本学期本班级是否已经加入课程管理的班级中 List classAdminCourseIds = new ArrayList<>(); for (Long classId : dto.getNewClassIds()){ String newClassSemester = classId + "_" + dto.getNewBaseSemesterId(); Long classAdminCourseId = null; BaseClassAdminCourse baseClassAdminCourse = null; if(ObjectUtils.isNotEmpty(classSemester) && ObjectUtils.isNotEmpty(classSemester.get(newClassSemester))){ classAdminCourseId = classSemester.get(newClassSemester); } else { baseClassAdminCourse = new BaseClassAdminCourse(); baseClassAdminCourse.setClassId(classId); baseClassAdminCourse.setBaseSemesterId(dto.getNewBaseSemesterId()); baseClassAdminCourseMapper.insert(baseClassAdminCourse); classAdminCourseId = baseClassAdminCourse.getId(); classSemester.put(newClassSemester, classAdminCourseId); } classAdminCourseIds.add(classAdminCourseId); } //删除班级的所有课程教材 LambdaQueryWrapper removeLambdaQueryWrapper = new LambdaQueryWrapper<>(); removeLambdaQueryWrapper .in(BaseClassCourse::getClassId, classAdminCourseIds) ; this.remove(removeLambdaQueryWrapper); List newBaseClassCourseList = new ArrayList<>(); for (Long classAdminCourseId : classAdminCourseIds){ for (BaseClassCourse baseClassCourse : baseClassCourseList){ Long courseId = baseClassCourse.getCourseId(); Long textbookId = baseClassCourse.getTextbookId(); newBaseClassCourseList.add(new BaseClassCourse(){{ setClassId(classAdminCourseId); setCourseId(courseId); setTextbookId(textbookId); setCreateDate(new Date()); }}); } } this.saveBatch(newBaseClassCourseList); return true; } @Override @Transactional public Boolean settingUpClasses(AddBaseClassAdminCourseDto dto) { if(ObjectUtils.isEmpty(dto.getBaseSemesterId())){ throw new MyException("请选择需要设置课程的学期"); } if(ObjectUtils.isEmpty(dto.getClassIds()) || dto.getClassIds().isEmpty()){ throw new MyException("请选择需要设置课程的班级"); } BaseClassAdminCourse baseClassAdminCourse; for(Long classId : dto.getClassIds()){ baseClassAdminCourse = new BaseClassAdminCourse(); baseClassAdminCourse.setBaseSemesterId(dto.getBaseSemesterId()); baseClassAdminCourse.setClassId(classId); baseClassAdminCourseMapper.insert(baseClassAdminCourse); } return true; } @Override @Transactional public Boolean deleteSettingUpClasses(List ids) { // 先移除已经添加的课程数据 LambdaUpdateWrapper baseClassCourseLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); baseClassCourseLambdaUpdateWrapper .in(BaseClassCourse::getClassId, ids) ; this.remove(baseClassCourseLambdaUpdateWrapper); baseClassAdminCourseMapper.deleteBatchIds(ids); return true; } @Override public Map> getSemesterTree() { List> semesterData = baseClassCourseMapper.getAllSemesterNames(); Map> tree = new TreeMap<>(); for (Map data : semesterData) { String name = (String) data.get("name"); String[] parts = name.split("年"); String year = parts[0]; // 年份 String semesterType = parts[1].substring(0, parts[1].length() - 1); // 学期类型(春期/秋期) Long id = Long.parseLong(data.get("id").toString()); if (!tree.containsKey(year + "年")) { tree.put(year + "年", new HashMap<>()); } Map yearMap = tree.get(year + "年"); if (semesterType.equals("春")) { yearMap.put("springName", name); yearMap.put("springId", id); } else if (semesterType.equals("秋")) { yearMap.put("autumnName", name); yearMap.put("autumnId", id); } } return tree; } @Override public Long GetClassIdByName(String name){ return baseClassCourseMapper.getClassIdByName(name); } @Override public Long GetCourseIdByName(String name){ return baseClassCourseMapper.getCourseIdByName(name); } @Override public Long GetTextbookIdByName(String name){ return baseClassCourseMapper.getBookIdByName(name); } @Override public Long GetBaseSemesterIdByName(String name) { return baseClassCourseMapper.getBaseSemesterIdByName(name); } @Override public boolean checkExits(Long classId,Long courseId,Long textbookId){ return baseClassCourseMapper.checkExits(classId, courseId, textbookId); } @Override public boolean checkExitsWithoutTextbook(Long classId, Long courseId) { return this.baseMapper.checkExitsWithoutTextbook(classId, courseId); } @Override public ByteArrayOutputStream classCourseTextbookExportQuery(ClassCourseTextbookExportQueryDto dto) throws IOException { MPJLambdaWrapper baseClassCourseMPJLambdaWrapper = new MPJLambdaWrapper<>(); baseClassCourseMPJLambdaWrapper .disableSubLogicDel() .selectAs(BaseSemester::getName, ClassCourseTextbookExportQueryVo::getSemester) .selectAs(Department::getName, ClassCourseTextbookExportQueryVo::getDeptName) .selectAs(BaseClass::getId, ClassCourseTextbookExportQueryVo::getClassId) .selectAs(BaseClass::getName, ClassCourseTextbookExportQueryVo::getClassName) .selectAs(BaseCourseSubject::getName, ClassCourseTextbookExportQueryVo::getCourseName) .selectAs(Textbook::getBookName, ClassCourseTextbookExportQueryVo::getTextbookName) .selectAs(Textbook::getUseType, ClassCourseTextbookExportQueryVo::getUseType) .selectAs(Textbook::getPrice, ClassCourseTextbookExportQueryVo::getPrice) .selectAs(Textbook::getDiscountPrice, ClassCourseTextbookExportQueryVo::getDiscountPrice) .leftJoin(BaseClassCourse.class, wrapper -> wrapper .eq(BaseClassCourse::getClassId, BaseClassAdminCourse::getId) .eq(BaseClassCourse::getDeleteMark, DeleteMark.NODELETE.getCode()) ) .leftJoin(BaseSemester.class, BaseSemester::getId, BaseClassAdminCourse::getBaseSemesterId) .leftJoin(BaseClass.class, BaseClass::getId, BaseClassAdminCourse::getClassId) .leftJoin(Department.class, Department::getId, BaseClass::getOrgId) .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, BaseClassCourse::getCourseId) .leftJoin(Textbook.class, Textbook::getId, BaseClassCourse::getTextbookId) .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType, wrapper -> wrapper .selectAs(DictionaryDetail::getName, ClassCourseTextbookExportQueryVo::getTextbookType) ) .in(ObjectUtils.isNotEmpty(dto.getClassIds()) && !dto.getClassIds().isEmpty(), BaseClassAdminCourse::getClassId, dto.getClassIds()) .like(StringUtils.isNotBlank(dto.getClassName()), BaseClass::getName, dto.getClassName()) .eq(ObjectUtils.isNotEmpty(dto.getDeptId()), Department::getId, dto.getDeptId()) // .having(ObjectUtils.isNotEmpty(dto.getCourseSet()) && dto.getCourseSet() == 1, "HAVING LENGTH(course_name) > 0") // .having(ObjectUtils.isNotEmpty(dto.getCourseSet()) && dto.getCourseSet() == 2, "HAVING COALESCE(LENGTH(course_name), 0) = 0") .eq(ObjectUtils.isNotEmpty(dto.getSemester()),BaseClassAdminCourse::getBaseSemesterId, dto.getSemester()) .orderByDesc(BaseCourseSubject::getName) .orderByDesc(Textbook::getBookName) ; List dataList = baseClassAdminCourseMapper.selectJoinList(ClassCourseTextbookExportQueryVo.class, baseClassCourseMPJLambdaWrapper); // 根据班级分组 Map> dataMapByClassId = dataList.stream() .collect(Collectors.groupingBy( ClassCourseTextbookExportQueryVo::getClassId, LinkedHashMap::new, // 指定使用LinkedHashMap来保持顺序 Collectors.toList() )); List classIds = dataList.stream() .filter(c -> ObjectUtils.isNotEmpty(c.getClassId())) .map(ClassCourseTextbookExportQueryVo::getClassId) .collect(Collectors.toList()); if(classIds.isEmpty()){ throw new MyException("导出数据中班级有误,请刷新重试"); } // 获取班级人数 MPJLambdaWrapper baseStudentSchoolRollMPJLambdaWrapper = new MPJLambdaWrapper<>(); baseStudentSchoolRollMPJLambdaWrapper .selectAs(BaseStudentSchoolRoll::getClassId, BaseStudentSchoolRoll::getClassId) .selectCount(BaseStudentSchoolRoll::getId, BaseStudentSchoolRoll::getDeleteMark) .in(BaseStudentSchoolRoll::getClassId, classIds) .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode()) .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode()) .groupBy(BaseStudentSchoolRoll::getClassId) ; List baseStudentSchoolRolls = baseStudentSchoolRollMapper.selectJoinList(BaseStudentSchoolRoll.class, baseStudentSchoolRollMPJLambdaWrapper); Map stuNumMap = baseStudentSchoolRolls.stream() .collect(Collectors.toMap(BaseStudentSchoolRoll::getClassId, BaseStudentSchoolRoll::getDeleteMark, (k1,k2) -> k1)); // 处理数据 for (ClassCourseTextbookExportQueryVo c : dataList){ // 处理使用学期 if(ObjectUtils.isNotEmpty(c.getUseType())){ String useType = UseSemesterTypeEnum.getValue(c.getUseType()); c.setUseTypeCn(useType); }else { c.setUseTypeCn("未知"); } // 处理班级人数 Integer stuNum = stuNumMap.get(c.getClassId()); if(ObjectUtils.isNotEmpty(stuNum)){ c.setStudentNum(stuNum); // 处理总价 if(ObjectUtils.isNotEmpty(c.getDiscountPrice())){ BigDecimal totalPrices = c.getDiscountPrice().multiply(BigDecimal.valueOf(stuNum)); c.setTotalPrices(totalPrices); }else { c.setTotalPrices(BigDecimal.ZERO); } }else { c.setStudentNum(0); } } // 开始写入 Workbook workbook = new XSSFWorkbook(); // 创建一个工作表(sheet) String sheetName = "sheet1"; Sheet sheet = workbook.createSheet(sheetName); List importConfigs = allFields(new ClassCourseTextbookExportQueryVo()); // 表头 createHead(workbook, sheet, importConfigs, 0); // 内容 int dataRowNumber = 1; Font font = workbook.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short)12); CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setFont(font); // 将字体应用到样式 cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); cellStyle.setAlignment(HorizontalAlignment.CENTER); List> inList = new ArrayList<>(); List mergeStepList = new ArrayList<>(); for (Map.Entry> entry : dataMapByClassId.entrySet()){ Long key = entry.getKey(); List value = entry.getValue(); // 小计合计 BigDecimal totalDiscountPrice = BigDecimal.ZERO; for (ClassCourseTextbookExportQueryVo c : value){ totalDiscountPrice = totalDiscountPrice.add(ObjectUtils.isNotEmpty(c.getDiscountPrice()) ? c.getDiscountPrice() : BigDecimal.ZERO); } // 总价合计 BigDecimal totalPriceTotal = BigDecimal.ZERO; for (ClassCourseTextbookExportQueryVo c : value){ totalPriceTotal = totalPriceTotal.add(ObjectUtils.isNotEmpty(c.getTotalPrices()) ? c.getTotalPrices() : BigDecimal.ZERO); } for (ClassCourseTextbookExportQueryVo c : value){ c.setTotalDiscountPrice(totalDiscountPrice); c.setTotalPriceTotal(totalPriceTotal); } // 开始写入 for (ClassCourseTextbookExportQueryVo c : value){ List date = new ArrayList<>(); date.add(c.getSemester()); date.add(c.getDeptName()); date.add(c.getClassName()); date.add(c.getCourseName()); date.add(c.getTextbookName()); date.add(c.getUseTypeCn()); date.add(c.getTextbookType()); date.add(ObjectUtils.isNotEmpty(c.getPrice()) ? c.getPrice().toString() : "0"); date.add(ObjectUtils.isNotEmpty(c.getDiscountPrice()) ? c.getDiscountPrice().toString() : "0"); date.add(ObjectUtils.isNotEmpty(c.getTotalDiscountPrice()) ? c.getTotalDiscountPrice().toString() : "0"); date.add(c.getStudentNum() + ""); date.add(ObjectUtils.isNotEmpty(c.getTotalPrices()) ? c.getTotalPrices().toString() : "0"); date.add(ObjectUtils.isNotEmpty(c.getTotalPriceTotal()) ? c.getTotalPriceTotal().toString() : "0"); inList.add(date); } mergeStepList.add(value.size()); } Cell cell; for (List rowData : inList) { Row dataRow = sheet.createRow(dataRowNumber); int size = rowData.size(); for (int i = 0; i < size; i++) { cell = dataRow.createCell(i); cell.setCellValue(rowData.get(i)); cell.setCellStyle(cellStyle); } dataRowNumber++; } // 合并 dataRowNumber = 1; for (Integer step : mergeStepList){ if(step == 1){ dataRowNumber++; } if(step > 1){ sheet.addMergedRegion(new CellRangeAddress(dataRowNumber, dataRowNumber + step - 1, 9, 9)); sheet.addMergedRegion(new CellRangeAddress(dataRowNumber, dataRowNumber + step - 1, 10, 10)); sheet.addMergedRegion(new CellRangeAddress(dataRowNumber, dataRowNumber + step - 1, 12, 12)); dataRowNumber = dataRowNumber + step; } } for (int i = 0; i < importConfigs.size(); i++) { sheet.autoSizeColumn(i); } //写入文件 ByteArrayOutputStream bot = new ByteArrayOutputStream(); workbook.write(bot); return bot; } }