解析合并单元格并拆解

​ 前言:废话少说,先看效果再上代码


​ 一. 合并模版

​ 合并模板.xlsx

​ 二. 代码

​ 1.依赖

<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version><exclusions><exclusion><groupId>cn.afterturn</groupId><artifactId>easypoi-wps</artifactId></exclusion></exclusions>
</dependency>

​ 2.代码

@Data
public class Student implements IExcelModel,IExcelDataModel {private static final long serialVersionUID = 1L;//  年级private String gradeName;//  班级@Excel(name = "班级", orderNum = "1", width = 40)private String className;@Excel(name = "姓名", orderNum = "2", width = 40)@NotNull(message = "不能为空")@Size(mess![在这里插入图片描述](https://img-blog.csdnimg.cn/cef3ddc111a7442481f44d0f856a92cf.png#pic_center)
age = "不能超过10个字符", max = 10)private String name;@Excel(name = "性别", orderNum = "3", width = 40, replace = {"男_1", "女_0"})@NotNull(message = "不能为空")private String sex;@Excel(name = "年龄", orderNum = "4", width = 40)@NotNull(message = "不能为空")private String age;private String errorMsg;private Integer rowNum;@Overridepublic String getErrorMsg() {return errorMsg;}@Overridepublic void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}@Overridepublic Integer getRowNum() {return rowNum;}@Overridepublic void setRowNum(Integer rowNum) {this.rowNum = rowNum;}}
@Overridepublic void importExcel(MultipartFile file, HttpServletRequest request) throws Exception {//    1.获取workBookWorkbook workbook = ExcelUtil.getWorkbook(file);
//    2.获取sheet页 TODO 默认单页导入 多页导入下集分享 敬请期待Sheet sheetAt0 = workbook.getSheetAt(0);
//    3.拆解合并单元格 拆解后就相当于是普通的excel导入了decomposeMergedCell(sheetAt0);
//    4.使用EasyPOI内的ExcelUtil工具类根据Entity.class内@Excel注解与导入文件匹配
//    从而导入数据ByteArrayOutputStream outputStream = new ByteArrayOutputStream();workbook.write(outputStream);ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());//    导入文件配置ImportParams params = new ImportParams();//表格标题行数,默认0  表示没有标题params.setTitleRows(0);//表头行数,默认1   表示有一行表头params.setHeadRows(1);//开始读取的sheet位置,默认为0params.setStartSheetIndex(0);//需要校验params.setNeedVerify(true);ExcelImportResult<Student> importResult = ExcelImportUtil.importExcelMore(inputStream,Student.class, params);
//    5.第三步可使纵向合并拆解第四部成功匹配到属性上,但是还有横向合并单元格需要特殊处理一下
//    因年级占单独一行且在头一行 导入后把校验通过与不通过的放一起重新排序,
//    再根据相同类型字段值全部一致判断该行数据是年级名List<Student> list = importResult.getList();list.addAll(importResult.getFailList());specialDispose(list);
//      重新分组list = list.stream().filter(pomVo -> StringUtils.isBlank(pomVo.getErrorMsg())).collect(Collectors.toList());
//    解析完成list.forEach(System.out::println);System.out.println("SOCCESS");}private void specialDispose(List<Student> list) {String gradeName = "";Iterator<Student> iterator = list.iterator();while (iterator.hasNext()) {Student student = iterator.next();student.setGradeName(gradeName);
//     年级名称if (null != student.getClassName() &&student.getClassName().equals(student.getName())) {gradeName = student.getClassName();iterator.remove();}}public void decomposeMergedCell(Sheet sheetAt0) {//获取合并单元格信息的hashmapMap<String, Integer[]> mergedRegionMap = ExcelUtil.getMergedRegionMap(sheetAt0);//拿到excel的最后一行的索引int lastRowNum = sheetAt0.getLastRowNum();//从excel的第二行索行开始,遍历到最后一行(第一行是标题,直接跳过不读取)for (int i = 0; i <= lastRowNum; i++) {//拿到excel的行对象Row row = sheetAt0.getRow(i);//获取excel的行中有多个列int cellNum = row.getLastCellNum();//对每行进行列遍历,即一列一列的进行解析for (int j = 0; j < cellNum; j++) {//拿到了excel的列对象Cell cell = row.getCell(j);//将列对象的行号和列号+下划线组成key去hashmap中查询,不为空说明当前的cell是合并单元列Integer[] firstRowNumberAndCellNumber = mergedRegionMap.get(i + "_" + j);//如果是合并单元列,就取合并单元格的首行和首列所在位置读数据,否则就是直接读数据if (firstRowNumberAndCellNumber != null) {Row rowTmp = sheetAt0.getRow(firstRowNumberAndCellNumber[0]);Cell cellTmp = rowTmp.getCell(firstRowNumberAndCellNumber[1]);setCellValue(cellTmp, cell);}}}}public String setCellValue(Cell cellTmp, Cell cell) {if (cellTmp == null) {return "";}if (cellTmp.getCellType() == CellType.STRING) {cell.setCellValue(cellTmp.getStringCellValue());return cellTmp.getStringCellValue();} else if (cellTmp.getCellType() == CellType.BOOLEAN) {cell.setCellValue(cellTmp.getBooleanCellValue());return String.valueOf(cellTmp.getBooleanCellValue());} else if (cellTmp.getCellType() == CellType.FORMULA) {cell.setCellValue(cellTmp.getCellFormula());return cellTmp.getCellFormula();} else if (cellTmp.getCellType() == CellType.NUMERIC) {cell.setCellValue(cellTmp.getNumericCellValue());return String.valueOf(cellTmp.getNumericCellValue());}return "";}//将存在合并单元格的列记录入put进hashmap并返回public static Map<String,Integer[]> getMergedRegionMap(Sheet sheet){Map<String,Integer[]> result = new HashMap<String,Integer[]>();//获取excel中的所有合并单元格信息int sheetMergeCount = sheet.getNumMergedRegions();//遍历处理for (int i = 0; i < sheetMergeCount; i++) {//拿到每个合并单元格,开始行,结束行,开始列,结束列CellRangeAddress range = sheet.getMergedRegion(i);int firstColumn = range.getFirstColumn();int lastColumn = range.getLastColumn();int firstRow = range.getFirstRow();int lastRow = range.getLastRow();//构造一个开始行和开始列组成的数组Integer[] firstRowNumberAndCellNumber = new Integer[]{firstRow,firstColumn};//遍历,将单元格中的所有行和所有列处理成由行号和下划线和列号组成的key,然后放在hashmap中for(int currentRowNumber = firstRow; currentRowNumber <= lastRow; currentRowNumber++) {for(int currentCellNumber = firstColumn; currentCellNumber <= lastColumn; currentCellNumber ++) {result.put(currentRowNumber+"_"+currentCellNumber, firstRowNumberAndCellNumber);}}}return result;}

​ 三.总结

1.本次分享是先解析拆解到workbook在进行导入.
2.横列合并单元格个人是没有好的方法进行拆分只能按照业务逻辑灵活处理.
3.重在记录,欢迎评价、指正.

EasyPOI 解析合并单元格并拆解相关推荐

  1. easypoi导入合并单元格_Word简历导入Excel,还在手动调整格式就out了,同事三步完成切换...

    今天老板把10个人的Word简历让我导入到Excel表格存档,复制Word表格到Excel后表格格式完全错乱,搞得我调整间距.宽度等加班了2小时. 如上图我将Word简历的表格完全复制到Excel之后 ...

  2. easypoi导入合并单元格_1分钟不到就能合并100个Excel工作表,这功能太强大了!...

    之前易老师有给各位小伙伴分享过<将100份Word文档全部合并到一个文档需要多久?>,许多小伙伴留言问我:那EXCEL中该如何合并呢?所以,这里易老师特意给大伙分享一下,利用PQ在EXCE ...

  3. EasyExcel解析excel(合并单元格和未合并)

    未合并的单元格excel文件 /*** 转换用户上传的excel文件为java对象** @param file 用户上传的文件* @param clazz 将被解析的类* @param <T&g ...

  4. easypoi利用模板导出图片到Excel;解决easypoi导出图片到合并单元格单元格被拉伸的问题

    easypoi的封装是非常好的,用起来很简单. 官方教程地址:http://easypoi.mydoc.io/ 但是在使用模板导出图片到合并单元格时出问题了,官网找了好几遍没找到方案. 其实官方早就实 ...

  5. easypoi导出一对多,合并单元格,且根据内容自适应行高

    easypoi导出一对多,合并单元格,且根据内容自适应行高 EasyPoi一对多导出 一.pom引入依赖 二.导出实体类 excelPoi常用注解说明 @Excel注解 @ExcelCollectio ...

  6. 用easyPoi导出excel,带多sheet,合并单元格,合计,单元格金额类型

    用easyPoi导出excel,带多sheet,合并单元格,合计,单元格金额类型 文档连接:http://easypoi.mydoc.io/ 1.引入依赖 <!-- 导出文件工具 EasyPoi ...

  7. easypoi 模板导出兼容合并单元格功能

    最新在使用easypoi,使用注解导出和模板导出的方式,现在主要就模板导出合并单元格一些坑和解决方法. 首先我建议刚接触的同学看这篇文章,很详细,功能也比较全面,比较感谢这篇文章的原创作者,网站1:e ...

  8. easypoi一对多,合并单元格,并且根据内容自适应行高

    记录一下 效果 一.引入依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypo ...

  9. EasyPoi导出复杂合并单元格

    前言: 上星期做了一个Excel的单元格合并,用的是EasyPoi,我之前合并单元格都是原生的,第一次使用EasyPoi合并也不太熟悉,看着网上自己套用,使用后发现比原生的方便些,贡献一下,也给其他用 ...

最新文章

  1. 【Python-ML】无监督线性降维PCA方法
  2. 谷歌雇程序员提升开源安全
  3. ARM体系结构简介 —— 迅为
  4. 【Loj - 515】贪心只能过样例(暴力,或01背包 + bitset)
  5. SpringMVC自学日志07(整合Mybatic)
  6. html和css的重难点知识
  7. Uber地图部门三员大将离职创业,要解决无人驾驶出租车的派单问题
  8. 查看、删除本地电脑,连接过的共有文件夹(盘符) 「net use」
  9. 加入MapReduce后完全分布式集群搭建
  10. display和float使用上的区别(1)-----多栏布局的实现
  11. 创建一个war类型的maven项目
  12. python linux 打印机,Python抓取打印机硒鼓和组件剩余量的爬虫
  13. 文献学习笔记丨转录组表达数据的生信挖掘研究
  14. 基于51单片机的温度检测调节系统设计
  15. BigDecimal实现加减乘除
  16. 零知识 QAP 问题的转化
  17. 结合使用katex html2canvas 将LaTeX公式保存为图片
  18. import-from
  19. qt实现简易图片转换功能
  20. linux聊天python_Python socket C/S结构的聊天室应用

热门文章

  1. 关于搜索引擎使用方法的一些小窍门
  2. Excel VBA 多重筛选
  3. (3DV 2017) SEGCloud: Semantic Segmentation of 3D Point Clouds
  4. 2.3 组织过程资产
  5. PLM系统集成Autovue插件
  6. Redis的日志级别
  7. **(p+1)和*(*p+1)的区别
  8. Xilinx 7系列FPGA PCB设计指导(二)
  9. Qt-FFmpeg开发-打开本地摄像头(6)
  10. 在App Inventor中实例:画画(Canvas组件)