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 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; } }