文章摘自:https://blog.csdn.net/caijwjava/article/details/100855361

实战

1、导入一个相关依赖即可

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>

2、读取(上传)Excel文件,使用上非常的简单,只要几行代码。

public class EasyExcelDemo {public static void main(String[] args) {
String path = "E:\\tmp\\demo.xlsx";
// 自定义读取每一行数据的事件监听
ReadListen readListen = new ReadListen();
// 开始读取Excel数据
ExcelReader reader = EasyExcel.read(path, readListen).build();
// 读取第一个sheet,readSheet默认是读取第一个,可以自定义
ReadSheet readSheet = EasyExcel.readSheet().build();
// 开始读取数据
reader.read(readSheet);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
reader.finish();
}}

3、自定义ReadListen,主要是为了装数据,方便获取和使用,具体怎么调到这个方法的,以及出现的问题点在哪,往下走。。。

public class ReadListen<T> extends AnalysisEventListener<T> {private List<T> sheetData = new ArrayList<>(10);@Override
public void invoke(T t, AnalysisContext analysisContext) {
sheetData.add(t);
System.out.println(t);
}@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// Excel数据解析完成后,想要实现的业务逻辑
System.out.println("excel data resolve finish!!!");
}
}

4、开始源码分析,easyexcel怎么读取数据,以及问题点分析解决!4.1 当调用reader.read(readSheet);时,进入

public ExcelReader read(ReadSheet readSheet) {
checkFinished();
// 开始进入解析sheet
excelAnalyser.analysis(readSheet);
return this;
}

我们只要分析excelAnalyser.analysis(readSheet);,进入继续

analysisContext.currentSheet(excelExecutor, readSheet);
try {
// 真正解析sheet表格的地方
excelExecutor.execute();
} catch (ExcelAnalysisStopException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Custom stop!");
}
}
// 这个是在sheet表格解析完成后回调的方法,参考前面自定义的ReadListen
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);

点击进入

@Override
public void execute() {
parseXmlSource(sheetMap.get(analysisContext.readSheetHolder().getSheetNo()),
// 这个就是我们真正关心的地方,每行解析完成后会执行的操作
new XlsxRowHandler(analysisContext, stylesTable));
}

点击进入,继续

public XlsxRowHandler(AnalysisContext analysisContext, StylesTable stylesTable) {
// 这个是每个单元格执行的一些操作,包括回调之类的
this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, stylesTable);
// ...
}

点击进去,这时我们会注意到notifyEndOneRow,这个正是需要关注的点,继续

@Override
public void endHandle(String name) {
analysisContext.readSheetHolder()
// 这个就是每一行表格数据解析完成后会触发的回调
.notifyEndOneRow(new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent()), analysisContext);
rowResultHandler.clearResult();
}

点击继续,看看里面做了什么操作。。。

@Override
public void notifyEndOneRow(AnalysisFinishEvent event, AnalysisContext analysisContext) {
// ...to do somethingif (rowIndex >= headRowNumber) {
// Now is data
for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) {
try {
// 真正触发回调的地方,这里会有多个监听,包括我们前面自定义的ReadListen
readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext);
// ...

现在慢慢的明朗了整个读取流程,在debug之后,看看每个Listenner之后,找到一个ModelBuildEventListener,这个就是Excel数据转换的Listenner,也就是前面说到的会导致Excel表格列数据为空的时候,导致位置发生变化的地方,具体看看这里做了什么?

private Object buildStringList(Map<Integer, CellData> cellDataMap, ReadHolder currentReadHolder,
AnalysisContext context) {
// 这里是为了兼容一些旧的代码,做了一个映射,是返回list还是map
if (context.readWorkbookHolder().getDefaultReturnMap()) {
// ...省略不需要关心的代码
return map;
} else {
List<String> list = new ArrayList<String>();
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) {
// ...省略不需要关心的代码
return list;
}
}

在进入context.readWorkbookHolder().getDefaultReturnMap())的时候,在新的版本中默认是true,这样返回map的时候就不会出现前面说的列数据对不上的问题。下面看看返回Map和List有什么区别。

使用List返回的数据示例:

使用Map返回的数据示例:

通过对比,我们就很快可以发现使用List缺少了序号而导致无法把数据对应上,而使用Map的时候,key就是序号,value是我们需要的单元格数据。那么,这个开关在哪里呢?细心的应该看到了,如果你也存在这个问题,又不想升级版本等,可以使用一个开关设置成Map再转换成自己需要的List集合即可。或者说不想用Map,那么都可以自己设置。

public static void main(String[] args) {
// ...省略
ReadSheet readSheet = EasyExcel.readSheet().build();
// 具体的设置开关,新的的版本中默认true
reader.analysisContext().readWorkbookHolder().setDefaultReturnMap(true);
// 开始读取数据
reader.read(readSheet);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
reader.finish();
}

在前面的代码中,添加一句reader.analysisContext().readWorkbookHolder().setDefaultReturnMap(true);,注意这里默认就是true,可以设置为false,返回的数据就是list了。

