Browse Source

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java
#	src/main/java/com/xjrsoft/module/textbook/vo/TextbookClaimExportQueryVo.java
dzx 1 năm trước cách đây
mục cha
commit
163ec792fa

+ 73 - 0
src/main/java/com/xjrsoft/common/utils/excel/CustomCellWriteWidthConfig.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.common.utils.excel;
+
+import cn.smallbun.screw.core.util.CollectionUtils;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.metadata.data.CellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CustomCellWriteWidthConfig extends AbstractColumnWidthStyleStrategy {
+
+    private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
+    @Override
+    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
+        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
+        if (needSetWidth) {
+            Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());
+
+            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
+            // 单元格文本长度大于60换行
+            if (columnWidth >= 0) {
+                if (columnWidth > 60) {
+                    columnWidth = 60;
+                }
+                Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
+                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
+                    maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
+                    Sheet sheet = writeSheetHolder.getSheet();
+                    sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
+                }
+            }
+        }
+    }
+    /**
+     * 计算长度
+     * @param cellDataList
+     * @param cell
+     * @param isHead
+     * @return
+     */
+    private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
+        if (isHead) {
+            return cell.getStringCellValue().getBytes().length;
+        } else {
+            CellData<?> cellData = cellDataList.get(0);
+            CellDataTypeEnum type = cellData.getType();
+            if (type == null) {
+                return -1;
+            } else {
+                switch (type) {
+                    case STRING:
+                        // 换行符(数据需要提前解析好)
+                        int index = cellData.getStringValue().indexOf("\n");
+                        return index != -1 ?
+                                cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;
+                    case BOOLEAN:
+                        return cellData.getBooleanValue().toString().getBytes().length;
+                    case NUMBER:
+                        return cellData.getNumberValue().toString().getBytes().length;
+                    default:
+                        return -1;
+                }
+            }
+        }
+    }
+}

+ 5 - 5
src/main/java/com/xjrsoft/module/textbook/controller/TextbookController.java

@@ -272,12 +272,12 @@ public class TextbookController {
         return RT.fileStream(bot.toByteArray(), "TextbookSubscription" + ExcelTypeEnum.XLSX.getValue());
     }
 
-//    @PostMapping("/textbook-claim-export-query")
-//    @ApiOperation(value = "教材发放记录条件导出")
-//    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid @RequestBody TextbookClaimExportQueryDto dto) {
-    @GetMapping("/textbook-claim-export-query")
+    @PostMapping("/textbook-claim-export-query")
     @ApiOperation(value = "教材发放记录条件导出")
-    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid TextbookClaimExportQueryDto dto) {
+    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid @RequestBody TextbookClaimExportQueryDto dto) {
+//    @GetMapping("/textbook-claim-export-query")
+//    @ApiOperation(value = "教材发放记录条件导出")
+//    public ResponseEntity<byte[]> textbookClaimExportQuery(@Valid TextbookClaimExportQueryDto dto) {
         ByteArrayOutputStream bot = textbookService.listTextbookClaimExportQuery(dto);
         return RT.fileStream(bot.toByteArray(), "TextbookClaim" + ExcelTypeEnum.XLSX.getValue());
     }

+ 173 - 27
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java

@@ -5,9 +5,11 @@ 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.WriteSheet;
 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.StringUtils;
@@ -20,10 +22,11 @@ import com.xjrsoft.common.enums.SubscriptionTypeEnum;
 import com.xjrsoft.common.enums.TextbookTypeEnum;
 import com.xjrsoft.common.enums.WarehouseModeEnum;
 import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.utils.excel.CustomCellWriteWidthConfig;
 import com.xjrsoft.common.utils.excel.ExcelFillCellMergePrevColUtil;
+import com.xjrsoft.common.utils.excel.ExcelMergeUtil;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseSemester;
-import com.xjrsoft.module.base.mapper.BaseClassMapper;
 import com.xjrsoft.module.base.service.IBaseClassService;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.textbook.dto.*;
@@ -35,15 +38,15 @@ import com.xjrsoft.module.textbook.service.IWfExerciseBookService;
 import com.xjrsoft.module.textbook.service.IWfTextbookSubscriptionService;
 import com.xjrsoft.module.textbook.vo.*;
 import lombok.AllArgsConstructor;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -555,7 +558,7 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
         List<TextbookSubscriptionExportQueryVo> result = textbookTextbookMapper.listTextbookSubscriptionExportQuery(dto);
         //将班级转换为中文
         for(TextbookSubscriptionExportQueryVo to: result){
-            if(to.getClassIds() != null && !to.getClassIds().equals("")){
+            if(to != null && to.getClassIds() != null && !("").equals(to.getClassIds())){
                 List<Long> classIdList = new ArrayList<>();
                 String[] classIdStrs = to.getClassIds().split(",");
                 for (String classIdStr : classIdStrs){
@@ -585,7 +588,61 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
         List<TextbookClaimExportQueryVo> customerList = textbookTextbookMapper.listTextbookClaimExportQuery(dto);
 
         ByteArrayOutputStream bot = new ByteArrayOutputStream();
-        try (ExcelWriter excelWriter = EasyExcel.write(bot, TextbookClaimExportQueryVo.class).build()) {
+        //内容样式
+        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((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();
+        // 背景颜色
+//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
+//        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
+
+        // 字体
+        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;
             //已经写入的表
@@ -605,27 +662,116 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
             WriteTable writeSheetHeadTable = EasyExcel.writerTable(tableIndex).needHead(Boolean.TRUE).head(sheetHeadList).registerWriteHandler(sheetHeadColumn).build();
             excelWriter.write(new ArrayList<>(), writeSheet, writeSheetHeadTable);
 
-            for (int i = 0; i < 3; i++){
-                //这是一个table的表头
-                List<List<String>> tableHeadList = new ArrayList<List<String>>();
-                tableHeadList.add(new ArrayList<String>(){{
-                    add("日期:2023春期 班级:23数控1班 班主任:路童话 教室:4502");
-                }});
-                //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);
-                // 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
-                WriteTable writeContentTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.TRUE).build();
-                // 第一次写入会创建头
-                excelWriter.write(customerList, writeSheet, writeContentTable);
-                rowIndex += (1 + customerList.size());
+            //对返回的集合进行处理
+            //现针对学期进行分组
+            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);
+
+                            // 不需要头
+                            WriteTable writeContentTable = EasyExcel.writerTable(++tableIndex).needHead(Boolean.FALSE).registerWriteHandler(subtotalColumn).registerWriteHandler(excelFillCellMergeStrategy).build();
+                            excelWriter.write(vv, writeSheet, writeContentTable);
+
+                            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);
+                }
             }
         }
-
-        // EasyExcel.write(bot, TextbookClaimExportQueryVo.class).automaticMergeHead(true).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);
         return bot;
     }
 

+ 13 - 0
src/main/java/com/xjrsoft/module/textbook/vo/TextbookClaimExportQueryVo.java

@@ -20,11 +20,24 @@ public class TextbookClaimExportQueryVo {
     @ExcelIgnore
     private Long baseSemesterId;
 
+    @ExcelIgnore
+    private String baseSemesterIdCn;
+
     @ExcelIgnore
     private Long classId;
 
+    @ExcelIgnore
+    private String classIdCn;
+
+    @ExcelIgnore
+    private String headTeacherName;
+
+    @ExcelIgnore
+    private String classRoomName;
+
     @ExcelIgnore
     private Long textbookId;
+
     /**
      * 教材类型(xjr_dictionary_item[textbook_type])
      */