1. 概述

在这个教程中,我们将讨论如何使用Java和Apache POI在Excel电子表格中找到最后一行。

首先,我们将了解如何使用Apache POI从文件中获取单行数据。接着,我们会探讨计算工作表中所有行数的方法。最后,我们将结合这些方法来获取给定工作表的最后一行。

2. 获取单行数据

我们已知,Apache POI为Java提供了与Microsoft文档(包括Excel)交互的抽象层。我们可以访问文件中的工作表,并读取和修改每个单元格。

让我们首先从Excel文件中获取一行数据。在继续之前,我们需要获取Worksheet

Workbook workbook = new XSSFWorkbook(fileLocation);
Sheet sheet = workbook.getSheetAt(0);

Workbook是Excel文件的Java表示,而SheetWorkbook内的主要结构,WorksheetSheet最常见的子类型,代表一个由单元格组成的网格。

当我们用Java打开工作表时,可以访问其中包含的数据,即行数据。要获取单行,我们可以使用getRow(int)方法:

Row row = sheet.getRow(2);

这个方法返回Row对象,它是Excel文件中单行的高层表示,如果不存在则返回null。

如你所见,我们需要提供一个参数,即请求行的索引(从0开始)。不幸的是,没有直接的API可以直接获取最后一行。

3. 计算行数

我们已经学会了如何使用Java从Excel文件中获取单行数据。现在,让我们找到给定Sheet的最后一行的索引。

Apache POI提供了两种帮助计数行的方法:*getLastRowNum()getPhysicalNumberOfRows()*。让我们逐一查看它们。

3.1. 使用getLastRowNum()

根据文档,getLastRowNum()方法返回工作表上最后一个初始化行的数字(从0开始),如果没有行存在,则返回-1:

int lastRowNum = sheet.getLastRowNum();

一旦我们获取了lastRowNum,就可以使用*getRow()*方法轻松访问最后一行。

需要注意的是,那些之前有内容后来被设置为空的行仍然会被计算在内。因此,结果可能不如预期。为了理解这一点,我们需要更多地了解物理行。

3.2. 使用getPhysicalNumberOfRows()

查阅Apache POI文档,我们可以发现与行相关的一个特殊术语——物理行。

当行中包含任何数据时,它总是被视为物理的。行不仅会在行中的任何单元格包含文本或公式时初始化,而且还会在它们有关于格式化的信息时初始化,例如背景颜色、行高或非默认字体。换句话说,每个初始化的行也是物理行

要获取物理行的数量,Apache POI提供了getPhysicalNumberOfRows()方法:

int physicalRows = sheet.getPhysicalNumberOfRows();

根据物理行的解释,结果可能会与使用*getLastRowNum()*方法得到的结果不同。

4. 获取最后一行

现在,让我们在一个更复杂的Excel网格上测试这两种方法:

baeldung lastrow

在这个例子中,前几行包含文本数据、由公式(=A1)计算出的值,以及相应改变的背景颜色。然后,第4行修改了高度,而第5和6行未改动。第7行再次包含文本。第8行的文本先前进行了格式化,但后来清除了。第9行及以后未被编辑。

让我们检查计数方法的结果:

assertEquals(7, sheet.getLastRowNum());
assertEquals(6, sheet.getPhysicalNumberOfRows());

正如我们之前所说,最后一行号和物理行数在某些情况下是不同的

现在,让我们基于索引获取行:

assertNotNull(sheet.getRow(0)); // data
assertNotNull(sheet.getRow(1)); // formula
assertNotNull(sheet.getRow(2)); // green
assertNotNull(sheet.getRow(3)); // height
assertNull(sheet.getRow(4));
assertNull(sheet.getRow(5));
assertNotNull(sheet.getRow(6)); // last?
assertNotNull(sheet.getRow(7)); // cleared later
assertNull(sheet.getRow(8));
...

我们可以看到,getPhysicalNumberOfRows()返回工作表中不为null(即初始化)的Rows总数。而getLastRowNum()的值是最后一个不为null的Row的索引**。

因此,我们可以获取工作表上的最后一行:

Row lastRow = null;
int lastRowNum = sheet.getLastRowNum();
if (lastRowNum >= 0) {
    lastRow = sheet.getRow(lastRowNum);
}

然而,我们必须记住,Apache POI返回的最后一行并不总是显示文本或公式的那一行,尤其是在像Microsoft Excel这样的UI编辑器中。

5. 总结

在这篇文章中,我们研究了Apache POI API,并从给定的Excel文件中获取了最后一行。

我们首先复习了一些基本方法,以在Java中打开电子表格。然后,我们介绍了getRow(int)方法来检索一个Row。接着,我们比较了*getLastRowNum()getPhysicalNumberOfRows()*的值,并解释了它们的区别。最后,我们在Excel网格上检验了所有方法以获取最后一行。

如往常一样,完整的代码版本可在GitHub上找到。