package cn.iocoder.yudao.framework.excel.core.handler; import cn.idev.excel.metadata.Head; import cn.idev.excel.write.handler.CellWriteHandler; import cn.idev.excel.write.handler.context.CellWriteHandlerContext; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Workbook; import java.lang.reflect.Field; /** * 必填表头处理器 * *
导出模板时,把标注了 {@link ExcelRequired} 的字段对应的表头文字标红,并在前面加一个星号, * 让用户一眼看出哪些列必须填写。 * * @author 超级管理员 */ public class RequiredHeaderWriteHandler implements CellWriteHandler { private static final String REQUIRED_MARK = "*"; @Override public void afterCellDispose(CellWriteHandlerContext context) { // 1. 只处理表头单元格 if (!Boolean.TRUE.equals(context.getHead())) { return; } Head head = context.getHeadData(); Cell cell = context.getCell(); if (head == null || head.getField() == null || cell == null) { return; } // 2. 只处理标注了 @ExcelRequired 的字段 Field field = head.getField(); if (!field.isAnnotationPresent(ExcelRequired.class)) { return; } // 3. 多级表头时只标记最后一行,避免父级表头重复加星号 int lastHeadRowIndex = head.getHeadNameList() == null ? 0 : head.getHeadNameList().size() - 1; if (context.getRelativeRowIndex() != null && context.getRelativeRowIndex() < lastHeadRowIndex) { return; } // 4. 表头加星号 String text = cell.getStringCellValue(); if (text != null && !text.startsWith(REQUIRED_MARK)) { cell.setCellValue(REQUIRED_MARK + text); } // 5. 字体标红,并保留原有表头样式的其它属性 Workbook workbook = cell.getSheet().getWorkbook(); CellStyle oldStyle = cell.getCellStyle(); CellStyle style = workbook.createCellStyle(); style.cloneStyleFrom(oldStyle); Font oldFont = workbook.getFontAt(oldStyle.getFontIndex()); Font font = workbook.createFont(); font.setFontName(oldFont.getFontName()); font.setFontHeightInPoints(oldFont.getFontHeightInPoints()); font.setBold(oldFont.getBold()); font.setItalic(oldFont.getItalic()); font.setColor(IndexedColors.RED.getIndex()); style.setFont(font); cell.setCellStyle(style); } }