EasyExcel源码浅读

AnalysisEventListener#invoke()

-继承抽象类->

ReadListener#invoke()

-继承接口->

ReadListener#invoke(){接口}


DefaultAnalysisEventProcessor#dealData(AnalysisContext analysisContext)

{

ReadListener数据从analysisContext.currentReadHolder().readListenerList()获取

调用ReadListener.invoke()

}

–dealData()被同类方法endRow(AnalysisContext analysisContext)调用–>

DefaultAnalysisEventProcessor#endRow(AnalysisContext analysisContext){

这个方法只是判断了下context中的属性,打log

然后就直接传context给了dealData();

}


调用endRow的方法有以下三个:

在这里插入图片描述

RowTagHandler#startElement/endElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes)

---->

XlsxRowHandler#startElement/endElement((String uri, String localName, String name, Attributes attributes))

{

xlsxReadContext即Context是这个类中传入的。

}


这个类在

XlsxSaxAnalyser#execute()方法中被创建,并且Context属性是从这个类中传入的。

–这个类在哪被初始化的呢–>

ExcelAnalyserImpl#choiceExcelExecutor()

{

XlsxReadContext xlsxReadContext = new DefaultXlsxReadContext(readWorkbook, ExcelTypeEnum.XLSX);

}

Context是在这里被创建的。

-这个方法在ExcelAnalyserImpl(ReadWorkbook readWorkbook)初始化时被调用->

那么ExcelAnalyserImpl是在哪被初始化的呢


ExcelReader的构造器中被初始化的

    public ExcelReader(ReadWorkbook readWorkbook) {
        excelAnalyser = new ExcelAnalyserImpl(readWorkbook);
    }

ExcelReader是在:

ExcelReaderBuilder#build()方法中创建的

public ExcelReader build() {
    return new ExcelReader(readWorkbook);
}

这个方法被以下几个方法调用:
在这里插入图片描述

官方demo中的使用方法是:

EasyExcel.read(fileName, FormulaDataReadData.class, new FormulaHeadListener<>(serviceImpl)).sheet().doRead();

其中sheet()方法即使用了sheet(Integer,String)


我们还看到这个Demo后面调用了.doRead()方法

点进去可以看到:

    public void doRead() {
        if (excelReader == null) {
            throw new ExcelGenerateException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
        }
        excelReader.read(build());
        excelReader.finish();
    }

finish()是关闭流操作,可以从官网https://alibaba-easyexcel.github.io/quickstart/read.html的一个Demo可以看到

/**
 * 读多个或者全部sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
 * <p>
 * 1. 创建excel对应的实体对象 参照{@link DemoData}
 * <p>
 * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
 * <p>
 * 3. 直接读即可
 */
@Test
public void repeatedRead() {
    String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
    // 读取全部sheet
    // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
    EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();

    // 读取部分sheet
    fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
    ExcelReader excelReader = EasyExcel.read(fileName).build();
    // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
    ReadSheet readSheet1 =
        EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
    ReadSheet readSheet2 =
        EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
    // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
    excelReader.read(readSheet1, readSheet2);
    // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
    excelReader.finish();
}

那么主要看

excelReader.read(build()){

build()为返回一个sheet,这个sheet

是构造ExcelReaderSheetBuilder也即doRead()方法所在类时new的一个ReadSheet

    public ExcelReaderSheetBuilder() {
        this.readSheet = new ReadSheet();
    }

    public ExcelReaderSheetBuilder(ExcelReader excelReader) {
        this.readSheet = new ReadSheet();
        this.excelReader = excelReader;
    }

}

那么看看read(ReadSheet… readSheet)方法:

    /**
     * Parse the specified sheet锛孲heetNo start from 0
     *
     * @param readSheet
     *            Read sheet
     */
    public ExcelReader read(ReadSheet... readSheet) {
        return read(Arrays.asList(readSheet));
    }

    /**
     * Read multiple sheets.
     *
     * @param readSheetList
     * @return
     */
    public ExcelReader read(List<ReadSheet> readSheetList) {
        excelAnalyser.analysis(readSheetList, Boolean.FALSE);
        return this;
    }

