easyexcel读取合并单元格

文章目录

  • easyexcel读取合并单元格
    • 一、设置读取额外信息
    • 二、重写Listener中的extra()方法,获取合并单元格的信息
    • 三、遍历合并单元格的信息
    • 四、代码清单
      • 1. UploadDataListener.java
      • 2. ExcelAnalysisHelper.java

一、设置读取额外信息

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

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

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

四、代码清单

1. UploadDataListener.java

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.api.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.ArrayList;
import java.util.List;/*** 模板的读取类** @author wangwei*/
public class UploadDataListener<T> extends AnalysisEventListener<T> {private static final Logger LOGGER = LoggerFactory.getLogger(UploadDataListener.class);/*** 解析的数据*/List<T> list = new ArrayList<>();/*** 正文起始行*/private Integer headRowNumber;/*** 合并单元格*/private List<CellExtra> extraMergeInfoList = new ArrayList<>();public UploadDataListener(Integer headRowNumber) {this.headRowNumber = headRowNumber;}/*** 这个每一条数据解析都会来调用** @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context context*/@Overridepublic void invoke(T data, AnalysisContext context) {LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));list.add(data);}/*** 所有数据解析完成了 都会来调用** @param context context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {LOGGER.info("所有数据解析完成!");}/*** 加上存储数据库*/public List<T> getData() {return list;}@Overridepublic void extra(CellExtra extra, AnalysisContext context) {LOGGER.info("读取到了一条额外信息:{}", JSON.toJSONString(extra));switch (extra.getType()) {case COMMENT: {LOGGER.info("额外信息是批注,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(), extra.getColumnIndex(),extra.getText());break;}case HYPERLINK: {if ("Sheet1!A1".equals(extra.getText())) {LOGGER.info("额外信息是超链接,在rowIndex:{},columnIndex;{},内容是:{}", extra.getRowIndex(),extra.getColumnIndex(), extra.getText());} else if ("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;}case MERGE: {LOGGER.info("额外信息是合并单元格,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}",extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),extra.getLastColumnIndex());if (extra.getRowIndex() >= headRowNumber) {extraMergeInfoList.add(extra);}break;}default: {}}}public List<CellExtra> getExtraMergeInfoList() {return extraMergeInfoList;}
}

2. ExcelAnalysisHelper.java

import cn.xxx.UploadDataListener;
import cn.xxx.BizException;
import cn.xxx.ResultCode;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;/*** @author wangwei* @date 2020-12-01 13:34**/
public class ExcelAnalysisHelper<T> {private static final Logger LOGGER = LoggerFactory.getLogger(ExcelAnalysisHelper.class);public List<T> getList(MultipartFile file, Class<T> clazz) {return getList(file, clazz, 0, 1);}public List<T> getList(MultipartFile file, Class<T> clazz, Integer sheetNo, Integer headRowNumber) {UploadDataListener<T> listener = new UploadDataListener<>(headRowNumber);try {EasyExcel.read(file.getInputStream(), clazz, listener).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetNo).headRowNumber(headRowNumber).doRead();} catch (IOException e) {LOGGER.error(e.getMessage());}List<CellExtra> extraMergeInfoList = listener.getExtraMergeInfoList();if (CollectionUtils.isEmpty(extraMergeInfoList)) {return listener.getData();}List<T> data = explainMergeData(listener.getData(), extraMergeInfoList, headRowNumber);return data;}/*** 处理合并单元格** @param data               解析数据* @param extraMergeInfoList 合并单元格信息* @param headRowNumber      起始行* @return 填充好的解析数据*/private List<T> explainMergeData(List<T> data, List<CellExtra> extraMergeInfoList, Integer headRowNumber) {//        循环所有合并单元格信息extraMergeInfoList.forEach(cellExtra -> {int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNumber;int lastRowIndex = cellExtra.getLastRowIndex() - headRowNumber;int firstColumnIndex = cellExtra.getFirstColumnIndex();int lastColumnIndex = cellExtra.getLastColumnIndex();
//            获取初始值Object initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, data);
//            设置值for (int i = firstRowIndex; i <= lastRowIndex; i++) {for (int j = firstColumnIndex; j <= lastColumnIndex; j++) {setInitValueToList(initValue, i, j, data);}}});return data;}/*** 设置合并单元格的值** @param filedValue  值* @param rowIndex    行* @param columnIndex 列* @param data        解析数据*/public void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, List<T> data) {T object = data.get(rowIndex);for (Field field : object.getClass().getDeclaredFields()) {//提升反射性能,关闭安全检查field.setAccessible(true);ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);if (annotation != null) {if (annotation.index() == columnIndex) {try {field.set(object, filedValue);break;} catch (IllegalAccessException e) {throw new BizException(ResultCode.FAILURE, "解析数据时发生异常!");}}}}}/*** 获取合并单元格的初始值* rowIndex对应list的索引* columnIndex对应实体内的字段** @param firstRowIndex    起始行* @param firstColumnIndex 起始列* @param data             列数据* @return 初始值*/private Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<T> data) {Object filedValue = null;T object = data.get(firstRowIndex);for (Field field : object.getClass().getDeclaredFields()) {//提升反射性能,关闭安全检查field.setAccessible(true);ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);if (annotation != null) {if (annotation.index() == firstColumnIndex) {try {filedValue = field.get(object);break;} catch (IllegalAccessException e) {throw new BizException(ResultCode.FAILURE, "解析数据时发生异常!");}}}}return filedValue;}
}

