|
@@ -14,86 +14,94 @@ import java.util.List;
|
|
|
*/
|
|
*/
|
|
|
public class ExcelCustomRowStyleHandler implements CellWriteHandler {
|
|
public class ExcelCustomRowStyleHandler implements CellWriteHandler {
|
|
|
|
|
|
|
|
- // 定义颜色常量 (RGB)
|
|
|
|
|
- private static final short COLOR_YELLOW = IndexedColors.YELLOW.getIndex(); // 黄色
|
|
|
|
|
- private static final short COLOR_LIGHT_GRAY = IndexedColors.GREY_25_PERCENT.getIndex(); // 浅灰色(斑马纹)
|
|
|
|
|
- private static final short COLOR_WHITE = IndexedColors.WHITE.getIndex(); // 白色
|
|
|
|
|
|
|
+ // 颜色常量
|
|
|
|
|
+ private static final short COLOR_YELLOW = IndexedColors.YELLOW.getIndex();
|
|
|
|
|
+ private static final short COLOR_LIGHT_GRAY = IndexedColors.GREY_25_PERCENT.getIndex();
|
|
|
|
|
+ private static final short COLOR_WHITE = IndexedColors.WHITE.getIndex();
|
|
|
|
|
+
|
|
|
|
|
+ // 缓存三种全局样式,只创建一次,解决POI样式超限问题
|
|
|
|
|
+ private CellStyle whiteCellStyle;
|
|
|
|
|
+ private CellStyle grayCellStyle;
|
|
|
|
|
+ private CellStyle yellowCellStyle;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 基础样式:统一边框 + 文本格式@
|
|
|
|
|
+ */
|
|
|
|
|
+ private CellStyle createBaseStyle(Workbook workbook) {
|
|
|
|
|
+ CellStyle base = workbook.createCellStyle();
|
|
|
|
|
+ // 全部边框细线
|
|
|
|
|
+ base.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
+ base.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
+ base.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
+ base.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
+ // 设置单元格为文本格式,替代 RowWriteHandlerImpl
|
|
|
|
|
+ DataFormat dataFormat = workbook.createDataFormat();
|
|
|
|
|
+ base.setDataFormat(dataFormat.getFormat("@"));
|
|
|
|
|
+ return base;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 初始化三种行样式,仅执行一次
|
|
|
|
|
+ */
|
|
|
|
|
+ private void initStyle(Workbook workbook) {
|
|
|
|
|
+ if (whiteCellStyle != null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 白色行
|
|
|
|
|
+ whiteCellStyle = createBaseStyle(workbook);
|
|
|
|
|
+ whiteCellStyle.setFillForegroundColor(COLOR_WHITE);
|
|
|
|
|
+ whiteCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
+
|
|
|
|
|
+ // 灰色斑马行
|
|
|
|
|
+ grayCellStyle = createBaseStyle(workbook);
|
|
|
|
|
+ grayCellStyle.setFillForegroundColor(COLOR_LIGHT_GRAY);
|
|
|
|
|
+ grayCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
+
|
|
|
|
|
+ // 黄色特殊行 ID=-1
|
|
|
|
|
+ yellowCellStyle = createBaseStyle(workbook);
|
|
|
|
|
+ yellowCellStyle.setFillForegroundColor(COLOR_YELLOW);
|
|
|
|
|
+ yellowCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
|
|
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
|
|
|
List<WriteCellData<?>> cellDataList, Cell cell, Head head,
|
|
List<WriteCellData<?>> cellDataList, Cell cell, Head head,
|
|
|
Integer relativeRowIndex, Boolean isHead) {
|
|
Integer relativeRowIndex, Boolean isHead) {
|
|
|
- // 1. 跳过表头,只处理数据行
|
|
|
|
|
|
|
+ // 跳过表头
|
|
|
if (isHead || relativeRowIndex == null) {
|
|
if (isHead || relativeRowIndex == null) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
|
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
|
|
- Row row = cell.getRow();
|
|
|
|
|
|
|
+ initStyle(workbook);
|
|
|
|
|
|
|
|
- // 2. 获取当前行的数据对象
|
|
|
|
|
-
|
|
|
|
|
- // 假设ID是第一列;如果ID不是第一列,修改columnIndex判断
|
|
|
|
|
- int idColumnIndex = 0;
|
|
|
|
|
- boolean isSpecialRow = false;
|
|
|
|
|
- long idValue = 0;
|
|
|
|
|
|
|
+ Row row = cell.getRow();
|
|
|
|
|
+ final int idColumnIndex = 0;
|
|
|
|
|
+ boolean markYellow = false;
|
|
|
|
|
|
|
|
- // 尝试获取当前单元格如果是ID列的值
|
|
|
|
|
- if (cell.getColumnIndex() == idColumnIndex) {
|
|
|
|
|
|
|
+ // 读取当前行ID列值,判断是否黄色高亮
|
|
|
|
|
+ Cell idCell = row.getCell(idColumnIndex);
|
|
|
|
|
+ if (idCell != null) {
|
|
|
try {
|
|
try {
|
|
|
- // 尝试读取数值
|
|
|
|
|
- if (cell.getCellType() == CellType.NUMERIC) {
|
|
|
|
|
- idValue = (long) cell.getNumericCellValue();
|
|
|
|
|
- } else if (cell.getCellType() == CellType.STRING) {
|
|
|
|
|
- idValue = Long.parseLong(cell.getStringCellValue());
|
|
|
|
|
|
|
+ long idVal = switch (idCell.getCellType()) {
|
|
|
|
|
+ case NUMERIC -> (long) idCell.getNumericCellValue();
|
|
|
|
|
+ case STRING -> Long.parseLong(idCell.getStringCellValue().trim());
|
|
|
|
|
+ default -> 0L;
|
|
|
|
|
+ };
|
|
|
|
|
+ if (idVal == -1L) {
|
|
|
|
|
+ markYellow = true;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 判定条件:ID == -1
|
|
|
|
|
- if (idValue == -1L) {
|
|
|
|
|
- isSpecialRow = true;
|
|
|
|
|
- }
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- // 忽略解析错误
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- // 如果不是ID列,我们需要查看同一行ID列的值来决定颜色
|
|
|
|
|
- Cell idCell = row.getCell(idColumnIndex);
|
|
|
|
|
- if (idCell != null) {
|
|
|
|
|
- try {
|
|
|
|
|
- if (idCell.getCellType() == CellType.NUMERIC) {
|
|
|
|
|
- idValue = (long) idCell.getNumericCellValue();
|
|
|
|
|
- }
|
|
|
|
|
- if (idValue == -1L) isSpecialRow = true;
|
|
|
|
|
- } catch(Exception ignored){}
|
|
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
|
+ // 解析异常走斑马纹逻辑
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 3. 创建或获取样式
|
|
|
|
|
- CellStyle style = workbook.createCellStyle();
|
|
|
|
|
-
|
|
|
|
|
- // 4. 设置背景色逻辑
|
|
|
|
|
- if (isSpecialRow) {
|
|
|
|
|
- // 优先级最高:如果是 ID=-1,强制黄色
|
|
|
|
|
- style.setFillForegroundColor(COLOR_YELLOW);
|
|
|
|
|
- style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
|
|
+ // 选择缓存好的样式赋值,不再新建
|
|
|
|
|
+ CellStyle targetStyle;
|
|
|
|
|
+ if (markYellow) {
|
|
|
|
|
+ targetStyle = yellowCellStyle;
|
|
|
} else {
|
|
} else {
|
|
|
- // 否则执行隔行换色 (斑马纹)
|
|
|
|
|
- // relativeRowIndex 从 0 开始,偶数行白,奇数行灰
|
|
|
|
|
- if (relativeRowIndex % 2 == 1) {
|
|
|
|
|
- style.setFillForegroundColor(COLOR_LIGHT_GRAY);
|
|
|
|
|
- style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
- } else {
|
|
|
|
|
- style.setFillForegroundColor(COLOR_WHITE);
|
|
|
|
|
- style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ targetStyle = relativeRowIndex % 2 == 1 ? grayCellStyle : whiteCellStyle;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 5. 将样式应用到当前单元格
|
|
|
|
|
- style.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
- style.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
- style.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
- style.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
-
|
|
|
|
|
- cell.setCellStyle(style);
|
|
|
|
|
|
|
+ cell.setCellStyle(targetStyle);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|