easyexcel读取合并单元格
easyexcel读取合并单元格
文章目录
- easyexcel读取合并单元格
- 一、设置读取额外信息
- 二、重写Listener中的extra()方法,获取合并单元格的信息
- 三、遍历合并单元格的信息
- 四、代码清单
- 1. UploadDataListener.java
- 2. ExcelAnalysisHelper.java
一、设置读取额外信息
二、重写Listener中的extra()方法,获取合并单元格的信息
三、遍历合并单元格的信息
- 合并单元格只有第一个(firstRowIndex,firstColumnIndex)有值,所以要取到这个值。
- 通过获取到的合并单元格信息(firstRowIndex,lastRowIndex,firstColumnIndex,lastColumnIndex),遍历此区域的每一个单元格,并给每一个单元格都赋上该值
- 此方法的重点在于利用反射找到实体对应的属性,对应关系是@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读取合并单元格相关推荐
- easyexcel读取合并单元格内容_一周一个小技巧 | excel不会核对内容?不会填充合并单元格?7个实用的EXCEL技巧,一起来看看吧...
上方蓝色字,获取更多就业信息~ 1 两列姓名核对 如果要核对表二中的姓名在表一中有没有出现,一个公式马上搞定.=IF(COUNTIF(A:A,C2),"是","否&qu ...
- easyexcel处理合并单元格数据
一.背景 一次工作任务是要解析excel数据,采用阿里的 easyexcel 工具进行解析,由于表格有合并单元格,但是 easyexcel 读取合并单元格只会读取一次,导致下面单元格数据为空,这样会影 ...
- poi读取合并单元格
poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...
- python 读取合并单元格的数据_Python使用xlrd实现读取合并单元格
合并单元格 操作方法: 1.使用xlrd自带属性:merged_cells # 获取表格中所有合并单元格位置,以列表形式返回 (起始行,结束行,起始列,结束列) merged = sheet.merg ...
- easyexcel 动态合并单元格
easyexcel 动态合并单元格 目前操作excel文档的底层都是用poi来进行的,在早期工作开发过程中,是基于poi,然后对每一个数据单元格进行操作代码编写,后面有一些比较好的开源项目,像easy ...
- python 读取合并单元格的excel_python 利用三方的xlrd模块读取excel文件,处理合并单元格...
目的: python能使用xlrd模块实现对Excel数据的读取,且按照想要的输出形式. 总体思路: (1)要想实现对Excel数据的读取,需要用到第三方应用,直接应用. (2)实际操作时候和我们实际 ...
- easyExcel中合并单元格文件读取实现方案
1.需求场景描述 2.问题分析与实现方案 1.需求场景描述 现在有个业务需要按照指定模板上传选择题,并进行入表处理,使用easyExcel进行文件上传并读取数据,其中涉及合并单元数据读取问题,这里简单 ...
- python 读取合并单元格 视频_Python如何使用xlrd实现读取合并单元格
合并单元格 操作方法: 1.使用xlrd自带属性:merged_cells # 获取表格中所有合并单元格位置,以列表形式返回 (起始行,结束行,起始列,结束列) merged = sheet.merg ...
- java读取合并单元格_Java POI常用方法,读取单元格的值,设置单元格格式,合并单元格,获取已合并的单元格,导出至本地等...
一.设置单元格格式. 设置单元格边框.单元格背景颜色.单元格对齐方式.单元格字体,设置自动换行. /** Description: 设置单元格格式. * @author : ys. * @date : ...
最新文章
- 使用class weight和sample weight处理不平衡问题
- 靠Python数据分析已赚10w的本科生
- 支付宝支付 第五集:二维码生成工具
- poj 2104: K-th Number 【主席树】
- python time datetime string 相互转换
- proc文件系统编程
- Silverlight 全屏模式
- 1223: 输出汉诺塔问题的盘子移动步骤(Java)
- 【设计模式】代理模式 ( 动态代理 )
- CSS网页制作布局实例教程
- 用友老是显示服务器错误,客户端连服务器出现这样的错误框
- 【若依(ruoyi)】自定义的数据选择对话框
- dll文件的c++制作
- 等级考试(一):三级网络---似曾相识
- linux qt目录查看,QT遍历目录获取文件信息
- Linux学习(1)阿里云服务器及配置、使用xshell远程连接
- 怎么使用虚拟机装服务器系统,如果使用VMware虚拟机创建系统,超详细安装图文教程...
- C语言-学习笔记完整版
- 线性代数 向量组 线性相关与表出 秩 解的关系总(一)
- 为什么word打字换行的时候突然上一行文字间距变大了?如图
热门文章
- [我的作死案例]图书馆泡妹记 上
- 硬件PM系列(二):硬件产品经理需要熟知的设计流程
- 【软考】 5 计算机网络
- 惊,面N次都不对:++ 操作不是线程全的
- 使用163网易相册的朋友注意啦!
- Tiny-DSOD: Lightweight Object Detection for Resource-Restricted Usages
- java点击按钮发出声音_java – 按下按钮时播放声音-android
- 一.学习前的准备-java程序员必备知识
- nth-child和nth-of-type的区别
- java中scanner是什么意思_java中scanner是什么