Удаление строки из листа Excel с помощью Apache POI HSSF - PullRequest
27 голосов
/ 02 декабря 2009

Я использую библиотеку Apache POi HSSF для импорта информации в мое приложение. Проблема в том, что в файлах есть несколько лишних / пустых строк, которые нужно сначала удалить перед анализом.

Нет HSSFSheet.removeRow( int rowNum ) метода. Только removeRow( HSSFRow row ). Проблема в том, что пустые строки не могут быть удалены. Например:

sheet.removeRow( sheet.getRow(rowNum) );

дает исключение NullPointerException для пустых строк, поскольку getRow() возвращает ноль. Кроме того, как я читал на форумах, removeRow() только стирает содержимое ячейки, но строка все еще там как пустая строка.

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

Ответы [ 7 ]

27 голосов
/ 24 августа 2010
 /**
 * Remove a row by its index
 * @param sheet a Excel sheet
 * @param rowIndex a 0 based index of removing row
 */
public static void removeRow(HSSFSheet sheet, int rowIndex) {
    int lastRowNum=sheet.getLastRowNum();
    if(rowIndex>=0&&rowIndex<lastRowNum){
        sheet.shiftRows(rowIndex+1,lastRowNum, -1);
    }
    if(rowIndex==lastRowNum){
        HSSFRow removingRow=sheet.getRow(rowIndex);
        if(removingRow!=null){
            sheet.removeRow(removingRow);
        }
    }
}
8 голосов
/ 04 июля 2012

Я знаю, что это 3-летний вопрос, но мне пришлось недавно решить ту же проблему, и я должен был сделать это в C #. А вот функция, которую я использую с NPOI, .Net 4.0

    public static void DeleteRow(this ISheet sheet, IRow row)
    {
        sheet.RemoveRow(row);   // this only deletes all the cell values

        int rowIndex = row.RowNum;

        int lastRowNum = sheet.LastRowNum;

        if (rowIndex >= 0 && rowIndex < lastRowNum)
        {
            sheet.ShiftRows(rowIndex + 1, lastRowNum, -1);
        }
    }
3 голосов
/ 03 декабря 2009

Что-то вроде

int newrownum=0;
for (int i=0; i<=sheet.getLastRowNum(); i++) {
  HSSFRow row=sheet.getRow(i);
  if (row) row.setRowNum(newrownum++);
}

должен сделать трюк.

3 голосов
/ 03 декабря 2009

У HSSFRow есть метод с именем setRowNum(int rowIndex).

Когда вам нужно «удалить» строку, вы помещаете этот индекс в List. Затем, когда вы попадаете в следующую непустую строку, вы берете индекс из этого списка и устанавливаете его как setRowNum(), и удаляете индекс из этого списка. (Или вы можете использовать очередь)

1 голос
/ 16 августа 2015

Этот ответ является расширением ответа AndreAY, предоставляя вам полную функцию по удалению строки.

public boolean deleteRow(String sheetName, String excelPath, int rowNo) throws IOException {

    XSSFWorkbook workbook = null;
    XSSFSheet sheet = null;

    try {
        FileInputStream file = new FileInputStream(new File(excelPath));
        workbook = new XSSFWorkbook(file);
        sheet = workbook.getSheet(sheetName);
        if (sheet == null) {
            return false;
        }
        int lastRowNum = sheet.getLastRowNum();
        if (rowNo >= 0 && rowNo < lastRowNum) {
            sheet.shiftRows(rowNo + 1, lastRowNum, -1);
        }
        if (rowNo == lastRowNum) {
            XSSFRow removingRow=sheet.getRow(rowNo);
            if(removingRow != null) {
                sheet.removeRow(removingRow);
            }
        }
        file.close();
        FileOutputStream outFile = new FileOutputStream(new File(excelPath));
        workbook.write(outFile);
        outFile.close();


    } catch(Exception e) {
        throw e;
    } finally {
        if(workbook != null)
            workbook.close();
    }
    return false;
}
1 голос
/ 23 июля 2012

Мой особый случай (у меня сработало):

    //Various times to delete all the rows without units
    for (int j=0;j<7;j++) {
      //Follow all the rows to delete lines without units (and look for the TOTAL row)
      for (int i=1;i<sheet.getLastRowNum();i++) {
        //Starting on the 2nd row, ignoring first one
        row = sheet.getRow(i);
        cell = row.getCell(garMACode);
        if (cell != null) 
        {
          //Ignore empty rows (they have a "." on first column)
          if (cell.getStringCellValue().compareTo(".") != 0) {  
            if (cell.getStringCellValue().compareTo("TOTAL") == 0) {
              cell = row.getCell(garMAUnits+1);
              cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
              cell.setCellFormula("SUM(BB1" + ":BB" + (i - 1) + ")");
            } else {
              cell = row.getCell(garMAUnits);
              if (cell != null) {
                int valor = (int)(cell.getNumericCellValue());
                if (valor == 0 ) {
                  //sheet.removeRow(row);
                  removeRow(sheet,i);
                }
              }
            }
          }
        }
      }
    }
0 голосов
/ 02 декабря 2009

Я пытаюсь заглянуть в глубины моего мозга для моего опыта, связанного с POI, год или два назад, но мой первый вопрос будет таким: зачем удалять строки перед анализом? Почему бы вам не перехватить нулевой результат вызова sheet.getRow(rowNum) и не пойти дальше?

...