首页 > 其他分享 >easypoi解析合并单元格并拆解

easypoi解析合并单元格并拆解

时间:2023-07-25 16:33:35浏览次数:34  
标签:return String int 单元格 private cellTmp 拆解 easypoi

解析合并单元格并拆解
? 前言:废话少说,先看效果再上代码

 


? 一. 合并模版

? 合并模板.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>
1
2
3
4
5
6
7
8
9
10
11
? 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![在这里插入图片描述](/i/ll/?i=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;

@Override
public String getErrorMsg() {
return errorMsg;
}

@Override
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}


@Override
public Integer getRowNum() {
return rowNum;
}

@Override
public void setRowNum(Integer rowNum) {
this.rowNum = rowNum;
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@Override
public void importExcel(MultipartFile file, HttpServletRequest request) throws Exception {
// 1.获取workBook
Workbook 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位置,默认为0
params.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) {
//获取合并单元格信息的hashmap
Map<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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
? 三.总结

1.本次分享是先解析拆解到workbook在进行导入.
2.横列合并单元格个人是没有好的方法进行拆分只能按照业务逻辑灵活处理.
3.重在记录,欢迎评价、指正.
————————————————
版权声明:本文为CSDN博主「铁头头铁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44533642/article/details/129362629

标签:return,String,int,单元格,private,cellTmp,拆解,easypoi
From: https://www.cnblogs.com/ai917882940/p/17580200.html

相关文章

  • 拆解雪花算法生成规则
    1介绍雪花算法(Snowflake)是一种生成分布式全局唯一ID的算法,生成的ID称为SnowflakeIDs或snowflakes。这种算法由Twitter创建,并用于推文的ID。目前仓储平台生成ID是用的雪花算法修改后的版本。雪花算法几个特性生成的ID分布式唯一和按照时间递增有序,毫秒数在高位,自增序列在低......
  • openpyxl模块--------------------------合并单元格功能
    #!/usr/bin/envpythonfromopenpyxlimportWorkbookfromopenpyxl.stylesimportAlignmentbook=Workbook()sheet=book.activesheet.merge_cells('A1:B2')cell=sheet.cell(row=1,column=1)cell.value='Sunnyday'cell.alignment=Alignment(h......
  • Apache POI excel导出(单元格html代码渲染)
    需求:将渲染后的html代码,导出到单元格中。依赖<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.8.2</version></dependency>代码实现publicclassExcelUtil{/***设置单元格......
  • Apache POI读取单元格多文本多样式
    需求:读取excel单元格数据(文本和部分样式),并拼接成html代码。代码实现/***工作簿*/privateWorkbookwb;/***导入的excel类型*/privateStringexcelType;/***2003-2007版本*/privatestaticfinalStringEXCEL_TYPE_2003="xls";/***20......
  • poi导出excel加水印,单元格可修改 java 下载生成Excel文件添加水印
    poi导出excel加水印,单元格可修改java下载生成Excel文件添加水印原文链接:https://blog.csdn.net/weixin_40077255/article/details/112848376目录poi导出excel加水印,单元格可修改(只支持XSSFWorkbook)引入的jar包:操作水印的工具类:最终效果 小提示poi导出excel加水印......
  • KerberosSDR硬件拆解
    接下来把kerberossdr拆开来看看里面到底是什么样子的。这个板子应该是4个rtlsdr组成,里面还有一个噪声源,还有一个四合一的usbhub。这个设备目前没有天线切换,所以每次校准都需要人来把天线拔掉换上虚负载然后用噪声源校准,所以天线和噪声源应该接在一起的。另外为了采样时间同......
  • 每N行合并单元格 LoopMergeStrategy
    对每N行合并单元格LoopMergeStrategy对1到11列(下标从0开始)每6行合并  EasyExcel.write(file).head(title).registerWriteHandler(newLoopMergeStrategy(6,0)).registerWriteHandler(newLoopMergeStrategy(6,1))......
  • Excel单元格进入编辑模式,保存更改退出编辑模式
    在Excel中,按F2键可以进入单元格的编辑模式,以便在单元格中编辑公式或文本。要退出编辑模式并保存更改,可以按Enter键或Tab键。如果要放弃更改并退出编辑模式,可以按Esc键。以下是一些常见的方法来退出编辑模式:按下Enter键:按下Enter键将保存更改并将焦点移动到下一个......
  • Camstar表格自定义写js,实现单元格合并。
     效果: ......
  • 按单元格填充颜色或字体颜色统计数据的自定义函数
    参考网络代码,自己写了二个通用的自定义函数,用于统计不同颜色的单元格数值或个数。1FunctionSumColor(rngAsRange,cellColorAsRange,NAsByte)AsDouble23'输入=SumColor(A1:A10,A1,0),其中A1:A10是统计的范围,A1是统计的颜色所在的单元格,0表示按照背景......