因近期工作需要,要做一个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均未做处理,如有使用可具体根据各自情况加以抛出。