【EasyExcel】导出excel扩展支持自定义颜色

  easyexcel官方的样式中,只能选64种标准色,无法支持自定义颜色,网上找了一下,也没发现相关的介绍,并且网上的大部分资料都无法实现真正的自定义颜色。于是把自己的实现方式记录下来,避免以后的兄弟们踩坑。

  

/**
* 自定义单元格背景颜色样式处理器,可以扩展其他的样式
*/
public class StyleHandler extends AbstractRowWriteHandler {
  /**
   * sheet页名称列表
   */
  private List<String> sheetNameList;
  /**
   * 样式信息
   */
  private List<StyleModel> cellStyleList = new ArrayList<>();
  /**
   * 自定义样式适配器构造方法
   *
   * @param cellStyleList 样式信息
   */
  public StyleHandler(List<StyleModel> cellStyleList) {
     if (CollectionUtil.isEmpty(cellStyleList)) {
        return;
    }
     cellStyleList = cellStyleList.stream().filter(x -> x != null
        //判断sheet名称KEY是否存在
        && StrUtil.isNotBlank(x.getSheetName())

        //判断背景颜色KEY是否存在
        && (x.getBackgroundColor() == null || x.getBackgroundColor() instanceof IndexedColors
        || x.getBackgroundColor() instanceof XSSFColor)
    ).collect(Collectors.toList());
     this.cellStyleList = cellStyleList;
     sheetNameList = this.cellStyleList.stream().map(x -> x.getSheetName()).distinct().collect(Collectors.toList());
  }

  /**
   * 这个方法是重点,通过重写该方法实现样式的添加
   * @param writeSheetHolder
   * @param writeTableHolder
   * @param row
   * @param relativeRowIndex
   * @param isHead
   */
  @Override
  public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row
    , Integer relativeRowIndex, Boolean isHead) {
     Sheet sheet = writeSheetHolder.getSheet();
     //不需要添加样式,或者当前sheet页不需要添加样式
     if (cellStyleList == null || cellStyleList.size() <= 0 || sheetNameList.contains(sheet.getSheetName()) == false) {
        return;
    }
     //获取当前行的样式信息
     List<StyleModel> rowCellStyleList = cellStyleList.stream().filter(x ->
        StrUtil.equals(x.getSheetName(), sheet.getSheetName()) && x.getRowIndex() == relativeRowIndex).collect(Collectors.toList());
     //该行不需要设置样式
     if (rowCellStyleList == null || rowCellStyleList.size() <= 0) {
        return;
    }
     for (StyleModel cellStyleModel : rowCellStyleList) {
        //设置单元格样式
        setCellStyle(cellStyleModel, row);
    }
     //删除已添加的样式信息
     cellStyleList.removeAll(rowCellStyleList);
     //重新获取要添加的sheet页姓名
     sheetNameList = cellStyleList.stream().map(x -> x.getSheetName()).distinct().collect(Collectors.toList());
  }
  /**
   * 给单元格设置样式
   *
   * @param cellStyleModel 样式信息
   * @param row           行对象
   */
  private void setCellStyle(StyleModel cellStyleModel, Row row) {
     //背景颜色
     Object backgroundColor = cellStyleModel.getBackgroundColor();
     //列索引
     int colIndex = cellStyleModel.getColIndex();
     //边框样式
     Cell cell = row.getCell(colIndex);
     if (cell == null) {
        cell = row.createCell(colIndex);
    }
     XSSFCellStyle style = (XSSFCellStyle) cell.getRow().getSheet().getWorkbook().createCellStyle();
     // 克隆出一个 style
     style.cloneStyleFrom(cell.getCellStyle());
     //设置背景颜色
     if (backgroundColor != null) {
        //使用IndexedColors定义的颜色
        if (backgroundColor instanceof IndexedColors) {
           style.setFillForegroundColor(((IndexedColors) backgroundColor).getIndex());
        }
        //使用自定义的RGB颜色
        else if (backgroundColor instanceof XSSFColor) {
           style.setFillForegroundColor((XSSFColor) backgroundColor);
        }
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    }
     cell.setCellStyle(style);
  }
}
/**
* 自定义单元格背景颜色样式,可以扩展其他的样式
*/
@Data
public class StyleModel {
/**
* sheet名称
*/
private String sheetName;
/**
* 列索引
*/
private int colIndex;
/**
* 行索引
*/
private int rowIndex;
/**
* 背景颜色
*/
private Object backgroundColor;

/**
* 生成背景颜色样式信息
*
* @param sheetName       sheet页名称
* @param rowIndex       行号
* @param columnIndex     列号
* @param backgroundColor 背景颜色
* @return
*/
public static StyleModel createBackgroundColorCellStyleModel(String sheetName, int rowIndex, int columnIndex, Object backgroundColor) {
StyleModel styleModel = new StyleModel();
//sheet页名称
styleModel.setSheetName(sheetName);
//行号
styleModel.setRowIndex(rowIndex);
//列号
styleModel.setColIndex(columnIndex);
//背景颜色
backgroundColor = backgroundColor != null && (backgroundColor instanceof IndexedColors == false && backgroundColor instanceof XSSFColor == false)
? null : backgroundColor;
styleModel.setBackgroundColor(backgroundColor);
return styleModel;
}
}
@Slf4j
public class TestDemo {


@Test
public void test() {
String fileName = "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx";

WriteSheet writeSheet = EasyExcel.writerSheet("数据").build();

ExcelWriter excelWriter = EasyExcel.write(fileName).build();
WriteHandler headColorHandler = addHeadColor(writeSheet.getSheetName(),4);


WriteTable writeTable0 = EasyExcel.writerTable(0)
.registerWriteHandler(headColorHandler)
.head(buildHeader()).build();

List<List<String>> body = this.buildBody();
excelWriter.write(body, writeSheet,writeTable0);
excelWriter.finish();
}

/**
* 添加表头背景色的WriteHandler。
*
* @param sheetName 工作表名称
* @param headSize 表头列数
* @return 返回添加表头背景色的WriteHandler
*/
public static WriteHandler addHeadColor(String sheetName, int headSize) {
List<StyleModel> cellStyleList = new ArrayList<>();
XSSFColor backgroundColor = CellStyleModel.getRGBColor(252, 228, 206);
for (int i = 0; i < headSize; i++) {
cellStyleList.add(StyleModel.createBackgroundColorCellStyleModel(sheetName, 0, i, backgroundColor));
}
return new StyleHandler(cellStyleList);
}


/**
* 模拟表头
* @return
*/
public List<List<String>> buildHeader() {
List<List<String>> header = new ArrayList<>();
header.add(Collections.singletonList("序号"));
header.add(Collections.singletonList("城市"));
header.add(Collections.singletonList("省会"));
header.add(Collections.singletonList("得分"));
return header;
}

/**
* 模拟表内容
*
* @return {@link List}<{@link List}<{@link String}>>
*/
public List<List<String>> buildBody() {
List<List<String>> result = new ArrayList<>();
result.add(Lists.newArrayList("1", "杭州", "江苏", "100"));
result.add(Lists.newArrayList("2", "无锡", "江苏", "100"));
result.add(Lists.newArrayList("3", "苏州", "江苏", "100"));
result.add(Lists.newArrayList("4", "常州", "江苏", "100"));
// 插入一个空行
result.add(Collections.emptyList());
return result;
}

}
 
posted @ 2024-04-13 00:31  海冠军  阅读(1915)  评论(0)    收藏  举报