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