sheet.GetRow(RowIndex) возвращает нулевой POI APACHE

#java #excel #apache-poi

Вопрос:

Я использую библиотеку POI APACHE для чтения файла excel в формате xlsx.

Моя проблема в том, что я хочу удалить последнюю строку с каждого листа этого excel, я нашел способ найти последнюю строку для удаления, но она возвращает значение int. Метод sheet.removeRow(строка var1); решил бы мою проблему.

Ну, имея номер строки, которую я хочу удалить, и способ удаления этой строки. Мне просто нужно преобразовать lastRow (int) в тип строки, чтобы я мог использовать метод sheet.removeRow.

Для этого я использовал следующий код: Строка a = sheet.GetRow(lastRow) этот метод должен возвращать строку с этим индексом. Но вместо этого он возвращает значение NULL.

Есть идеи, что я делаю не так или как преобразовать номер строки, который я хочу удалить, в тип строки?

Ценю вашу помощь!

Вот выдержка из кода, который читает мой файл excel

     public static List<Measure> excelToMeasures(InputStream is, ProjectMeasureFile projectMeasureFile) throws IOException {

    List<Measure> measures = new ArrayList<>();

    try (Workbook workbook = new XSSFWorkbook(is)) {

        for (int i = 0; i < 3; i  ) {
            Sheet sheet = workbook.getSheetAt(i);

            int lastRow = sheet.getPhysicalNumberOfRows() -1;

            removeRow(sheet, lastRow);

            int rowNumber = 0;
            for (Row row : sheet) {

                // skip header
                if (rowNumber == 0) {
                    rowNumber  ;
                    continue;
                }

                Iterator<Cell> cellIterator = row.iterator();
                List<Cell> cellObject = new ArrayList<>();

                while (cellIterator.hasNext()) {
                    cellObject.add(cellIterator.next());
                }

                if (cellObject.size() > 0) {
                    Measure measure = new Measure();
                    measure.setArea(sheet.getSheetName());
                    measure.setCode(convertStringCell(cellObject.get(0)));
                    measure.setBehavior(convertStringCell(cellObject.get(1)));

                    measure.setHumanDependencyFactor(convertNumericCell(cellObject.get(2)));
                    Double measureType = convertToPercentage(measure.getHumanDependencyFactor());
                    measure.setHumanDependencyFactor(measureType);

                    measure.setMeasurementResults(convertNumericCell(cellObject.get(3)));
                    Double value = convertToPercentage(measure.getMeasurementResults());
                    measure.setMeasurementResults(value);

                    measure.setProjectMeasureFile(projectMeasureFile);
                    measures.add(measure);
                }

                rowNumber  ;
            }
        }

    } catch (Exception e) {
        log.error("An error occurred when trying to parse the file.");
        e.printStackTrace();
    }

    return measures;
}
 

А вот способ удаления строки:

   public static void removeRow(Sheet sheet, int rowIndex) {
    int lastRowNum = sheet.getPhysicalNumberOfRows() -1;

    if (rowIndex == lastRowNum) {
        Row removingRow = sheet.getRow(rowIndex);
        sheet.getRow(rowIndex);
        Row a = sheet.getRow(rowIndex);
        if (removingRow != null) {

           
            System.out.println(sheet.getRow(lastRowNum).getCell(0).toString());
           
            sheet.removeRow(removingRow); 
        }
    }
}
 

Ответ №1:

Сначала к названию вашего вопроса: Sheet.getRow вернется NULL по дизайну. Он возвращается NULL , если строка за индексом строки не хранится в листе. Поэтому вам всегда нужно проверять NULL , что будет после Sheet.getRow . То же Row.getCell самое относится и к тому, что возвращает NULL по дизайну для ячеек, которые не хранятся в строке.

И Sheet.getPhysicalNumberOfRows это неправильный способ получить последнюю строку на листе.

Excel Лист физически содержит только строки, в которых сохранены ячейки. Строки, которые полностью пусты, физически не сохраняются. Таким образом, если лист содержит данные только в строках 1, 2, 5, 6 и 7, то Sheet.getPhysicalNumberOfRows будет возвращено 5, но последняя строка равна 7.

Там Sheet.getLastRowNum нужно получить номер последней строки (на основе 0) в листе. Так что это вернет 6 в приведенном выше примере и sheet.getRow(6) получит последнюю строку, а не NULL .

Но есть еще одна проблема, которую следует рассмотреть. В Excel строках может быть не совсем пусто, а только пустые ячейки. Пустые ячейки могут храниться, потому что у них есть форматы ячеек или у них было содержимое раньше. Sheet.getLastRowNum возвращает последнюю сохраненную строку, даже если эта строка содержит только пустые ячейки. Поэтому вам нужно проверить, содержит ли строка позади Sheet.getLastRowNum только пустые ячейки, выполнив итерацию по ячейкам и проверив CellType.BLANK , нужна ли вам последняя заполненная строка.

Следующий метод возвращает последнюю заполненную строку на листе. Он возвращается NULL , если заполненная строка не найдена.

  Row getLastFilledRow(Sheet sheet) {
  int lastStoredRowNum = sheet.getLastRowNum();
  for (int r = lastStoredRowNum; r >= 0; r--) {
   Row row = sheet.getRow(r);
   if (row != null) {
    for (Cell cell : row) {
     if (cell.getCellType() != CellType.BLANK) return row;  
    }
   }       
  }
  return null;  
 }