Explorar o código

课表导出excel优化

大数据与最优化研究所 hai 1 ano
pai
achega
ad96179b61

+ 100 - 11
src/main/java/com/xjrsoft/module/courseTable/service/impl/CourseTableServiceImpl.java

@@ -7,7 +7,12 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
 import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.excel.write.metadata.WriteTable;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -21,6 +26,8 @@ import com.xjrsoft.common.enums.TimeNumberEnum;
 import com.xjrsoft.common.enums.TimePeriodEnum;
 import com.xjrsoft.common.enums.WeekEnum;
 import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.utils.excel.ExcelFillCellMergePrevColUtil;
+import com.xjrsoft.common.utils.excel.ExcelMergeUtil;
 import com.xjrsoft.config.TimetableConfig;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseSemester;
@@ -53,6 +60,10 @@ import com.xjrsoft.module.textbook.vo.TextbookClaimExportQueryVo;
 import com.xjrsoft.module.textbook.vo.TextbookIssueRecordExcelVo;
 import io.swagger.models.auth.In;
 import lombok.AllArgsConstructor;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.apache.poi.xwpf.usermodel.XWPFTable;
@@ -362,7 +373,7 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
         List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList = buildScheduleWeekExportQueryList(courseTableVo);
 
         // 将数据写入Excel文件
-        writeScheduleWeekExportToExcel(outputStream, scheduleWeekExportQueryVoList);
+        writeScheduleWeekExportToExcel(courseTableVo, outputStream, scheduleWeekExportQueryVoList);
 
         return outputStream;
     }
