2011-02-08 53 views
34

Tengo un archivo de Excel enorme con toneladas de columnas que se parece a esto: -¿Cómo obtener un valor de celda en blanco de Excel en Apache POI?

Column1 Column2 Column3 Column4 Column5 
abc    def    ghi 
     mno    pqr 
...... 

Este es el código que escribí para imprimir estos valores:

try { 
    FileInputStream inputStr = new FileInputStream(fileName); 
    XSSFWorkbook xssfWork = new XSSFWorkbook(inputStr) ; 
    XSSFSheet sheet1 = xssfWork.getSheetAt(0); 
    Iterator rowItr = sheet1.rowIterator(); 

    while (rowItr.hasNext()) { 
     XSSFRow row = (XSSFRow) rowItr.next(); 
     System.out.println("ROW:-->"); 
     Iterator cellItr = row.cellIterator(); 

     while (cellItr.hasNext()) { 
      XSSFCell cell = (XSSFCell) cellItr.next(); 
      System.out.println("CELL:-->"+cell.toString()); 
     } 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

La salida generada por este código es: -

ROW:--> 
CELL:-->Column1 
CELL:-->Column2 
CELL:-->Column3 
CELL:-->Column4 
CELL:-->Column5 
ROW:--> 
CELL:-->abc 
CELL:-->def 
CELL:-->ghi 
ROW:--> 
CELL:-->mno 
CELL:-->pqr 

lo tanto, si nos fijamos en la salida anterior podemos observar que las células donde deje los valores en blanco no fue recogido por la biblioteca de puntos de interés, ¿hay una forma en que puedo obtener estos valores como nulos. o una forma de reconocer que los valores presentados saltaron las celdas en blanco?

Gracias.

Respuesta

1
 for(org.apache.poi.ss.usermodel.Row tmp : hssfSheet){ 
      for(int i = 0; i<8;i++){ 
       System.out.println(tmp.getCell(i)); 
      }    
     } 
+0

él está utilizando XSSF para abrir un archivo XLSX (2007+). HSSF no resolverá su problema. –

9

Me he sentido frustrado por este mismo problema. Esto es lo que encontré con poi-3.7-20101029 y poi-3.8.

RowIterator y CellIterator no son compatibles con la iteración sobre celdas o filas NULL: solo celdas definidas físicamente (que pueden estar en BLANCO).

La solución que devuelve lo que espero requiere el 0-basado en Row.getCell([int], Row.CREATE_NULL_AS_BLANK), al igual que la respuesta de Chavira alude (suponiendo 8 filas de celdas). O puede usar el valor Cell.columnIndex mientras itera para verificar si saltan números ...

Es irritante que, después de crear celdas en blanco utilizando el método n. ° 1, los iteradores devuelvan las células BLANK ahora creadas. Considero que es un error que CellIterator ignora a MissingCellPolicy.

+1

Se metió en el mismo problema y utilizando el enfoque de índice basado en 0 (no a través del foreach) y el CREAT_NULL_AS_BLANK MissingRowPolicy funcionó para mí. – fimez

+1

Excelente. Puede confirmar que esto también funciona en POI 3.8. – javatestcase

51

Si desea obtener todas las células, sin importar si existe o no, entonces el iterador no es para ti. En su lugar, tendrá que obtener manualmente las células apropiadas, probablemente con una política de células que falta

for(Row row : sheet) { 
    for(int cn=0; cn<row.getLastCellNum(); cn++) { 
     // If the cell is missing from the file, generate a blank one 
     // (Works by specifying a MissingCellPolicy) 
     Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK); 
     // Print the cell for debugging 
     System.out.println("CELL: " + cn + " --> " + cell.toString()); 
    } 
} 

hay más detalles sobre todo esto en the Apache POI documentation on iterating over cells

+0

El método 'row.getCell()' está en desuso. –

+3

Realmente no lo es ... – Gagravarr

+2

Es 'row.getCell (short)' que está en desuso. Lo siento. –

3

La razón es muy sencilla: los archivos de Excel pueden contener tantas filas y tantas columnas como sea posible, por lo que devolver todas las filas y columnas disponibles hará que las celdas sean enormes y requieran mucha memoria.

Suponiendo que tiene una hoja de 10x10, en Excel, no es "exactamente" 10x10 ya que puede agregar 11x10 muy fácilmente con una celda en blanco, ¿debe devolver POI la columna 11?

Una manera de hacer lo que está solicitando es utilizar HSSFCell.getColumnIndex().

Ejemplo:

//Assuming your have a 2 dimensional array. 
String[][] values = ......;// It is assigned 

POIFSFileSystem fileSystem = new POIFSFileSystem(new FileInputStream(fileName)); 
HSSFWorkbook workbook = new HSSFWorkbook(fileSystem); 

//Going through every worksheet. 
for (int sheetPos = 0; sheetPos < workbook.getNumberOfSheets(); sheetPos++) { 
    HSSFSheet sheet = workbook.getSheetAt(sheetPos); 

    int rowPos = 0; 
    Iterator<Row> rows = sheet.rowIterator(); 
    while (rows.hasNext()) { 
     HSSFRow row = (HSSFRow) rows.next(); 

     Iterator<Cell> cells = row.cellIterator(); 
     while (cells.hasNext()) { 
      HSSFCell cell = (HSSFCell) cells.next(); 
      String value = ""; 

      switch (cell.getCellType()) { 
       case HSSFCell.CELL_TYPE_NUMERIC: 
        value = BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString(); 
        break; 

       case HSSFCell.CELL_TYPE_STRING: 
        value = cell.getStringCellValue(); 
        break; 

       case HSSFCell.CELL_TYPE_BLANK: 
        value = ""; 
        break; 

       case HSSFCell.CELL_TYPE_FORMULA: 
        value = cell.getCellFormula(); 
        break; 

       default: 
        break; 
      } 

      values[rowPos][cell.getColumnIndex()] = value; 
     } 

     rowPos++; 
    } 
} 
+0

Row.getCell (int) ** no está en desuso **! No tengo idea de por qué piensas eso, pero puedo asegurarte que no es así - ver [JavaDocs] (http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Row.html# getCell (int)) para la prueba. – Gagravarr

+0

@Gagravarr, lo siento, es 'Row.getCell (short)' que está en desuso. –

0

Esto funcionó para mí ....

int rowNumber; 
int previousCell; 
int currentCell; 
int currentRowNumber; 
HSSFCell cell; 

while (rows.hasNext()) { 
    previousCell = -1; 
    currentCell = 0; 
    while (cellIterator.hasNext()) { 
     cell = (HSSFCell) cellIterator.next(); 
     currentCell = cell.getColumnIndex(); 
     if (previousCell == currentCell-1) { 
      //... 
     } 
     else { 
      System.out.println("Blank cell found"); 
     } 
     previousCell = currentCell; 
    } 
} 
1

continuación es lo que funcionó para mí. El "row.CREATE_NULL_AS_BLANK" no parece ser válido, pero podría ser una falta de conocimiento de NPOI.

HSSFCell dataCell= (HSSFCell)row.GetCell(column, NPOI.SS.UserModel.MissingCellPolicy.CREATE_NULL_AS_BLANK); 
+3

NPOI? Si está utilizando un puerto .NET de PDI, cualquier número de cosas podría ser diferente;) – Leigh

0
List cellDataList = new ArrayList(); 

int lineNumber = 0; 

while (rowIterator.hasNext()) { 
    HSSFRow hssfRow = (HSSFRow) rowIterator.next(); 
    //System.out.println("Befor If"); 
    lineNumber++; 
    if(lineNumber==1){continue;} 
    //System.out.println("Out side if "); 

    Iterator<Cell> iterator = hssfRow.cellIterator(); 
    List<Cell> cellTempList = new ArrayList(); 
    int current = 0, next = 1; 
    while (iterator.hasNext()) { 
     Cell hssfCell = iterator.next(); 
     current = hssfCell.getColumnIndex(); 

     if(current<next){ 
      System.out.println("Condition Satisfied"); 
     } 
     else{ 
      int loop = current-next; 
      System.out.println("inside else Loop value : "+(loop)); 
      for(int k=0;k<loop+1;k++){ 
      System.out.println("Adding nulls"); 
      cellTempList.add(null); 
      next = next + 1; 
      } 
     } 

     cellTempList.add(hssfCell); 

     next = next + 1; 
     System.out.println("At End next value is : "+next); 
    } 
    cellDataList.add(cellTempList); 
} 
0
public String[] rowToString(Row row) 
{ 
    Iterator<Cell> cells = row.cellIterator() ; 
    String[] data = new String[row.getLastCellNum()] ; 

    int previousCell = 0 ; 

    Cell cell = cells.next() ; 
    int currentCell = cell.getColumnIndex(); 

    while (true) 
    { 
     if (previousCell == currentCell) { 
      switch (cell.getCellType()) { 
       case Cell.CELL_TYPE_NUMERIC: 
        data[previousCell] = cell.getNumericCellValue()+"" ; 
        break; 
       case Cell.CELL_TYPE_STRING: 
        data[previousCell] = cell.getStringCellValue() ; 
        break; 
        /* // there could be other cases here. 
        case Cell.CELL_TYPE_FORMULA: 
         data[previousCell] =eval.evaluateFormulaCell(cell); 
         break; 
        case Cell.CELL_TYPE_BOOLEAN: 
         data[previousCell] = cell.getBooleanCellValue(); 
         break; 
        case Cell.CELL_TYPE_BLANK: 
         data[previousCell] = ""; 
         break; 
        case Cell.CELL_TYPE_ERROR: 
         data[previousCell] = "ERROR"; 
         break; 
        */ 
      } 
      if(cells.hasNext()){ 
       cell = cells.next() ; 
       currentCell = cell.getColumnIndex(); 
      } else { 
       break ; 
      } 

     } else { 
      data[previousCell] = ""; 
     } 
     previousCell++ ; 

    } 

    return data ; 

} 
+0

favor, añadir comentarios a su respuesta – dlavila

+1

se debe añadir los comentarios y explicaciones en el puesto no por debajo, también, por favor mire el año de la pregunta – dlavila

+0

Este método transforma una fila de Excel en una matriz de cadenas, sin omitir los valores de celda en blanco o vacíos (el valor de matriz correspondiente tendrá solo una cadena vacía en este caso). – Albe

Cuestiones relacionadas