在Excel电子表格中查找最后一行

我试图使用Apache的POI for Java来查找Excel电子表格中最后一行的索引。

我认为这应该是可能的getLastRowNum()getPhysicalNumberOfRows()但他们似乎并没有给出正确的结果。 例如,我有一行电子表格,这两个函数返回值为1140.另外两行电子表格的值为1162。

另一个问题是,我不能只查找第一个空行,因为有可能在有效的数据行之间有空行。

那么有没有办法find最后一行的索引? 我想我可以要求不要在数据之间有空行,但我希望有一个更好的解决scheme。

编辑:使用迭代器logging没有帮助。 它只是遍历1140/1162假定的行。

我使用poi-3.6-20091214得到了预期的输出结果,一个test.xls有两个空行,后面跟着三个被占用的行:

 InputStream myxls = new FileInputStream("test.xls"); Workbook book = new HSSFWorkbook(myxls); Sheet sheet = book.getSheetAt(0); System.out.println(sheet.getLastRowNum()); 

输出: 4

您可以使用以下方法获取原始行数。

 HSSFSheet worksheet = workbook.getSheet("Role_Mapping"); int rowsNum = worksheet.getPhysicalNumberOfRows(); 

我知道如何使用VBA解决您的问题,但我不知道如何从Apache POI接口获取等效信息。 在VBA中,要获取工作表“Sheet1”中使用的单元格的范围,请使用:

 Worksheets("Sheet1").UsedRange 

这将返回一个Range对象,它具有提供更多信息的属性。 例如,要获取此Range的行数,请使用:

 Worksheets("Sheet1").UsedRange.Rows 

再一次,我不确定这是否可以通过POI API访问,但是如果没有,也许它提供了执行任意VBA片段的方法?

要知道的唯一方法是testing行。 以下是我用于解决相同问题的解决scheme:

 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 for( ; lastRowIndex >= 0; lastRowIndex-- ){ Row row = sheet.getRow( lastRowIndex ); if( row != null ){ break; } } } 

注意:这不检查看起来是空的但不是的行,例如其中有一个空string的单元格。 为此,您需要一个更完整的解决scheme,如:

 private int determineRowCount() { this.evaluator = workbook.getCreationHelper().createFormulaEvaluator(); this.formatter = new DataFormatter( true ); 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 for( ; lastRowIndex >= 0; lastRowIndex-- ) { Row row = sheet.getRow( lastRowIndex ); if( !isRowEmpty( row ) ) { break; } } } return lastRowIndex; } /** * Determine whether a row is effectively completely empty - ie all cells either contain an empty string or nothing. */ private boolean isRowEmpty( Row row ) { if( row == null ){ return true; } int cellCount = row.getLastCellNum() + 1; for( int i = 0; i < cellCount; i++ ){ String cellValue = getCellValue( row, i ); if( cellValue != null && cellValue.length() > 0 ){ return false; } } return true; } /** * Get the effective value of a cell, formatted according to the formatting of the cell. * If the cell contains a formula, it is evaluated first, then the result is formatted. * * @param row the row * @param columnIndex the cell's column index * @return the cell's value */ private String getCellValue( Row row, int columnIndex ) { String cellValue; Cell cell = row.getCell( columnIndex ); if( cell == null ){ // no data in this cell cellValue = null; } else{ if( cell.getCellType() != Cell.CELL_TYPE_FORMULA ){ // cell has a value, so format it into a string cellValue = this.formatter.formatCellValue( cell ); } else { // cell has a formula, so evaluate it cellValue = this.formatter.formatCellValue( cell, this.evaluator ); } } return cellValue; } 

你可以通过下面的代码来做到这一点:

 SVTableModel model = new SVTableModel(sheet); lastRowNum = model.getRowCount(); 

但是,我正在尝试在Apache POI 3.7中执行此操作,但无法在API中findSVTableModel 。 我猜,这已经从3.2版本中删除了。

我以前也有同样的问题。 我使用这个技巧来获得正确的返回行值:

  1. 打开Excel文件,并转到预期的工作表。
  2. select最后一行+1。例如,你有12行的数据,然后点击行13,然后向下滚动到2000行。请确保所有行被选中。
  3. 用鼠标点击所选行并select删除。
  4. 重新运行代码并检查返回的值。

这不是POI库的问题。

 int total = sheet.getPhysicalNumberOfRows() - sheet.getLastRowNum();