Finding the last row in an Excel spreadsheet
我正在尝试使用 Apache\\’s POI for Java 在 Excel 电子表格中查找最后一行的索引。
我认为使用 getLastRowNum() 或 getPhysicalNumberOfRows() 应该可以做到这一点,但它们似乎没有给出正确的结果。例如,我有一个单行电子表格,这两个函数返回值 1140。另外两行电子表格的值是 1162。
另一个问题是我不能只查找第一个空行,因为在有效数据行之间可能有空行。
那么有没有办法找到最后一行的索引呢?我想我可以要求数据之间没有空行,但我希望有更好的解决方案。
编辑:对于使用迭代器的记录没有帮助。它只是遍历了 1140/1162 假定的行。
- 所有 POI 的 Excel 类都称为 HSSF 是有原因的…
- use 可以使用迭代器
我使用 poi-3.6-20091214 和一个 test.xls 获得预期的输出,该输出有两个空行,后跟三个占用的行:
1
2 3 4 |
InputStream myxls = new FileInputStream(“test.xls”);
Workbook book = new HSSFWorkbook(myxls); Sheet sheet = book.getSheetAt(0); System.out.println(sheet.getLastRowNum()); |
输出:4
- 实际上,在再次检查后,我注意到我在使用的数百个左右的电子表格中得到了正确的结果。唯一的区别似乎是那些不起作用的只有一个重命名的工作表。我尝试测试一个新的工作簿,它确实给出了正确的结果。但是,我无法通过重命名工作表并删除其他工作表来重现错误,因此问题的根源仍然未知=/
- 有什么方法可以通过检查不匹配来剔除错误的书籍以供人工注意?
- 这将在正常情况下工作..但是当您在删除最后几行后运行相同 excel 的代码时将无法工作……sheet.getLastRowNum 将只给出之前的行数……
您可以使用以下方法获取原始行数。
1
2 |
HSSFSheet worksheet = workbook.getSheet(“Role_Mapping”);
int rowsNum = worksheet.getPhysicalNumberOfRows(); |
- 如果顶部有空行或散布在数据中,这将不起作用。
- 在那种情况下有什么选择?如果第一行为空
我以前也遇到过同样的问题。这可能是由于 Excel 单元格已被编辑然后在 Excel 中清空所致。一旦它们被触摸,它们就会显示为使用过的单元格。
我使用这个技巧来删除(不仅仅是清空)那些单元格,并获得正确的返回行值:
这不是 POI 库的问题。
确定的唯一方法是测试行。这是我用于相同问题的解决方案:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
int lastRowIndex = –1;
if( sheet.getPhysicalNumberOfRows() > 0 ) { // getLastRowNum() actually returns an index, not a row number lastRowIndex = sheet.getLastRowNum(); // now, start at end of spreadsheet and work our way backwards until we find a row having data |
注意:这不会检查看似为空但实际上不是空的行,例如其中包含空字符串的单元格。为此,您需要一个更完整的解决方案,例如:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
private int determineRowCount()
{ this.evaluator = workbook.getCreationHelper().createFormulaEvaluator(); this.formatter = new DataFormatter( true ); int lastRowIndex = –1; // now, start at end of spreadsheet and work our way backwards until we find a row having data /** int cellCount = row.getLastCellNum() + 1; /** |
- 这背后的想法是好的(太糟糕的 POI 让做这么简单的事情变得如此困难)。两个注释: 1. int cellCount = row.getLastCellNum() + 1; 你从 maxcellindex 1 的单元格索引开始?第二个: determineRowCount 返回最后填充行的索引,因此需要对其进行重命名,或者您必须在该数字上加 1 才能获得实际计数。
我知道如何使用 VBA 解决您的问题,但我不确定如何从 Apache POI 界面获取等效信息。在 VBA 中,要获取工作表”Sheet1″中使用的单元格范围,请使用:
1
|
Worksheets(“Sheet1”).UsedRange
|
这将返回一个 Range 对象,该对象具有提供更多信息的属性。例如,要获取此 Range 中的行数,请使用:
1
|
Worksheets(“Sheet1”).UsedRange.Rows
|
同样,我不确定这是否可以通过 POI API 访问,但如果不能,也许它提供了一种执行任意 VBA 片段的方法?
- 乍一看,我看不到任何类似于 VBA 解决方案的东西。也不太确定 VBA 的执行片段。
使用迭代器不会返回空行和未使用的行
1
2 3 4 5 6 7 8 |
Iterator<Row> itr = sheet.iterator(); //iterating over excel file
while (itr.hasNext()) |
对我来说,在任何情况下都没有任何效果,因为它适用于 HSSFWorkbook,但不适用于 XSSFWorkbook。
最后在解决方法的帮助下,我能够解决这个问题。
通过在工作表末尾合并两列或两行(在您的内容完成后)。
然后写下面的代码。
sheet.getMergedRegion(0).getLastRow()
这里 0 只是我合并的一种情况,但如果您已经合并了单元格或行,则相应地增加您的值。
希望这会有所帮助。
您可以通过以下代码做到这一点:
1
2 |
SVTableModel model = new SVTableModel(sheet);
lastRowNum = model.getRowCount(); |
但是,我试图在 Apache POI 3.7 中执行此操作,但在 API 中找不到 SVTableModel。我猜这从 3.2 开始就被删除了。
1
|
int total = sheet.getPhysicalNumberOfRows() – sheet.getLastRowNum();
|
- 该问题要求最后一行的索引。这似乎获得了第一行的索引,并且莫名其妙地将其分配给名为”total”的变量。
来源:https://www.codenong.com/2645566/