上片文章easyexcel基于注解的可回调的更精细的单元格格式设置(一)中只能根据本字段的值的情况设置不同样式,但如果该字段单元格样式受到其它字段值影响,则无法实现。于是衍生出了该方案。
该方案也有方案一中两个Consumer,且多了一个richTextConsumer用于设置富文本,CommonCallBackData只是对于字体和单元格样式类等的封装而已。多了一个List<T> dataList,该dataList也包含在CommonCallBackData中,在回调时会将该集合会作为方法参数传过去,同时会传入relativeRowIndex字段,这样根据这两个字段,就可以获取到某一行的数据,也就可以实现上述需求。代码1处为富文本回调。为了支持富文本,注解也添加了字段是否为富文本,哪个字段需要支持富文本,只需将注解的richText设置为true。若有多个字段都需要支持富文本,则需要根据回调中传过去的Field做判断。
@ExcelProperty("名称") @ColumnWidth(45) @ExcelStyle(richText = true) private String name; @Target({ElementType.FIELD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ExcelStyle { String fontName() default "宋体"; short fontHeightInPoints() default 12; HorizontalAlignment horizontalAlignment() default HorizontalAlignment.LEFT; VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER; boolean wrapText() default false; boolean richText() default false; } package com.tzxx.common.domain.logic.excel; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.tzxx.common.annotation.ExcelStyle; import lombok.extern.slf4j.Slf4j; 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.Workbook; import java.lang.reflect.Field; import java.util.List; import java.util.function.Consumer; @Slf4j public class ExcelStyleAnnotationAndContainsCommonCallBackCellWriteHandler<T> extends HorizontalCellStyleStrategy { private Class<?> c; private List<T> dataList; private Consumer<CommonCallBackData<T>> fontConsumer; private Consumer<CommonCallBackData<T>> cellStyleConsumer; private Consumer<CommonCallBackData<T>> richTextConsumer; public ExcelStyleAnnotationAndContainsCommonCallBackCellWriteHandler(Class<?> c, WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle, List<T> dataList, Consumer<CommonCallBackData<T>> fontConsumer, Consumer<CommonCallBackData<T>> cellStyleConsumer, Consumer<CommonCallBackData<T>> richTextConsumer) { super(headWriteCellStyle, contentWriteCellStyle); this.c = c; this.fontConsumer = fontConsumer; this.cellStyleConsumer = cellStyleConsumer; this.richTextConsumer = richTextConsumer; this.dataList = dataList; } @Override protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { try { Field declaredField = c.getDeclaredField(head.getFieldName()); ExcelStyle annotation = declaredField.getAnnotation(ExcelStyle.class); if (annotation != null) { Workbook wb = cell.getSheet().getWorkbook(); CellStyle cellStyle = wb.createCellStyle(); cell.setCellStyle(cellStyle); Font font = wb.createFont(); CommonCallBackData<T> callBackData = create(font,cellStyle,relativeRowIndex,cell,wb,annotation,declaredField); font.setFontName(annotation.fontName()); font.setFontHeightInPoints(annotation.fontHeightInPoints()); if (fontConsumer != null) { fontConsumer.accept(callBackData); } cellStyle.setFont(font); cellStyle.setAlignment(annotation.horizontalAlignment()); cellStyle.setVerticalAlignment(annotation.verticalAlignment()); cellStyle.setWrapText(annotation.wrapText()); if (cellStyleConsumer != null) { cellStyleConsumer.accept(callBackData); } //1 boolean richText = annotation.richText(); if (richText && richTextConsumer != null) { richTextConsumer.accept(callBackData); } }else { super.setContentCellStyle(cell,head,relativeRowIndex); } } catch (NoSuchFieldException e) { log.error("ExcelStyleAnnotationCellWriteHandler error{0}",e); } } private CommonCallBackData<T> create(Font font, CellStyle cellStyle, Integer relativeRowIndex,Cell cell,Workbook wb,ExcelStyle annotation, Field field){ CommonCallBackData<T> callBackData = new CommonCallBackData<>(); callBackData.setFont(font); callBackData.setCellStyle(cellStyle); callBackData.setRelativeRowIndex(relativeRowIndex); callBackData.setDataList(this.dataList); callBackData.setCell(cell); callBackData.setWorkbook(wb); callBackData.setAnnotation(annotation); callBackData.setField(field); return callBackData; } } @Data public class CommonCallBackData<T> { private Font font; private CellStyle cellStyle; private List<T> dataList; private Integer relativeRowIndex; private Cell cell; private Workbook workbook; private Field field; private ExcelStyle annotation; }Consumer示例:
public static void richTextConsumer(CommonCallBackData<XX> callBackData){ Integer relativeRowIndex = callBackData.getRelativeRowIndex(); List<XX> dataList = callBackData.getDataList(); XX dto = dataList.get(relativeRowIndex); if (Boolean.TRUE.equals(dto.getXx))) { Workbook workbook = callBackData.getWorkbook(); Cell cell = callBackData.getCell(); Font font = workbook.createFont(); font.setColor(Font.COLOR_RED); String big = "富文本"; String value = cell.getStringCellValue() + big; int index = value.lastIndexOf(big); //将富文本三个字设置为红色字体 RichTextString richTextString = new XSSFRichTextString(value); richTextString.applyFont(index,index+3,font); cell.setCellValue(richTextString); } } public static void cellStyleTextConsumer(CommonCallBackData<XX> callBackData){ Integer relativeRowIndex = callBackData.getRelativeRowIndex(); List<XX> dataList = callBackData.getDataList(); XX dto = dataList.get(relativeRowIndex); if (Boolean.TRUE.equals(dto.getXx())) { CellStyle cellStyle = callBackData.getCellStyle(); cellStyle.setAlignment(HorizontalAlignment.CENTER); } }调用:为了支持富文本,需要将inMemory设置为true,该设置是将默认的SXSSF替换为XSSF,SXSSF不支持富文本。
EasyExcelFactory.write(httpServletResponse.getOutputStream(), XX.class) .inMemory(true) .registerWriteHandler(EasyExcelUtil.getStyleForCustomAnnotationAndContainsCommonCallBack( XX.class,exportList,null, XX::cellStyleTextConsumer,XX::richTextConsumer )) .sheet("xxxxx表").doWrite(list); //EasyExcelUtil public static <T> ExcelStyleAnnotationAndContainsCommonCallBackCellWriteHandler getStyleForCustomAnnotationAndContainsCommonCallBack(Class<?> c, List<T> dataList, Consumer<CommonCallBackData<T>> fontConsumer, Consumer<CommonCallBackData<T>> cellStyleConsumer, Consumer<CommonCallBackData<T>> richTextConsumer) { return new ExcelStyleAnnotationAndContainsCommonCallBackCellWriteHandler(c,getHeadWriteCellStyle(), getContentWriteCellStyle(),dataList,fontConsumer,cellStyleConsumer,richTextConsumer); } private static WriteCellStyle getHeadWriteCellStyle(){ // 头的策略 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); WriteFont headWriteFont = new WriteFont(); headWriteFont.setFontHeightInPoints((short)14); headWriteFont.setFontName("宋体"); headWriteCellStyle.setWriteFont(headWriteFont); return headWriteCellStyle; } private static WriteCellStyle getContentWriteCellStyle(){ // 内容的策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); WriteFont contentWriteFont = new WriteFont(); contentWriteFont.setFontName("宋体"); contentWriteFont.setFontHeightInPoints((short)13); contentWriteCellStyle.setWriteFont(contentWriteFont); return contentWriteCellStyle; }