EasyExcel低版本中数据行中包含空数据会跳过导致数据对应不上的问题解析相关推荐

  1. 问题 C: C语言11.4——设有若干个人员的数据,其中包含学生和教师。学生的数据中包括:号码、姓名、性别、职业、班级。教师的数据包括:号码、姓名、性别、职业、职务。

    题目描述: 设有若干个人员的数据,其中包含学生和教师.学生的数据中包括:号码.姓名.性别.职业.班级.教师的数据包括:号码.姓名.性别.职业.职务.可以看出,学生和教师所包含的数据是不同的.现在要求把 ...

  2. pandas使用idxmax函数获取dataframe每个数据行中最大值对应的列名称(column label of max value in each row in dataframe)

    pandas使用idxmax函数获取dataframe每个数据行中最大值对应的列名称(column label of max value in each row in dataframe) 目录

  3. pandas使用idxmin函数获取dataframe每个数据行中最小值对应的列名称(column label of min value in each row in dataframe)

    pandas使用idxmin函数获取dataframe每个数据行中最小值对应的列名称(column label of min value in each row in dataframe) 目录

  4. pandas删除数据行中的重复数据行、基于dataframe所有列删除重复行、基于特定数据列或者列的作何删除重复行、删除重复行并保留重复行中的最后一行、pandas删除所有重复行(不进行数据保留)

    pandas删除数据行中的重复数据行.基于dataframe所有列删除重复行.基于特定数据列或者列的作何删除重复行.删除重复行并保留重复行中的最后一行.pandas删除所有重复行(不进行数据保留) 目 ...

  5. R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行、基于多数据列not in规则过滤数据行

    R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行.基于多数据列not in规则过滤数据行 目录

  6. as工程放到源码编译_关于AS高版本SDK编译生成的apk放入低版本android源码中集成编译...

    做dfu功能的时候,遇到的这样一个问题.添加了dfu的依赖之后,会要求编译的sdk为28,我的AS版本默认生成的是27.然而target版本是25. // The DFU Library is imp ...

  7. android studio 跳转后保留原页面数据_Intent详解以及Activity的跳转与数据传递

    在上一次讲述Activity的时候,还有一个非常重要且常用的知识点没有讲,就是不同Activity之间的跳转和数据传递.我们在平常在使用app应用的时候,Activity的跳转和数据传递是经常会接触到 ...

  8. #金数据#微信小程序#微信小程序跳转金数据小程序并获取问卷信息

    问题描述:需要实现 在我们自己的微信小程序点击跳转到金数据小程序填写问卷,并且填写问卷后能够把问卷数据保存到项目的数据库里. 解决方法: 1.微信小程序端,主要实现跳转另一个小程序的功能. //按键点 ...

  9. CYUSB3014固件部分低版本工程在Eclipse中编译得到img文件时无效的解决方案

    最近在做基于我们AC6102开发板的UVC图像视频方案,下载了官方的an75779应用工程,但是倒入到FX3-SDK自带的Eclipse中后,却无法编译生成img文件,经过比对后确认是生成该文件的命令 ...

最新文章

  1. 量子计算的符号表示(Dirac notation)
  2. PHP开发工具 zend studio
  3. volatile 使用说明
  4. UVA 10803 Thunder Mountain
  5. Exchange 2007 OWA中出现“HTTP 错误404”解决方法
  6. springcloud 系列教程一:微服务与网站架构演变过程
  7. 38 MM配置-采购-采购订单-采购订单审批-定义采购订单审批过程
  8. 最全使用SQL Server创建、配置数据库的各种方法和注意细节
  9. 后端数据成功返回 页面不渲染_在浏览器地址栏输入地址到页面渲染完成发生了什么?(下)...
  10. 互联网大数据与物联网大数据的区别 你有必要了解下
  11. php web helloworld,webim_server.php
  12. 威廉玛丽学院计算机教授刘旭,专栏-中国计算机学会
  13. MATLAB 数据分析方法(第2版)1.2 MATLAB基础概述
  14. java的rest教程,REST接口
  15. 如何为雷电模拟器安装Burpsuite证书并抓包
  16. 飞行的小鸟论文python_80+行代码实现简单的“飞行的小鸟”游戏
  17. Python有多牛,竟然能被称为高级编程语言?
  18. Manjaro系统更新,wifi用不了,解决方法
  19. HTTP Referer(页面统计/资源防盗链)
  20. C#,两个接口相同名称函数调用时的区分

热门文章

  1. java毕业设计全套基于SSM+Vue的SSM学业预警平台信息管理|学生课程成绩管理系统作业[包运行成功]
  2. 《C语言杂记》详解extern “C“
  3. base64转图片出现的问题及解决方案
  4. quagga 命令定义的代码分析--从定义到实现
  5. ubuntu 命令行卸载并清理软件
  6. Linux下密码恢复及免密登录
  7. win10 mmcv-full mmdection 安装 问题解决方案
  8. 皮皮微信推出广告平台
  9. 女生做前端还是测试,该如何选择?
  10. linux grep 加 正则表达式搜索