Java使用POI解析各种单元格合并的行数、列数和单元格值
程序员文章站
2022-07-13 15:20:34
...
因近期工作需要,要做一个Excel解析的事情,这里要解析的文件为任意Excel文件,其中会包含各种各样的行合并、列合并等操作,需要解析出该Excel中具体行、列、Cell中的值信息,故编写此文章做以记录,如有问题还请指正,谢谢!
1. pom.xml中引用poi相关的包:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
2. 实体类:
@Data
public class ExcelEntity {
/**
* 开始行
*/
private int startRow;
/**
* 结束行
*/
private int endRow;
/**
* 开始列
*/
private int startCol;
/**
* 结束列
*/
private int endCol;
/**
* 单元格值
*/
private String value;
}
3. Excel处理类:
package com.quick.bookdataclean.excel;
import com.quick.bookdataclean.test.ExcelEntity;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 初始作者: drj
* 创建日期: 2019/5/22
* 功能说明:
*/
public class ExcelUtils {
/**
* @Description:读取excel文件
* @author: drj
* @date: 2019/5/22 17:14
*/
public static Map<String, Object> readFileContentToEntity(InputStream inputStream) {
Map<String, Object> excelMap = new HashMap<>(16);
List<List<ExcelEntity>> result = new ArrayList<>();
Workbook wb = null;
try {
wb = WorkbookFactory.create(inputStream);
} catch (IOException | InvalidFormatException e) {
}
if (wb == null) {
return excelMap;
}
// 获取excel中存在的sheet个数
int sheetsNum = wb.getNumberOfSheets();
if (sheetsNum <= 0) {
return excelMap;
}
for (int i = 0; i < sheetsNum; i++) {
Sheet sheet = wb.getSheetAt(i);
// 读取excel数据
if (sheet.getPhysicalNumberOfRows() <= 0) {
continue;
}
int coloumNum = sheet.getRow(0).getPhysicalNumberOfCells();
result.addAll(dealWithExcelSheet(sheet));
// 列总数
excelMap.put("totalColumnNumber", coloumNum);
// 数据集
excelMap.put("data", result);
}
return excelMap;
}
/**
* @Description: 读取sheet中的数据
* @author: drj
* @date: 2019/5/22 17:14
*/
private static List<List<ExcelEntity>> dealWithExcelSheet(Sheet sheet) {
List<List<ExcelEntity>> result = new ArrayList<>();
// 遍历sheet行
for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
List<ExcelEntity> record = new ArrayList<>();
Row row = sheet.getRow(i);
// 遍历行中的没有个单元格
if (row == null || row.getPhysicalNumberOfCells() <= 0) {
continue;
}
for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
Cell cell = row.getCell(j);
if (cell == null) {
continue;
}
// 读取单元格数据格式(标记为字符串)
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
// 处理有值的cell
if (StringUtils.isEmpty(value)) {
continue;
}
try {
value = value.trim();
ExcelEntity entity = new ExcelEntity();
// 起始行数
entity.setStartRow(i);
// 结束行数
entity.setEndRow(getMergeRowNum(cell, sheet) + i - 1);
// 起始列数
entity.setStartCol(j);
// 结束列数
entity.setEndCol(getMergeColumNum(cell, sheet) + j - 1);
// 单元格数据
entity.setValue(value);
record.add(entity);
} catch (NumberFormatException e) {
}
}
result.add(record);
}
return result;
}
/**
* @param cell 当前cell
* @param sheet 当前sheet
* @Description: 获取当前cell合并的行数
* @author: drj
* @date: 2019/5/22 18:00
*/
public static int getMergeRowNum(Cell cell, Sheet sheet) {
int mergeSize = 1;
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
for (CellRangeAddress cellRangeAddress : mergedRegions) {
if (cellRangeAddress.isInRange(cell)) {
//获取合并的行数
mergeSize = cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow() + 1;
break;
}
}
return mergeSize;
}
/**
* @param cell 当前cell
* @param sheet 当前sheet
* @Description: 获取合并的列数
* @author: drj
* @date: 2019/5/22 17:59
*/
public static int getMergeColumNum(Cell cell, Sheet sheet) {
int mergeSize = 1;
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
for (CellRangeAddress cellRangeAddress : mergedRegions) {
if (cellRangeAddress.isInRange(cell)) {
//获取合并的列数
mergeSize = cellRangeAddress.getLastColumn() - cellRangeAddress.getFirstColumn() + 1;
break;
}
}
return mergeSize;
}
}
4. 工具类具体调用方式:
public static void main(String[] args) {
String path = "C:\\Users\\Administrator\\Desktop\\demo.xls";
File file = new File(path);
if (file.exists()) {
try {
InputStream fileInput = new FileInputStream(file);
Map<String, Object> result = AccountExcelUtils.readFileContentToEntity(fileInput);
System.out.println(JSON.toJSONString(result));
} catch (FileNotFoundException e) {
}
}
}
说明:以上代码中所有catch中Exception均未做处理,如有使用可具体根据各自情况加以抛出。