1. 概述

在Java中处理Excel文件时,识别空行是常见任务,尤其是在处理大型数据集进行分析或报告时。空行会干扰数据处理流程,可能导致分析结果不准确或增加不必要的复杂性。提前识别这些空行,能确保数据清洗、转换等操作顺利进行。

本教程将介绍三个主流Java库——Apache POIJExcelfastexcel,演示如何使用它们读取Excel表格并检测空行。

2. 使用Apache POI

Apache POI是功能全面的Java Excel处理库,支持*.xls.xlsx*格式,以其灵活性和健壮性被广泛采用。

2.1. Maven依赖

pom.xml中添加依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.3.0</version>
</dependency>

2.2. 检测空行

创建辅助类PoiHelper,通过isRowEmpty()方法检测空行。核心逻辑是遍历行中所有单元格,检查是否为nullCellType.BLANK

public class PoiHelper {
    public static boolean isRowEmpty(Row row) {
        for (int cellNum = row.getFirstCellNum(); cellNum < row.getLastCellNum(); cellNum++) {
            Cell cell = row.getCell(cellNum);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                return false;
            }
        }
        return true;
    }
}

2.3. 测试验证

使用测试文件empty_excel_file.xlsx验证方法:

public class PoiDetectEmptyRowUnitTest {
    
    private PoiHelper poiHelper = new PoiHelper();
    private static final String XLSX_EMPTY_FILE_PATH = "src/main/resources/empty_excel_file.xlsx";
    
    @Test
    public void givenXLSXFile_whenParsingExcelFile_thenDetectAllRowsEmpty() throws IOException {
        try (FileInputStream file = new FileInputStream(XLSX_EMPTY_FILE_PATH);
             Workbook workbook = new XSSFWorkbook(file)) {
            Sheet sheet = workbook.getSheetAt(0);

             for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
                 Row row = sheet.getRow(rowNum);
                 assertTrue(poiHelper.isRowEmpty(row));
             }
        }
    }
}

测试流程:

  1. 使用try-with-resources打开工作簿
  2. 获取第一个工作表
  3. 遍历所有行并调用isRowEmpty()检测
  4. 断言所有行均为空

3. 使用JExcel

JExcel是轻量级Excel处理库,专门优化*.xls*文件操作,以简单易用著称。

3.1. Maven依赖

添加依赖到pom.xml

<dependency>
    <groupId>net.sourceforge.jexcelapi</groupId>
    <artifactId>jxl</artifactId>
    <version>2.6.12</version>
</dependency>

3.2. 检测空行

通过遍历Cell[]数组并检查getContents()判断空行:

public class JExcelHelper {

    public boolean isRowEmpty(Cell[] row) {
        if (row == null) {
            return true;
        }
        for (Cell cell : row) {
            if (cell != null && !cell.getContents().trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }
}

3.3. 测试验证

使用测试文件empty_excel_file.xls

public class JExcelDetectEmptyRowUnitTest {

    private JExcelHelper jexcelHelper = new JExcelHelper();
    private static final String EMPTY_FILE_PATH = "src/main/resources/empty_excel_file.xls";

    @Test
    public void givenXLSFile_whenParsingJExcelFile_thenDetectAllRowsEmpty()
      throws IOException, BiffException {
        Workbook workbook = Workbook.getWorkbook(new File(EMPTY_FILE_PATH));
        Sheet sheet = workbook.getSheet(0);

        for (int rowNum = 0; rowNum < sheet.getRows(); rowNum++) {
            Cell[] row = sheet.getRow(rowNum);
            assertTrue(jexcelHelper.isRowEmpty(row));
        }
    }
}

⚠️ 注意:JExcel仅支持*.xls格式,处理.xlsx*文件会抛出异常。

4. 使用fastexcel

fastexcel是专为高性能读写大型Excel文件设计的轻量级库,在处理超大数据集时表现优异。

4.1. Maven依赖

添加依赖:

<dependency>
    <groupId>org.dhatim</groupId>
    <artifactId>fastexcel</artifactId>
    <version>0.18.3</version>
</dependency>

4.2. 检测空行

通过getText()方法检查单元格内容:

public class FastexcelHelper {
    public boolean isRowEmpty(Row row) {
        if (row == null) {
            return true;
        }
        for (Cell cell : row) {
            if (cell != null && !cell.getText().trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }
}

4.3. 测试验证

使用流式API高效处理大型文件:

public class FastexcelDetectEmptyRowUnitTest {

    private FastexcelHelper fastexcelHelper = new FastexcelHelper();
    private static final String EMPTY_FILE_PATH = "src/main/resources/empty_excel_file.xlsx";
    
    @Test
    public void givenXLSXFile_whenParsingEmptyFastExcelFile_thenDetectAllRowsAreEmpty()
      throws IOException {
        try (FileInputStream file = new FileInputStream(EMPTY_FILE_PATH);
             ReadableWorkbook wb = new ReadableWorkbook(file)) {
            Sheet sheet = wb.getFirstSheet();
            try (Stream<Row> rows = sheet.openStream()) {
                boolean isEmpty = rows.allMatch(fastexcelHelper::isRowEmpty);
                assertTrue(isEmpty);
            }
        }
    }
}

✅ 优势:openStream()流式处理避免内存溢出,适合GB级文件处理。

5. 结论

三个库都能有效检测Excel空行,各有特点:

库名 优势 适用场景
Apache POI 功能全面,格式支持最全 复杂Excel操作
JExcel 轻量简单 遗留*.xls*文件处理
fastexcel 高性能,内存占用低 超大型Excel文件读写

选择建议:

  • 需要操作*.xls*格式 → JExcel
  • 处理GB级数据 → fastexcel
  • 复杂Excel操作 → Apache POI

完整代码示例见GitHub仓库


原始标题:Determining Empty Row in an Excel File With Java | Baeldung