云
2 天以前 4966ba8b88ca9d6f3a7f93489d0e18a78a44a3c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package cn.iocoder.yudao.framework.excel.core.handler;
 
import cn.idev.excel.write.handler.CellWriteHandler;
import cn.idev.excel.write.handler.context.CellWriteHandlerContext;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.apache.poi.ss.usermodel.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
 
/** 仅修改必填表头字体颜色;不改变表头文本,以免破坏导入匹配。 */
public class RequiredHeaderWriteHandler implements CellWriteHandler {
    private final Map<Short, CellStyle> redStyles = new HashMap<>();
    @Override public int order() { return 50000; }
    @Override public void afterCellDispose(CellWriteHandlerContext context) {
        if (!Boolean.TRUE.equals(context.getHead()) || context.getHeadData() == null) return;
        Field field = context.getHeadData().getField();
        if (field == null || !required(field)) return;
        Cell cell = context.getCell();
        Workbook workbook = cell.getSheet().getWorkbook();
        CellStyle old = cell.getCellStyle();
        CellStyle style = redStyles.computeIfAbsent(old.getIndex(), index -> {
            CellStyle copy = workbook.createCellStyle();
            copy.cloneStyleFrom(old);
            Font source = workbook.getFontAt(old.getFontIndex());
            Font font = workbook.createFont();
            font.setFontName(source.getFontName()); font.setFontHeight(source.getFontHeight());
            font.setBold(source.getBold()); font.setItalic(source.getItalic());
            font.setUnderline(source.getUnderline()); font.setStrikeout(source.getStrikeout());
            font.setTypeOffset(source.getTypeOffset()); font.setCharSet(source.getCharSet());
            font.setColor(IndexedColors.RED.getIndex());
            copy.setFont(font);
            return copy;
        });
        cell.setCellStyle(style);
    }
    private boolean required(Field field) {
        if (field.isAnnotationPresent(ExcelRequired.class) || field.isAnnotationPresent(NotNull.class)
                || field.isAnnotationPresent(NotBlank.class) || field.isAnnotationPresent(NotEmpty.class)) return true;
        // Import VO 中常用 OpenAPI 的 requiredMode 标明必填;避免 Excel 模块依赖 Swagger。
        for (Annotation annotation : field.getAnnotations()) {
            if (!annotation.annotationType().getName().equals("io.swagger.v3.oas.annotations.media.Schema")) continue;
            try {
                if ("REQUIRED".equals(String.valueOf(annotation.annotationType().getMethod("requiredMode").invoke(annotation)))) return true;
            } catch (ReflectiveOperationException ignored) { return false; }
        }
        return false;
    }
}