@@ -429,10 +440,10 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
                     for (int i = 1; i <= 7; i++) {
                         CourseDetailVo courseDetailVo = courseDetailVoByWeeksMap.get(i);
                         if (courseDetailVo != null) {
-                            String courseInfo = courseDetailVo.getCourseName() + " " +
-                                    courseDetailVo.getTeacherName() + " " +
-                                    courseDetailVo.getClassName() + " " +
-                                    courseDetailVo.getClassroomName() + " ";
+                            String courseInfo = courseDetailVo.getCourseName() + "\n" +
+                                    courseDetailVo.getTeacherName() + "\n" +
+                                    courseDetailVo.getClassName() + "\n" +
+                                    courseDetailVo.getClassroomName() + "\n";
                             switch (i) {
                                 case 1:
                                     scheduleWeekExportQueryVo.setMonday(courseInfo);
@@ -467,13 +478,91 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
         return scheduleWeekExportQueryVoList;
     }
 
-    private void writeScheduleWeekExportToExcel(ByteArrayOutputStream outputStream, List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList) {
+    private void writeScheduleWeekExportToExcel(CourseTableVo courseTableVo, ByteArrayOutputStream outputStream, List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList) {
+        // 创建内容样式
+        WriteCellStyle contentWriteCellStyle = createContentCellStyle();
+        // 创建头部样式
+        WriteCellStyle headWriteCellStyle = createHeadCellStyle();
         // 将数据写入Excel文件
-        EasyExcel.write(outputStream, ScheduleWeekExportQueryVo.class)
-                .automaticMergeHead(true)
-                .excelType(ExcelTypeEnum.XLSX)
-                .sheet()
-                .doWrite(scheduleWeekExportQueryVoList);
+        try (ExcelWriter excelWriter = EasyExcel.write(outputStream, ScheduleWeekExportQueryVo.class)
+                .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle))
+                .build()) {
+
+            writeSheetHead(courseTableVo, excelWriter);
+
+            writeSheetContent(excelWriter, scheduleWeekExportQueryVoList);
+
+        }
+    }
+
+    private void writeSheetContent(ExcelWriter excelWriter, List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList) {
+        int mergeRowIndex = 2;
+        int[] mergeColumeIndex = {0};
+        ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex);
+
+        WriteTable writeSheetContentTable = EasyExcel.writerTable(1).needHead(Boolean.TRUE).automaticMergeHead(Boolean.TRUE).registerWriteHandler(excelFillCellMergeStrategy).build();
+        excelWriter.write(scheduleWeekExportQueryVoList, EasyExcel.writerSheet("模板").build(), writeSheetContentTable);
+    }
+
+    private void writeSheetHead(CourseTableVo courseTableVo, ExcelWriter excelWriter) {
+        List<List<String>> sheetHeadList = new ArrayList<>();
+        sheetHeadList.add(Collections.singletonList(courseTableVo.getSemesterName() + " "
+                + ((courseTableVo.getTeacherName() != null) ? courseTableVo.getTeacherName() : courseTableVo.getClassName()) + " "
+                + courseTableVo.getWeek() + " "
+                + "课程表"));
+
+        ExcelFillCellMergePrevColUtil sheetHeadColumn = new ExcelFillCellMergePrevColUtil();
+        sheetHeadColumn.add(0, 0, 8);
+
+        WriteTable writeSheetHeadTable = EasyExcel.writerTable(0).needHead(Boolean.TRUE).head(sheetHeadList).registerWriteHandler(sheetHeadColumn).build();
+        excelWriter.write(new ArrayList<>(), EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build(), writeSheetHeadTable);
+    }
+
+    private WriteCellStyle createContentCellStyle() {
+        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        contentWriteCellStyle.setWrapped(true);
+
+        WriteFont contentWriteFont = new WriteFont();
+        contentWriteFont.setFontHeightInPoints((short) 12);
+        contentWriteFont.setFontName("宋体");
+        contentWriteCellStyle.setWriteFont(contentWriteFont);
+
+        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
+        contentWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
+        contentWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
+        contentWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
+        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
+        contentWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
+
+        return contentWriteCellStyle;
+    }
+
+    private WriteCellStyle createHeadCellStyle() {
+        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+        WriteFont headWriteFont = new WriteFont();
+        headWriteFont.setFontName("宋体");
+        headWriteFont.setFontHeightInPoints((short) 14);
+        headWriteFont.setBold(true);
+        headWriteCellStyle.setWriteFont(headWriteFont);
+
+        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
+        headWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
+        headWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+        headWriteCellStyle.setBorderRight(BorderStyle.THIN);
+        headWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
+        headWriteCellStyle.setBorderTop(BorderStyle.THIN);
+        headWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
+        headWriteCellStyle.setWrapped(true);
+        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        headWriteCellStyle.setShrinkToFit(true);
+
+        return headWriteCellStyle;
     }
 
     /**

+ 6 - 11
src/main/java/com/xjrsoft/module/schedule/controller/ScheduleController.java

@@ -235,18 +235,13 @@ public class ScheduleController {
         return jsonParser.parse(result).getAsJsonObject();
     }
 
-//    @PostMapping("/schedule-week-export-query")
-//    @ApiOperation(value = "按周导出课表")
-//    public ResponseEntity<byte[]> scheduleWeekExportQuery(@Valid @RequestBody ScheduleWeekExportQueryDto dto) {
-    @GetMapping("/schedule-week-export-query")
+    @PostMapping("/schedule-week-export-query")
     @ApiOperation(value = "按周导出课表")
-    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid ScheduleWeekExportQueryDto dto) {
-        dto = new ScheduleWeekExportQueryDto(){{
-            setSemesterId(1753983822311616512L);
-            setCourseType("teacher");
-            setWeek(3);
-            setTeacherName("彭霞");
-        }};
+    public ResponseEntity<byte[]> scheduleWeekExportQuery(@Valid @RequestBody ScheduleWeekExportQueryDto dto) {
+//    @GetMapping("/schedule-week-export-query")
+//    @ApiOperation(value = "按周导出课表")
+//    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid ScheduleWeekExportQueryDto dto) {
+
         ByteArrayOutputStream bot = courseTableService.listScheduleWeekExportQuery(dto);
         return RT.fileStream(bot.toByteArray(), "scheduleWeek" + ExcelTypeEnum.XLSX.getValue());
     }

+ 178 - 121
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java

@@ -588,137 +588,194 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
     @Override
     public ByteArrayOutputStream listTextbookClaimExportQuery(TextbookClaimExportQueryDto dto) {
         List<TextbookClaimExportQueryVo> customerList = textbookTextbookMapper.listTextbookClaimExportQuery(dto);
-        ByteArrayOutputStream bot = new ByteArrayOutputStream();
-
-        // 创建内容样式
-        WriteCellStyle contentWriteCellStyle = createContentCellStyle();
-        // 创建头部样式
-        WriteCellStyle headWriteCellStyle = createHeadCellStyle();
-
-        try (ExcelWriter excelWriter = EasyExcel.write(bot, TextbookClaimExportQueryVo.class)
-                .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle))
-                .build()) {
-
-            int rowIndex = 0;
-            int tableIndex = 0;
-
-            writeSheetHead(excelWriter, rowIndex, tableIndex);
-
-            processTextbookClaimData(excelWriter, customerList, rowIndex, tableIndex);
-
-        }
-
-        return bot;
-    }
 
-    private WriteCellStyle createContentCellStyle() {
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        //内容样式
         WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
-        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
-        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
-        contentWriteCellStyle.setWrapped(true);
-
+        //设计内容居中
+        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
+        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
+        contentWriteCellStyle.setWrapped(true); //设置自动换行;
+        // 设置字体
         WriteFont contentWriteFont = new WriteFont();
-        contentWriteFont.setFontHeightInPoints((short) 12);
-        contentWriteFont.setFontName("宋体");
-        contentWriteCellStyle.setWriteFont(contentWriteFont);
-
-        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
-        contentWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
-        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
-        contentWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
-        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
-        contentWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
-        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
-        contentWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
-
-        return contentWriteCellStyle;
-    }
-
-    private WriteCellStyle createHeadCellStyle() {
+        contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
+        contentWriteFont.setFontName("宋体"); //设置字体名字
+        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;
+        //设置样式;
+        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
+        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
+        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
+        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
+        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
+        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
+        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
+        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;
+
+        //设置头部样式
         WriteCellStyle headWriteCellStyle = new WriteCellStyle();
-        WriteFont headWriteFont = new WriteFont();
-        headWriteFont.setFontName("宋体");
-        headWriteFont.setFontHeightInPoints((short) 14);
-        headWriteFont.setBold(true);
-        headWriteCellStyle.setWriteFont(headWriteFont);
-
-        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
-        headWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
-        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
-        headWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
-        headWriteCellStyle.setBorderRight(BorderStyle.THIN);
-        headWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
-        headWriteCellStyle.setBorderTop(BorderStyle.THIN);
-        headWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
-        headWriteCellStyle.setWrapped(true);
-        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
-        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
-        headWriteCellStyle.setShrinkToFit(true);
-
-        return headWriteCellStyle;
-    }
-
-    private void writeSheetHead(ExcelWriter excelWriter, int rowIndex, int tableIndex) {
-        List<List<String>> sheetHeadList = new ArrayList<>();
-        sheetHeadList.add(Collections.singletonList("铜梁执教中心班级教材教辅发放情况表"));
-
-        ExcelFillCellMergePrevColUtil sheetHeadColumn = new ExcelFillCellMergePrevColUtil();
-        sheetHeadColumn.add(rowIndex, 0, 9);
-
-        WriteTable writeSheetHeadTable = EasyExcel.writerTable(tableIndex).needHead(Boolean.TRUE).head(sheetHeadList).registerWriteHandler(sheetHeadColumn).build();
-        excelWriter.write(new ArrayList<>(), EasyExcel.writerSheet("模板").build(), writeSheetHeadTable);
-    }
-
-    private void processTextbookClaimData(ExcelWriter excelWriter, List<TextbookClaimExportQueryVo> customerList, int rowIndex, int tableIndex) {
-        // 处理数据逻辑
-        // 写入数据到Excel表格
-        for (TextbookClaimExportQueryVo customer : customerList) {
-            List<List<String>> tableHeadList = new ArrayList<>();
-            tableHeadList.add(Collections.singletonList("日期:" + customer.getBaseSemesterIdCn() + " 班级:" + customer.getClassIdCn() + " 班主任:" + customer.getHeadTeacherName() + " 教室:" + customer.getClassRoomName()));
+        // 背景颜色
+//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
+//        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
 
-            ExcelFillCellMergePrevColUtil tableHeadColumn = new ExcelFillCellMergePrevColUtil();
-            tableHeadColumn.add(++rowIndex, 0, 9);
-
-            WriteTable writeTableHeadTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.TRUE).head(tableHeadList).registerWriteHandler(tableHeadColumn).build();
-            excelWriter.write(new ArrayList<>(), EasyExcel.writerSheet("模板").build(), writeTableHeadTable);
-
-            Map<String, List<TextbookClaimExportQueryVo>> groupedByTextbookType = customerList.stream()
-                    .filter(c -> c.getBaseSemesterId().equals(customer.getBaseSemesterId()) && c.getClassId().equals(customer.getClassId()))
-                    .collect(Collectors.groupingBy(TextbookClaimExportQueryVo::getTextbookTypeCn));
-
-            BigDecimal total = BigDecimal.ZERO;
-
-            for (Map.Entry<String, List<TextbookClaimExportQueryVo>> entry : groupedByTextbookType.entrySet()) {
-                List<TextbookClaimExportQueryVo> group = entry.getValue();
-
-                BigDecimal subtotal = group.stream()
-                        .map(TextbookClaimExportQueryVo::getSubtotal)
-                        .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-                group.add(new TextbookClaimExportQueryVo("小计", subtotal));
-                total = total.add(subtotal);
+        // 字体
+        WriteFont headWriteFont = new WriteFont();
+        headWriteFont.setFontName("宋体");//设置字体名字
+        headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
+        headWriteFont.setBold(true);//字体加粗
+        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
+
+        // 样式
+        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
+        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
+        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
+        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
+        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
+        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
+        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
+        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
+
+        headWriteCellStyle.setWrapped(true);  //设置自动换行;
+
+        //设置头部标题居中
+        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
+        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
+        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
+
+        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
+        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
+                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
+        try (ExcelWriter excelWriter = EasyExcel.write(bot, TextbookClaimExportQueryVo.class).registerWriteHandler(horizontalCellStyleStrategy).build()) {
+            //已经写入的行
+            int rowIndex = 0;
+            //已经写入的表
+            int tableIndex = 0;
+            // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
+            WriteSheet writeSheet = EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build();
+
+            //sheet的表头
+            List<List<String>> sheetHeadList = new ArrayList<List<String>>();
+            sheetHeadList.add(new ArrayList<String>(){{
+                add("铜梁执教中心班级教材教辅发放情况表");
+            }});
+            //sheet的表头合并策略
+            ExcelFillCellMergePrevColUtil sheetHeadColumn = new ExcelFillCellMergePrevColUtil();
+            sheetHeadColumn.add(rowIndex, 0, 9);
+            //这是一个sheet表头的table
+            WriteTable writeSheetHeadTable = EasyExcel.writerTable(tableIndex).needHead(Boolean.TRUE).head(sheetHeadList).registerWriteHandler(sheetHeadColumn).build();
+            excelWriter.write(new ArrayList<>(), writeSheet, writeSheetHeadTable);
+
+            //对返回的集合进行处理
+            //现针对学期进行分组
+            Map<Long, List<TextbookClaimExportQueryVo>> groupedBySemester = customerList.stream()
+                    .collect(Collectors.groupingBy(TextbookClaimExportQueryVo::getBaseSemesterId));
+            Iterator<Map.Entry<Long, List<TextbookClaimExportQueryVo>>> groupedBySemesterIterator = groupedBySemester.entrySet().iterator();
+            while (groupedBySemesterIterator.hasNext()) {
+                Map.Entry<Long, List<TextbookClaimExportQueryVo>> groupedBySemesterEntry = groupedBySemesterIterator.next();
+                Long key = groupedBySemesterEntry.getKey();
+                List<TextbookClaimExportQueryVo> value = groupedBySemesterEntry.getValue();
+
+                Map<Long, List<TextbookClaimExportQueryVo>> groupedBySemesterByClass = value.stream()
+                        .collect(Collectors.groupingBy(TextbookClaimExportQueryVo::getClassId));
+                Iterator<Map.Entry<Long, List<TextbookClaimExportQueryVo>>> groupedBySemesterByClassIdIterator = groupedBySemesterByClass.entrySet().iterator();
+                while (groupedBySemesterByClassIdIterator.hasNext()) {
+                    Map.Entry<Long, List<TextbookClaimExportQueryVo>> groupedBySemesterByClassIdEntry = groupedBySemesterByClassIdIterator.next();
+                    Long k = groupedBySemesterByClassIdEntry.getKey();
+                    List<TextbookClaimExportQueryVo> v = groupedBySemesterByClassIdEntry.getValue();
+
+                    //这是一个table的表头
+                    List<List<String>> tableHeadList = new ArrayList<List<String>>();
+                    tableHeadList.add(new ArrayList<String>(){{
+                        add("日期:" + v.get(0).getBaseSemesterIdCn() + " 班级:" + v.get(0).getClassIdCn() + " 班主任:" + v.get(0).getHeadTeacherName() + " 教室:" + v.get(0).getClassRoomName() + " ");
+                    }});
+                    //table的表头合并策略
+                    ExcelFillCellMergePrevColUtil tableHeadColumn = new ExcelFillCellMergePrevColUtil();
+                    tableHeadColumn.add(++rowIndex, 0, 9);
+                    //这是一个table表头的table
+                    WriteTable writeTableHeadTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.TRUE).head(tableHeadList).registerWriteHandler(tableHeadColumn).build();
+                    excelWriter.write(new ArrayList<>(), writeSheet, writeTableHeadTable);
+
+                    Map<String, List<TextbookClaimExportQueryVo>> groupedByTextbookType = v.stream()
+                            .collect(Collectors.groupingBy(TextbookClaimExportQueryVo::getTextbookTypeCn));
+                    Iterator<Map.Entry<String, List<TextbookClaimExportQueryVo>>> groupedByTextbookTypeIterator = groupedByTextbookType.entrySet().iterator();
+                    int index = 1;
+                    BigDecimal total = new BigDecimal("0");
+                    while (groupedByTextbookTypeIterator.hasNext()) {
+                        Map.Entry<String, List<TextbookClaimExportQueryVo>> groupedByTextbookTypeEntry = groupedByTextbookTypeIterator.next();
+                        String kk = groupedByTextbookTypeEntry.getKey();
+                        List<TextbookClaimExportQueryVo> vv = groupedByTextbookTypeEntry.getValue();
+                        if(index == 1){
+                            //添加小计
+                            ExcelFillCellMergePrevColUtil subtotalColumn = new ExcelFillCellMergePrevColUtil();
+                            subtotalColumn.add(rowIndex + vv.size() + 2, 1, 4);
+                            BigDecimal subtotal = new BigDecimal("0");
+                            for (TextbookClaimExportQueryVo tv : vv) {
+                                subtotal = subtotal.add(tv.getSubtotal());
+                            }
+                            BigDecimal finalSubtotal = subtotal;
+                            vv.add(new TextbookClaimExportQueryVo(){{
+                                setTextbookTypeCn(vv.get(0).getTextbookTypeCn());
+                                setBookName("小计");
+                                setSubtotal(finalSubtotal);
+                            }});
+                            total = total.add(finalSubtotal);
+
+                            // 调用合并单元格工具类,此工具类是根据工程名称相同则合并后面数据
+                            int mergeRowIndex = rowIndex + 1;
+                            int[] mergeColumeIndex = {0};
+                            ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex);
+
+                            // 第一次必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
+                            WriteTable writeContentTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.TRUE).registerWriteHandler(subtotalColumn).registerWriteHandler(excelFillCellMergeStrategy).build();
+                            // 第一次写入会创建头
+                            excelWriter.write(vv, writeSheet, writeContentTable);
+
+                            rowIndex += (1 + vv.size());
+                        }else {
+                            //添加小计
+                            ExcelFillCellMergePrevColUtil subtotalColumn = new ExcelFillCellMergePrevColUtil();
+                            subtotalColumn.add(rowIndex + vv.size() + 1, 1, 4);
+                            BigDecimal subtotal = new BigDecimal("0");
+                            for (TextbookClaimExportQueryVo tv : vv) {
+                                subtotal = subtotal.add(tv.getSubtotal());
+                            }
+                            BigDecimal finalSubtotal = subtotal;
+                            vv.add(new TextbookClaimExportQueryVo(){{
+                                setTextbookTypeCn(vv.get(0).getTextbookTypeCn());
+                                setBookName("小计");
+                                setSubtotal(finalSubtotal);
+                            }});
+                            total = total.add(finalSubtotal);
+                            // 调用合并单元格工具类,此工具类是根据工程名称相同则合并后面数据
+                            int mergeRowIndex = rowIndex;
+                            int[] mergeColumeIndex = {0};
+                            ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex);
 
-                ExcelFillCellMergePrevColUtil subtotalColumn = new ExcelFillCellMergePrevColUtil();
-                subtotalColumn.add(rowIndex + group.size() + 1, 1, 4);
+                            // 不需要头
+                            WriteTable writeContentTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.FALSE).registerWriteHandler(subtotalColumn).registerWriteHandler(excelFillCellMergeStrategy).build();
+                            excelWriter.write(vv, writeSheet, writeContentTable);
 
-                WriteTable writeContentTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.TRUE).registerWriteHandler(subtotalColumn).build();
-                excelWriter.write(group, EasyExcel.writerSheet("模板").build(), writeContentTable);
-                rowIndex += group.size();
+                            rowIndex += (vv.size());
+                        }
+                        index++;
+                    }
+                    //添加合计
+                    BigDecimal finalTotal = total;
+                    List<TextbookClaimExportQueryVo> totalList = new ArrayList<>();
+                    totalList.add(new TextbookClaimExportQueryVo(){{
+                        setTextbookTypeCn("合计");
+                        setSubtotal(finalTotal);
+                    }});
+                    //-合并策略
+                    ExcelFillCellMergePrevColUtil totaColumn = new ExcelFillCellMergePrevColUtil();
+                    totaColumn.add(++rowIndex, 0, 5);
+                    //这是一个合计的table
+                    WriteTable writeTotalTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.FALSE).registerWriteHandler(totaColumn).build();
+                    excelWriter.write(totalList, writeSheet, writeTotalTable);
+                }
             }
-
-            List<TextbookClaimExportQueryVo> totalList = new ArrayList<>();
-            totalList.add(new TextbookClaimExportQueryVo("合计", total));
-
-            ExcelFillCellMergePrevColUtil totalColumn = new ExcelFillCellMergePrevColUtil();
-            totalColumn.add(++rowIndex, 0, 5);
-
-            WriteTable writeTotalTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.FALSE).registerWriteHandler(totalColumn).build();
-            excelWriter.write(totalList, EasyExcel.writerSheet("模板").build(), writeTotalTable);
-
-            rowIndex++;
         }
+        return bot;
     }
-
     @Override
     @Transactional
     public Boolean deliverWarehouse(AddTextbookWarehouseRecordDto dto) {