注:easyexcel版本为2.2.6

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

easyexcel读取合并单元格相关推荐

  1. easyexcel读取合并单元格内容_一周一个小技巧 | excel不会核对内容?不会填充合并单元格?7个实用的EXCEL技巧,一起来看看吧...

    上方蓝色字,获取更多就业信息~ 1 两列姓名核对  如果要核对表二中的姓名在表一中有没有出现,一个公式马上搞定.=IF(COUNTIF(A:A,C2),"是","否&qu ...

  2. easyexcel处理合并单元格数据

    一.背景 一次工作任务是要解析excel数据,采用阿里的 easyexcel 工具进行解析,由于表格有合并单元格,但是 easyexcel 读取合并单元格只会读取一次,导致下面单元格数据为空,这样会影 ...

  3. poi读取合并单元格

    poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...

  4. python 读取合并单元格的数据_Python使用xlrd实现读取合并单元格

    合并单元格 操作方法: 1.使用xlrd自带属性:merged_cells # 获取表格中所有合并单元格位置,以列表形式返回 (起始行,结束行,起始列,结束列) merged = sheet.merg ...

  5. easyexcel 动态合并单元格

    easyexcel 动态合并单元格 目前操作excel文档的底层都是用poi来进行的,在早期工作开发过程中,是基于poi,然后对每一个数据单元格进行操作代码编写,后面有一些比较好的开源项目,像easy ...

  6. python 读取合并单元格的excel_python 利用三方的xlrd模块读取excel文件,处理合并单元格...

    目的: python能使用xlrd模块实现对Excel数据的读取,且按照想要的输出形式. 总体思路: (1)要想实现对Excel数据的读取,需要用到第三方应用,直接应用. (2)实际操作时候和我们实际 ...

  7. easyExcel中合并单元格文件读取实现方案

    1.需求场景描述 2.问题分析与实现方案 1.需求场景描述 现在有个业务需要按照指定模板上传选择题,并进行入表处理,使用easyExcel进行文件上传并读取数据,其中涉及合并单元数据读取问题,这里简单 ...

  8. python 读取合并单元格 视频_Python如何使用xlrd实现读取合并单元格

    合并单元格 操作方法: 1.使用xlrd自带属性:merged_cells # 获取表格中所有合并单元格位置,以列表形式返回 (起始行,结束行,起始列,结束列) merged = sheet.merg ...

  9. java读取合并单元格_Java POI常用方法,读取单元格的值,设置单元格格式,合并单元格,获取已合并的单元格,导出至本地等...

    一.设置单元格格式. 设置单元格边框.单元格背景颜色.单元格对齐方式.单元格字体,设置自动换行. /** Description: 设置单元格格式. * @author : ys. * @date : ...

最新文章

  1. 使用class weight和sample weight处理不平衡问题
  2. 靠Python数据分析已赚10w的本科生
  3. 支付宝支付 第五集:二维码生成工具
  4. poj 2104: K-th Number 【主席树】
  5. python time datetime string 相互转换
  6. proc文件系统编程
  7. Silverlight 全屏模式
  8. 1223: 输出汉诺塔问题的盘子移动步骤(Java)
  9. 【设计模式】代理模式 ( 动态代理 )
  10. CSS网页制作布局实例教程
  11. 用友老是显示服务器错误,客户端连服务器出现这样的错误框
  12. 【若依(ruoyi)】自定义的数据选择对话框
  13. dll文件的c++制作
  14. 等级考试(一):三级网络---似曾相识
  15. linux qt目录查看,QT遍历目录获取文件信息
  16. Linux学习(1)阿里云服务器及配置、使用xshell远程连接
  17. 怎么使用虚拟机装服务器系统,如果使用VMware虚拟机创建系统,超详细安装图文教程...
  18. C语言-学习笔记完整版
  19. 线性代数 向量组 线性相关与表出 秩 解的关系总(一)
  20. 为什么word打字换行的时候突然上一行文字间距变大了?如图

热门文章

  1. [我的作死案例]图书馆泡妹记 上
  2. 硬件PM系列(二):硬件产品经理需要熟知的设计流程
  3. 【软考】 5 计算机网络
  4. 惊,面N次都不对:++ 操作不是线程全的
  5. 使用163网易相册的朋友注意啦!
  6. Tiny-DSOD: Lightweight Object Detection for Resource-Restricted Usages
  7. java点击按钮发出声音_java – 按下按钮时播放声音-android
  8. 一.学习前的准备-java程序员必备知识
  9. nth-child和nth-of-type的区别
  10. java中scanner是什么意思_java中scanner是什么