2009-09-22 10 views
5

Cuando la primera celda de una hoja de Excel para importar utilizando ExcelStorage.ExtractRecords está vacía, el proceso falla. Es decir. Si los datos comienzan en la columna 1, fila 2, si la celda (2,1) tiene un valor vacío, el método falla.Filehelpers ExcelStorage.ExtractRecords falla cuando la primera celda está vacía

¿Alguien sabe cómo solucionarlo? Intenté agregar un atributo FieldNullValue a la clase de mapeo sin suerte.

Here es un proyecto de ejemplo que muestra el código con problemas

la esperanza que alguien me puede ayudar o punto en alguna dirección.

¡Gracias!

+0

No he usado esto realmente, solo miré la biblioteca hace algún tiempo: ¿Puede el atributo FieldOptional ayudar? –

Respuesta

4

Parece que ha encontrado un problema en FileHelpers.

Lo que está sucediendo es que el método ExcelStorage.ExtractRecords utiliza una comprobación de celda vacía para ver si ha llegado al final de la hoja. Esto se puede ver en el código fuente ExcelStorage.cs:

while (CellAsString(cRow, mStartColumn) != String.Empty) 
{ 
    try 
    { 
     recordNumber++; 
     Notify(mNotifyHandler, mProgressMode, recordNumber, -1); 

     colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

     object record = ValuesToRecord(colValues); 
     res.Add(record); 

    } 
    catch (Exception ex) 
    { 
     // Code removed for this example 
    } 
} 


lo tanto, si la columna de inicio de cualquier fila está vacía, entonces se supone que el archivo está hecho.

Algunas opciones de evitar esto:

  1. No ponga las celdas vacías en la primera posición de la columna.
  2. No utilice excel como formato de archivo: primero conviértalo en CSV.
  3. Vea si puede obtener un parche del desarrollador o parchear la fuente usted mismo.

Las dos primeras son soluciones (y no muy buenas). La tercera opción podría ser la mejor, pero ¿cuál es el final de la condición del archivo? Probablemente una fila entera que esté vacía sería una verificación suficientemente buena (pero incluso eso podría no funcionar en todos los casos todo el tiempo).

+0

¡Gracias a Tuzo! Trataré de arreglarlo, me diste información útil. – Sebastian

4

Gracias a la ayuda de Tuzo, pude encontrar una forma de solucionar esto. Agregué un método a la clase ExcelStorage para cambiar la condición while end. En lugar de mirar la primera celda para ver el valor vacío, veo que todas las celdas de la fila actual están vacías. Si ese es el caso, devuelve falso por el momento. Este es el cambio a la parte rato de ExtractRecords:

while (!IsEof(cRow, mStartColumn, RecordFieldCount)) 

en lugar de

while (CellAsString(cRow, mStartColumn) != String.Empty) 

IsEOF es un método para comprobar toda la fila que está vacío:

private bool IsEof(int row, int startCol, int numberOfCols) 
    { 
     bool isEmpty = true; 
     string cellValue = string.Empty; 

     for (int i = startCol; i <= numberOfCols; i++) 
     { 
      cellValue = CellAsString(row, i); 
      if (cellValue != string.Empty) 
      { 
       isEmpty = false; 
       break; 
      } 
     } 

     return isEmpty; 
    } 

Por supuesto, si el usuario deja una fila vacía entre dos filas de datos, las filas posteriores a esa no se procesarán, pero creo que es bueno seguir trabajando en esto.

Gracias

+1

Gracias, he llevado su código un paso más allá. Necesitaba poder omitir las líneas en blanco –

+0

Esto se ha agregado desde entonces al recurso FileHelpers en Github. También he asignado otro cambio a FileHelpers ExcelStorage: "permitir que las hojas de Excel contengan una o más filas vacías sin que el Reader se detenga en esas filas hasta que se exceda un máximo (ExcelReadStopAfterEmptyRows)" see: https://github.com/MarcosMeli/ FileHelpers/pull/4 – rohancragg

3

que necesitaba ser capaz de saltar líneas en blanco, por lo que hemos añadido el siguiente código a la biblioteca FileHelpers.Me he tomado Sebastian 's IsEof código y cambió el nombre del método para IsRowEmpty y cambió el bucle en ExtractRecords de ...

while (CellAsString(cRow, mStartColumn) != String.Empty) 

a ...

while (!IsRowEmpty(cRow, mStartColumn, RecordFieldCount) || !IsRowEmpty(cRow+1, mStartColumn, RecordFieldCount)) 

que luego cambió esta ...

colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

object record = ValuesToRecord(colValues); 
res.Add(record); 

a este ...

bool addRow = true; 

if (Attribute.GetCustomAttribute(RecordType, typeof(IgnoreEmptyLinesAttribute)) != null && IsRowEmpty(cRow, mStartColumn, RecordFieldCount)) 
{ 
    addRow = false; 
} 

if (addRow) 
{ 
    colValues = RowValues(cRow, mStartColumn, RecordFieldCount); 

    object record = ValuesToRecord(colValues); 
    res.Add(record); 
} 

Lo que esto me da es la capacidad de omitir filas vacías. El archivo se leerá hasta que se encuentren dos filas vacías sucesivas

Cuestiones relacionadas