将带有“合并单元格”的 Excel 进行解析,Excel 示例如下:
Java 生态中 Excel 解析库比较多,下面介绍两种比较常用的库
在本示例中,将使用 POI 来解析 Excel 。需要注意的是 ,POI 对 xls
和 xlsx
格式的 Excel 采用不同的 API ,分别是 org.apache.poi.hssf.usermodel.HSSFWorkbook
和 org.apache.poi.xssf.usermodel.XSSFWorkbook
。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
以下示例展示了解析 xls
格式的 Excel 。
package com.xzbd.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import cn.hutool.core.collection.CollectionUtil;
public class ExcelUtil {
public static void main(String[] args) throws IOException {
String filePath = "<your-excel-dir>\\ParseDemo.xls";
File file = new File(filePath);
if (!file.exists()) {
System.out.println(" File not exists ...");
return;
}
FileInputStream fis = new FileInputStream(file);
Workbook workbook = new HSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
// 遍历每行数据
for (Row row : sheet) {
// 遍历每个单元格
for (Cell cell : row) {
CellRangeAddress cellRangeAddress = getCellRangeAddress(mergedRegions, cell);
String value = "";
if (Objects.nonNull(cellRangeAddress)) {
value = getCellRangeAddressValue(cellRangeAddress, sheet);
} else {
value = getStringValue(cell);
}
System.out.print(value + "\t");
}
System.out.println();
}
// 关闭资源
workbook.close();
fis.close();
}
public static String getCellRangeAddressValue(CellRangeAddress cellRangeAddress, Sheet sheet) {
if (Objects.isNull(cellRangeAddress)) {
return StringUtils.EMPTY;
}
if (Objects.isNull(sheet)) {
return StringUtils.EMPTY;
}
Row row = sheet.getRow(cellRangeAddress.getFirstRow());
if (Objects.isNull(row)) {
return StringUtils.EMPTY;
}
Cell cell = row.getCell(cellRangeAddress.getFirstColumn());
if (Objects.isNull(cell)) {
return StringUtils.EMPTY;
}
return getStringValue(cell);
}
public static CellRangeAddress getCellRangeAddress(List<CellRangeAddress> mergedRegions, Cell cell) {
if (CollectionUtil.isEmpty(mergedRegions)) {
return null;
}
if (Objects.isNull(cell)) {
return null;
}
for (CellRangeAddress mergedRegion : mergedRegions) {
Boolean in = mergedRegion.isInRange(cell);
if (in) {
return mergedRegion;
}
}
return null;
}
/**
* 判断当前单元格是否在合并单元格区域内
*
* @param mergedRegion
* @param cell
* @return
*/
public static Boolean isInMergedRegin(CellRangeAddress mergedRegion, Cell cell) {
if (Objects.isNull(mergedRegion)) {
return false;
}
if (Objects.isNull(cell)) {
return false;
}
int row = cell.getRowIndex();
int column = cell.getColumnIndex();
int firstColumn = mergedRegion.getFirstColumn();
int lastColumn = mergedRegion.getLastColumn();
int firstRow = mergedRegion.getFirstRow();
int lastRow = mergedRegion.getLastRow();
// 判断当前单元格是否在合并单元格区域内
if ((row >= firstRow && row <= lastRow) && (column >= firstColumn && column <= lastColumn)) {
return true;
}
return false;
}
public static String getStringValue(Cell cell) {
String value = "";
// 判断单元格类型
if (cell.getCellType() == CellType.STRING) {
value = cell.getStringCellValue();
} else if (cell.getCellType() == CellType.BOOLEAN) {
value = String.valueOf(cell.getBooleanCellValue());
} else if (cell.getCellType() == CellType.NUMERIC) {
value = String.valueOf(cell.getNumericCellValue());
}
return value;
}
}
以下是解析 Excel ,打印出的结果
xxx相关信息 xxx相关信息 xxx相关信息
大类 小类 材料
水果类 苹果 花牛苹果
水果类 香蕉 老山香蕉
水果类 梨 巴山雪梨
蔬菜类 蒜苗 红皮蒜苗
蔬菜类 蒜苗 白皮蒜苗
蔬菜类 辣椒 小米椒
蔬菜类 茄子 胖茄子
肉类 鱼类 三文鱼
肉类 鱼类 金枪鱼
肉类 鱼类 耗儿鱼
本文基于 xls
格式的 Excel 给出了解析合并单元格的示例。且经过运行打印出了解析结果。
要将工具类改为支持 xlsx
格式的 Excel 解析,只需要如下两步操作:
HSSFWorkbook
改为 XSSFWorkbook
并导入包 org.apache.poi.xssf.usermodel.XSSFWorkbook
。 String filePath = "<your-excel-dir>\\ParseDemo.xls";
改为 String filePath = "<your-excel-dir>\\ParseDemo.xlsx";
注意 ParseDemo.xlsx 不是仅仅更改名称,还要创建正确的文件。