feat: Supports obtaining current row data object during writing #598 by hooj0 · Pull Request #619 · apache/fesod

Purpose of the pull request

Supports obtaining current row data object during writing #598
#598

What's changed?

增加上下文属性

  • WriteConverterContext 中可以获取到原始数据对象,通过 getRecord 方法
  • CellWriteHandlerContext 中可以获取到原始数据对象,通过 getOriginalRecord方法

设置当前数据对象到上下文属性中

  • AbstractExcelWriteExecutor#doConvert 方法中设置当前对象值
cellData = ((Converter<Object>) converter)
                    .convertToExcelData(new WriteConverterContext<>(
                            cellWriteHandlerContext.getOriginalValue(), cellWriteHandlerContext.getOriginalRecord(), excelContentProperty, writeContext));
  • ExcelWriteAddExecutor#doAddBasicTypeToExcel/addJavaObjectToExcel/addBasicTypeToExcel 方法中设置当前对象值 setOriginalRecord
cellWriteHandlerContext.setOriginalRecord(oneRowData);
cellWriteHandlerContext.setOriginalValue(oneRowData.get(dataIndex));
cellWriteHandlerContext.setOriginalFieldClass(
        FieldUtils.getFieldClass(cellWriteHandlerContext.getOriginalValue()));
converterAndSet(cellWriteHandlerContext);

WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
  • ExcelWriteFillExecutor#doFill 方法中设置当前对象值 setOriginalRecord
createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext);
cellWriteHandlerContext.setOriginalRecord(oneRowData);
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));

converterAndSet(cellWriteHandlerContext);
WriteCellData<?> cellData = cellWriteHandlerContext.getFirstCellData();

增加测试用例

以下是测试用例需要的对象,WriteConverterCellWriteHandler

@Getter
@Setter
@ToString
@EqualsAndHashCode
public class RecordData {
    /**
     * String Title
     */
    @ExcelProperty("String Title")
    private String string;

    /**
     * Date Title
     */
    @ExcelProperty("Date Title")
    private Date date;

    /**
     * Number Title
     */
    @ExcelProperty("Number Title")
    private Double doubleData;

    /**
     * 通过自定义转换器转换
     */
    @ExcelProperty(converter = RecordStringStringConverter.class)
    private String text;
}

// 可以访问到原始数据,进行其他业务处理
@Slf4j
public class RecordStringStringConverter implements Converter<String> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        return context.getReadCellData().getStringValue();
    }

    /**
     * 这里是写的时候会可以访问到原始数据,你可以进行其他业务处理,然后进行转换
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        // 获取原始数据
        RecordData record = (RecordData) context.getRecord();
        log.info("原始数据:{}", record);
        return new WriteCellData<>("自定义:" + context.getValue() + "-" + record.getDoubleData());
    }
}


/**
 * 拦截器中单元格上下文可以获取到行数据
 */
@Slf4j
public class RecordCellWriteHandler implements CellWriteHandler {

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        Cell cell = context.getCell();

        if (BooleanUtils.isFalse(context.getHead()) && cell.getColumnIndex() != 0) {
            RecordData record = (RecordData) context.getOriginalRecord();
            log.info("写入数据:{}", record);
        }
    }
}

测试用例代码

@Test
public void recordWrite() {
    String fileName = TestFileUtil.getPath() + "recordWrite" + System.currentTimeMillis() + ".xlsx";
    FastExcel.write(fileName, RecordData.class)
            .registerWriteHandler(new RecordCellWriteHandler())
            .sheet("模板")
            .doWrite(records());
}

执行结果

image image

Checklist

  • I have read the Contributor Guide.
  • I have written the necessary doc or comment.
  • I have added the necessary unit tests and all cases have passed.