easyexcel读取合并单元格

简介: easyexcel读取合并单元格

easyexcel读取合并单元格

一、设置读取额外信息

20201201174130195.png

二、重写Listener中的extra()方法,获取合并单元格的信息

20201201174130195.png

三、遍历合并单元格的信息

  1. 合并单元格只有第一个(firstRowIndex,firstColumnIndex)有值,所以要取到这个值。
  2. 通过获取到的合并单元格信息(firstRowIndex,lastRowIndex,firstColumnIndex,lastColumnIndex),遍历此区域的每一个单元格,并给每一个单元格都赋上该值
  3. 此方法的重点在于利用反射找到实体对应的属性,对应关系是@ExcelProperty(index = 0)->columnIndexindex对应了columnIndex(也就是字段在excel所在的位置);rowindex对应了解析出来的List data的索引值

四、代码清单

1. UploadDataListener.java

importcom.alibaba.excel.context.AnalysisContext;
importcom.alibaba.excel.event.AnalysisEventListener;
importcom.alibaba.excel.metadata.CellExtra;
importcom.alibaba.fastjson.JSON;
importcom.baomidou.mybatisplus.extension.api.Assert;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importjava.util.ArrayList;
importjava.util.List;
/*** 模板的读取类** @author wangwei*/publicclassUploadDataListener<T>extendsAnalysisEventListener<T> {
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(UploadDataListener.class);
/*** 解析的数据*/List<T>list=newArrayList<>();
/*** 正文起始行*/privateIntegerheadRowNumber;
/*** 合并单元格*/privateList<CellExtra>extraMergeInfoList=newArrayList<>();
publicUploadDataListener(IntegerheadRowNumber) {
this.headRowNumber=headRowNumber;
    }
/*** 这个每一条数据解析都会来调用** @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context context*/@Overridepublicvoidinvoke(Tdata, AnalysisContextcontext) {
LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
list.add(data);
    }
/*** 所有数据解析完成了 都会来调用** @param context context*/@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext) {
LOGGER.info("所有数据解析完成!");
    }
/*** 加上存储数据库*/publicList<T>getData() {
returnlist;
    }
@Overridepublicvoidextra(CellExtraextra, AnalysisContextcontext) {
LOGGER.info("读取到了一条额外信息:{}", JSON.toJSONString(extra));
switch (extra.getType()) {
caseCOMMENT: {
LOGGER.info("额外信息是批注,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(), extra.getColumnIndex(),
extra.getText());
break;
            }
caseHYPERLINK: {
if ("Sheet1!A1".equals(extra.getText())) {
LOGGER.info("额外信息是超链接,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(),
extra.getColumnIndex(), extra.getText());
                } elseif ("Sheet2!A1".equals(extra.getText())) {
LOGGER.info(
"额外信息是超链接,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{},"+"内容是:{}",
extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
extra.getLastColumnIndex(), extra.getText());
                } else {
Assert.fail("Unknown hyperlink!");
                }
break;
            }
caseMERGE: {
LOGGER.info(
"额外信息是合并单元格,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}",
extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
extra.getLastColumnIndex());
if (extra.getRowIndex() >=headRowNumber) {
extraMergeInfoList.add(extra);
                }
break;
            }
default: {
            }
        }
    }
publicList<CellExtra>getExtraMergeInfoList() {
returnextraMergeInfoList;
    }
}

2. ExcelAnalysisHelper.java

importcn.xxx.UploadDataListener;
importcn.xxx.BizException;
importcn.xxx.ResultCode;
importcom.alibaba.excel.EasyExcel;
importcom.alibaba.excel.annotation.ExcelProperty;
importcom.alibaba.excel.enums.CellExtraTypeEnum;
importcom.alibaba.excel.metadata.CellExtra;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.util.CollectionUtils;
importorg.springframework.web.multipart.MultipartFile;
importjava.io.IOException;
importjava.lang.reflect.Field;
importjava.util.List;
/*** @author wangwei* @date 2020-12-01 13:34**/publicclassExcelAnalysisHelper<T> {
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(ExcelAnalysisHelper.class);
publicList<T>getList(MultipartFilefile, Class<T>clazz) {
returngetList(file, clazz, 0, 1);
    }
publicList<T>getList(MultipartFilefile, Class<T>clazz, IntegersheetNo, IntegerheadRowNumber) {
UploadDataListener<T>listener=newUploadDataListener<>(headRowNumber);
try {
EasyExcel.read(file.getInputStream(), clazz, listener).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetNo).headRowNumber(headRowNumber).doRead();
        } catch (IOExceptione) {
LOGGER.error(e.getMessage());
        }
List<CellExtra>extraMergeInfoList=listener.getExtraMergeInfoList();
if (CollectionUtils.isEmpty(extraMergeInfoList)) {
returnlistener.getData();
        }
List<T>data=explainMergeData(listener.getData(), extraMergeInfoList, headRowNumber);
returndata;
    }