excelAnalyser怎么获得的,主要有两个方法:

@Deprecated
public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent,
    AnalysisEventListener eventListener, boolean trim){}
public ExcelReader(ReadWorkbook readWorkbook) {
    excelAnalyser = new ExcelAnalyserImpl(readWorkbook);
}

所以主使用的是下面这个构造方法。

这个构造方法是在sheet()这个方法中被调用的:

public ExcelReaderSheetBuilder sheet(Integer sheetNo, String sheetName) {
        ExcelReaderSheetBuilder excelReaderSheetBuilder = new ExcelReaderSheetBuilder(build());
        if (sheetNo != null) {
            excelReaderSheetBuilder.sheetNo(sheetNo);
        }
        if (sheetName != null) {
            excelReaderSheetBuilder.sheetName(sheetName);
        }
        return excelReaderSheetBuilder;
    }

然后看build()这个方法:

    public ExcelReader build() {
        return new ExcelReader(readWorkbook);
    }

这个readWorkbook属性是在ExcelReaderBuilder的构造方法中赋值

    public ExcelReaderBuilder() {
        this.readWorkbook = new ReadWorkbook();
    }

其实上面这些可以不用看的,因为都仅仅是new出一个对象,并没有进行更深层次的操作,影响不大。

我们现在主要看到了这个构造方法:

    public ExcelReader(ReadWorkbook readWorkbook) {
        excelAnalyser = new ExcelAnalyserImpl(readWorkbook);
    }

这样我们就可以和前面写过的遥相呼应:

在这里插入图片描述


Listener是如何加入进去的呢?

主要是ExcelReaderBuilder中的readWorkbook成员变量。

ReadWorkbook继承了ReadBasicParameter

ReadBasicParameter中维护了一个private List customReadListenerList;


开始有些疑惑的点,后来理顺了:

XlsxRowHandler#startElement/endElement()在XlsxSaxAnalyser#execute()方法中被创建

那么这个方法如何被调用的呢?

调用流程如下:

ExcelReaderSheetBuilder#doRead()

​ --ExcelReader#read(ReadSheet… readSheet)–>

ExcelReader#read(List readSheetList)

​ --excelAnalyser.analysis(readSheetList, Boolean.FALSE)–>

ExcelAnalyserImpl#analysis(List readSheetList, Boolean readAll)

​ --excelReadExecutor.execute();

doRead()应该是EasyExcel中比较重要的方法了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EasyExcel是一种用于读取和写入Excel文件的Java库,它提供了EasyExcelFactory工厂类来封装了一些常用的读取和写入操作。你可以通过查看EasyExcelFactory工厂类的源代码来深入了解EasyExcel的实现细节。 为了开始使用EasyExcel,首先需要引入EasyExcel的依赖。在你的项目的pom.xml文件中添加以下依赖代码: ```xml <!-- easyexcel 3.1.0 版本不需要poi依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.1</version> </dependency> ``` 一旦你引入了EasyExcel的依赖,就可以开始使用EasyExcel来进行Excel文件的读取和写入操作了。 EasyExcel的读取操作非常简单。你可以使用EasyExcelFactory的静态方法createReader来创建一个ExcelReader对象,然后通过该对象的read方法来读取Excel文件中的数据。 ```java ExcelReader excelReader = EasyExcelFactory.read(inputStream).build(); List<MyData> dataList = excelReader.readAll(MyData.class); excelReader.finish(); ``` 上面的代码片段展示了如何读取一个Excel文件中的数据,并将其映射到名为MyData的自定义类的对象列表中。 这里的inputStream是一个代表Excel文件的输入流,MyData是一个自定义的Java类,用于表示Excel文件中的数据。你可以根据自己的需求进行相应的修改。 通过查看EasyExcelFactory工厂类的源代码,你可以深入理解EasyExcel的实现原理,并根据自己的项目需求编写适合自己项目的方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [EasyExcel读文件详解和源码分析](https://blog.csdn.net/qq_42402854/article/details/131382629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值