Поиск последней строки в электронной таблице Excel
Я пытаюсь найти индекс последней строки в таблице Excel с использованием Apache POI для Java.
Я думал, что это возможно с помощью getLastRowNum()
или getPhysicalNumberOfRows()
, но они, похоже, не дают правильных результатов. Например, у меня есть таблица с одной строкой, и эти две функции возвращают значение 1140. Еще две строки электронных таблиц получают значение 1162.
Другая проблема заключается в том, что я не могу просто искать первую пустую строку, так как может быть возможно иметь пустые строки между строками действительных данных.
Итак, есть способ найти индекс последней строки? Я полагаю, что я мог бы сделать это требование не иметь пустых строк между данными, но я надеялся на лучшее решение.
Изменить: запись с использованием итератора не помогла. Он просто повторялся над предполагаемыми рядами 1140/1162.
Ответы
Ответ 1
Я получаю ожидаемый вывод с использованием 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
Ответ 2
вы можете использовать следующий метод для получения исходного количества строк.
HSSFSheet worksheet = workbook.getSheet("Role_Mapping");
int rowsNum = worksheet.getPhysicalNumberOfRows();
Ответ 3
Я знаю, как решить вашу проблему с помощью VBA, но я не уверен, как получить эквивалентную информацию из интерфейса Apache POI. В VBA, чтобы получить диапазон используемых ячеек на листе "Sheet1", используйте:
Worksheets("Sheet1").UsedRange
Возвращает объект Range
, который имеет свойства, которые предоставляют дополнительную информацию. Например, чтобы получить количество строк в этом Range
, используйте:
Worksheets("Sheet1").UsedRange.Rows
Опять же, я не уверен, доступно ли это через API POI, но если нет, возможно, он обеспечивает способ выполнения произвольных фрагментов VBA?
Ответ 4
Единственный способ узнать наверняка - проверить строки. Здесь решение, которое я использую для той же проблемы:
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;
}
}
}
Примечание: это не проверяет, что строки, которые кажутся пустыми, но не являются такими, как ячейки, в которых есть пустая строка. Для этого вам нужно более полное решение, например:
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 - i.e. 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 column index
* @return the cell 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;
}
Ответ 5
Вы можете сделать это по следующему коду:
SVTableModel model = new SVTableModel(sheet);
lastRowNum = model.getRowCount();
Однако я пытаюсь сделать это в Apache POI 3.7, но не смог найти SVTableModel
в API. Это было удалено с 3,2, я думаю.
Ответ 6
У меня была такая же проблема раньше. Это может быть вызвано ячейками Excel, которые были отредактированы, а затем очищены в Excel. После того, как они были затронуты, они появляются как использованные клетки.
Я использую этот трюк, чтобы удалить (а не просто очистить) эти ячейки и получить правильное возвращаемое значение строки:
- Откройте файл Excel и перейдите на ожидаемый лист.
- Выберите последнюю строку + 1. Например, у вас есть 12 строк с данными, затем нажмите на строку 13.
- Выделите всю строку [Shift] - [Space]
- Выделите все строки в нижней части листа [Ctrl] - [Shift] - [Arrow down]
- Удалить все выделенные строки [Ctrl] - [Minus]
- Сохраните свою книгу
- Повторите код и проверьте возвращаемое значение.
Это не проблема библиотеки POI.
Ответ 7
int total = sheet.getPhysicalNumberOfRows() - sheet.getLastRowNum();