/*** 处理合并单元格** @param data               解析数据* @param extraMergeInfoList 合并单元格信息* @param headRowNumber      起始行* @return 填充好的解析数据*/privateList<T>explainMergeData(List<T>data, List<CellExtra>extraMergeInfoList, IntegerheadRowNumber) {
//        循环所有合并单元格信息extraMergeInfoList.forEach(cellExtra-> {
intfirstRowIndex=cellExtra.getFirstRowIndex() -headRowNumber;
intlastRowIndex=cellExtra.getLastRowIndex() -headRowNumber;
intfirstColumnIndex=cellExtra.getFirstColumnIndex();
intlastColumnIndex=cellExtra.getLastColumnIndex();
//            获取初始值ObjectinitValue=getInitValueFromList(firstRowIndex, firstColumnIndex, data);
//            设置值for (inti=firstRowIndex; i<=lastRowIndex; i++) {
for (intj=firstColumnIndex; j<=lastColumnIndex; j++) {
setInitValueToList(initValue, i, j, data);
                }
            }
        });
returndata;
    }
/*** 设置合并单元格的值** @param filedValue  值* @param rowIndex    行* @param columnIndex 列* @param data        解析数据*/publicvoidsetInitValueToList(ObjectfiledValue, IntegerrowIndex, IntegercolumnIndex, List<T>data) {
Tobject=data.get(rowIndex);
for (Fieldfield : object.getClass().getDeclaredFields()) {
//提升反射性能,关闭安全检查field.setAccessible(true);
ExcelPropertyannotation=field.getAnnotation(ExcelProperty.class);
if (annotation!=null) {
if (annotation.index() ==columnIndex) {
try {
field.set(object, filedValue);
break;
                    } catch (IllegalAccessExceptione) {
thrownewBizException(ResultCode.FAILURE, "解析数据时发生异常!");
                    }
                }
            }
        }
    }
/*** 获取合并单元格的初始值* rowIndex对应list的索引* columnIndex对应实体内的字段** @param firstRowIndex    起始行* @param firstColumnIndex 起始列* @param data             列数据* @return 初始值*/privateObjectgetInitValueFromList(IntegerfirstRowIndex, IntegerfirstColumnIndex, List<T>data) {
ObjectfiledValue=null;
Tobject=data.get(firstRowIndex);
for (Fieldfield : object.getClass().getDeclaredFields()) {
//提升反射性能,关闭安全检查field.setAccessible(true);
ExcelPropertyannotation=field.getAnnotation(ExcelProperty.class);
if (annotation!=null) {
if (annotation.index() ==firstColumnIndex) {
try {
filedValue=field.get(object);
break;
                    } catch (IllegalAccessExceptione) {
thrownewBizException(ResultCode.FAILURE, "解析数据时发生异常!");
                    }
                }
            }
        }
returnfiledValue;
    }
}


注:easyexcel版本为2.2.6

<!--========================EasyExcel 配置============================--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency><!--========================EasyExcel 配置结束========================-->



目录
相关文章
|
Java Spring
【注解】Spring AOP 面向切面编程之@Around的详细用法
【注解】Spring AOP 面向切面编程之@Around的详细用法
4166 0
|
XML easyexcel Java
EasyExcel实现对excel文件读写
EasyExcel是阿里巴巴开源的一个excel处理框架,**以使用简单、节省内存著称**。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
2620 1
EasyExcel实现对excel文件读写
|
easyexcel
easyExcel自定定义类型转换
easyExcel自定定义类型转换
1305 0
|
消息中间件 JSON Java
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
37110 1
|
easyexcel
EasyExcel动态合并单元格
EasyExcel动态合并单元格
1327 0
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
1265 0
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
2443 1
|
前端开发 easyexcel Java
springboot使用EasyExcel导入数据(获取行号)
springboot使用EasyExcel导入数据(获取行号)
2221 1
|
IDE Java 开发工具
Lombok 详解:简化 Java 开发的神奇工具
Lombok 是一款 Java 工具,通过注解自动处理如 getter/setter、toString、equals 和 hashCode 等常见代码,减少样板代码。安装 Lombok 需要在 IDE(如 IntelliJ IDEA)中添加插件,并在 Maven 或 Gradle 项目中配置依赖。常用注解包括 @Getter/@Setter 生成访问器,@ToString 生成对象描述,@EqualsAndHashCode 生成比较方法,@NoArgsConstructor/@AllArgsConstructor 生成构造器,@Data 综合应用这些注解。
2099 9
|
SpringCloudAlibaba 监控 Java
SpringCloud Alibaba微服务-- Sentinel的使用(保姆级)
SpringCloud Alibaba微服务-- Sentinel的使用(保姆级)

热门文章

最新文章