2009-12-02 72 views
23

Estoy utilizando la biblioteca de Apache POi HSSF para importar información en mi aplicación. El problema es que los archivos tienen algunas filas adicionales/vacías que deben eliminarse primero antes de analizar.Eliminar una fila de una hoja de Excel con POI de Apache HSSF

No hay un método HSSFSheet.removeRow(int rowNum). Solo removeRow(HSSFRow row). El problema con esto es que las filas vacías no se pueden eliminar. Por ejemplo:

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

da una NullPointerException en las filas vacías porque getRow() devuelve null. Además, mientras leo en los foros, removeRow() solo borra el contenido de la celda, pero la fila todavía está allí como una fila vacía.

¿Hay alguna manera de eliminar filas (vacías o no) sin crear una hoja nueva sin las filas que quiero eliminar?

Respuesta

0

Estoy tratando de volver a las profundidades de mi cerebro para mi experiencia relacionada con PDI de hace un año o dos, pero mi primera pregunta sería: ¿por qué las filas deben eliminarse antes de analizar? ¿Por qué no solo captura el resultado nulo de la llamada sheet.getRow(rowNum) y continúa?

+0

Debido a que ya he hecho un programa de análisis de archivos de Excel con formato de una tabla simple (nombres de columna en la primera fila y datos más abajo) y tengo que advertir al usuario si hay filas vacías. Además, los archivos que quiero importar ahora son de otra aplicación y tienen muchas filas adicionales (vacías o no) solo para que el archivo se vea mejor. – fmaste

+0

OK - Sin embargo, solo diría que probablemente te servirán solo para subclasificar tu analizador existente y dejar que tu subclase ignore las filas vacías en lugar de hacer algo con ellas; De esta manera, los archivos de la otra aplicación todavía se ven bien y no tienes que morir en esos archivos. :) – delfuego

+0

Sí. También pienso en eso. Pero el archivo tiene cosas como: una fila solo para la primera columna (la identificación) y el resto de las columnas en la fila siguiente. Solo porque se ve mejor. Necesito hacer una sola fila y eliminar una. Creo que haría una clase que contiene una hoja y una lista de índices de fila y borro los índices cuando elimino una fila. Es demasiado, pero necesito eliminar la fila, ¡no entiendo por qué no puedes eliminar la fila con esta biblioteca! – fmaste

3

El HSSFRow tiene un método llamado setRowNum(int rowIndex).

Cuando tiene que "eliminar" una fila, coloca ese índice en List. Luego, cuando llegue a la siguiente fila no vacía, tome un índice de esa lista y configúrelo llamando al setRowNum(), y elimine el índice de esa lista. (O puede utilizar una cola)

2

Algo a lo largo de las líneas de

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

debe hacer el truco.

24
/** 
* 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); 
     } 
    } 
} 
+1

esta solución no funciona en el caso de la eliminación de varias filas. – gospodin

+0

@gospodin: ejecute el código interno en un bucle y no olvide disminuir el contador rowIndex en 1 cada vez que elimine una fila. – Avik

+1

Actualmente hay un error en el POI que lanzará> org.apache.xmlbeans.impl.values.XmlValueDisconnectedException beermann

6

Lo sé, esta es una pregunta de 3 años, pero tuve que resolver el mismo problema recientemente, y tuve que hacerlo en C#. Y aquí es la función que estoy usando con 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); 
     } 
    } 
1

Mi caso especial (que trabajó para mí):

//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

Esta respuesta es una extensión sobre la respuesta de AndreAY, Dándole completar la función al eliminar una fila.

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; 
} 
Cuestiones relacionadas