[alibaba/easyexcel]如何跳过表格中示例数据行

2024-05-23 151 views
1

表格中包含3行固定内容,

Test.java

@Ignore
public class ReadTest {
    @Test
    public void read() {
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "test1.xlsx";
        EasyExcel.read(fileName, TestData.class, new DataListener()).sheet().headRowNumber(1).doRead();
    }
}

DataListener.java

@Slf4j
public class DataListener extends AnalysisEventListener<TestData> {

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        log.info("HEAD : {}", headMap);
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.info("ERROR : {}", exception.getMessage());
        String message = exception.getMessage();
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            message = String.format("解析异常:第%d行,第%d列,数据为:%s\n",
                excelDataConvertException.getRowIndex() + 1,
                excelDataConvertException.getColumnIndex() + 1,
                excelDataConvertException.getCellData().toString());
            log.info(message);
        }
    }

    @Override
    public void invoke(TestData data, AnalysisContext context) {
        log.info("DATA : {}", JSON.toJSONString(data));
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("END ROW : {}", context.readRowHolder().getRowIndex() + 1);
    }
}

TestData.java

@Data
public class TestData {

    @ExcelProperty(value = {"head1"})
    private String head1;

    @ExcelProperty(value = {"head2"})
    private String head2;
}

表格数据为: image head1 | head2 头部名称1 | 头部名称2 示例1 | 示例2 数据11 | 数据12 数据21 | 数据22

情景: 1.此时设置的 headRowNumber 为 1,解析表格时会将head的名称行和示例行一起解析成数据。 且如果解析数据类型包括 Date 或者 Number,因为head的描述内容是字符文本,此行就会解析错误。 Test.java

EasyExcel.read(fileName, TestData.class, new DataListener()).sheet().headRowNumber(1).doRead();

TestData.java

@ExcelProperty(value = {"head1"})

输出日志:

com.alibaba.easyexcel.test.demo.read.DataListener:20 - HEAD : {0=head1, 1=head2}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {"head1":"头部名称1","head2":"头部名称2"}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {"head1":"示例1","head2":"示例2"}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {"head1":"数据11","head2":"数据12"}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {"head1":"数据21","head2":"数据22"}
com.alibaba.easyexcel.test.demo.read.DataListener:44 - END ROW : 5

2.但如果将 headRowNumber 设置为 3,@ExcelProperty(value = {""}) 的值就需要设置为示例行的数据,即 @ExcelProperty(value = {"示例1"}) ,否则就会使解析的数据内容为空 Test.java

EasyExcel.read(fileName, TestData.class, new DataListener()).sheet().headRowNumber(3).doRead();

TestData.java

@ExcelProperty(value = {"head1"})

输出日志:

com.alibaba.easyexcel.test.demo.read.DataListener:20 - HEAD : {0=head1, 1=head2}
com.alibaba.easyexcel.test.demo.read.DataListener:20 - HEAD : {0=头部名称1, 1=头部名称2}
com.alibaba.easyexcel.test.demo.read.DataListener:20 - HEAD : {0=示例1, 1=示例2}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {}
com.alibaba.easyexcel.test.demo.read.DataListener:39 - DATA : {}
com.alibaba.easyexcel.test.demo.read.DataListener:44 - END ROW : 5

问题: 现在是否有设置方式,使得 @ExcelProperty(value = {""}) 设置的值为第一行内容,且跳过 名称描述行 和 示例数据行? 或者是否有一个设置读取指定head行的方法,以及可以设置跳过若干指定行的方法。

备注: 如果使用 @ExcelProperty(index = ) 可以避开这个问题,但就这样对模板要求更严格,无法自定义模板。

回答

3

自定义读取监听器,设置一个开始数据行号,示例行,不进行数据读取,就可以避免读取错误,或者为空的情况

1

自定义读取监听器,设置一个开始数据行号,示例行,不进行数据读取,就可以避免读取错误,或者为空的情况

已有自定义监听器 DataListener 继承了 AnalysisEventListener,设置开始数据行号是哪个方法?看源代码并没有这相应的方法

7

就是在DataListener自定义的监听器中,增加一个属性,比如开始数据行数start,加一个判断,AnalysisContext可以获取到当前读的行,如果当前行<start,直接返回,因为一般都默认用了对象转换,监听器会先走到这个ModelBuildEventListener中,所以需要我们自定义一个ModelBuildEventListener,和DataListener中的处理一样, image 如果我还说的不清楚的话,晚上回去给你贴点代码

6

自定义读取监听器,设置一个开始数据行号,示例行,不进行数据读取,就可以避免读取错误,或者为空的情况

已有自定义监听器 DataListener 继承了 AnalysisEventListener,设置开始数据行号是哪个方法?看源代码并没有这相应的方法

源码中没有对应的处理,就是自己强行跳过了这些无用的数据,我也是前几天有这个需求,看了api,处理了下

7

自定义读取监听器,设置一个开始数据行号,示例行,不进行数据读取,就可以避免读取错误,或者为空的情况

已有自定义监听器 DataListener 继承了 AnalysisEventListener,设置开始数据行号是哪个方法?看源代码并没有这相应的方法

源码中没有对应的处理,就是自己强行跳过了这些无用的数据,我也是前几天有这个需求,看了api,处理了下

谢谢,明白了。要是easyExcel 这边可以更灵活设置就好了?

5

目前没法跳过 某些行数。

9

@xmmxjy 没太看明白,是在自定义的 DatatListener 中加一个属性,然后在哪个方法里判断呢,invoke 么,当进入到 invoke 里时就已经因为数据类型不匹配而报错了啊。还是说要重写官方的 ModelBuildEventListener 类?能麻烦再给详细解释下么,谢谢