Leer un excel usando la librería NPOI

El fragmento de código C# de este sencillo tutorial, muestra cómo utilizar la biblioteca NPOI de código abierto para leer los valores de las celdas en archivos de Microsoft Excel. Las celdas de Excel pueden contener valores de diferentes tipos. Además, los valores pueden ser evaluados a partir de fórmulas. Tenemos que atender estos casos, cuando desempeñamos la lectura de los valores de las celdas. ¿Estás dispuesto a parsear archivos excel con la librería NPOI de C#? En este artículo te enseñamos cómo llevarlo a cabo.

Escribo una clase abstracta ExcelFileReader que nos proporciona las funciones básicas para leer los valores de un archivo de Excel.

//
// ExcelFileReader
//
public abstract class ExcelFileReader
{
    protected IWorkbook workbook;
    protected DataFormatter dataFormatter;
    protected IFormulaEvaluator formulaEvaluator;

    //
    // Inicializamos el stream del archivo excel
    //
    protected void InitializeMembers(Stream excelFileStream)
    {
        this.workbook = WorkbookFactory.Create(excelFileStream);
        if (this.workbook != null)
        {
            this.dataFormatter = new DataFormatter(CultureInfo.InvariantCulture);
            this.formulaEvaluator = WorkbookFactory.CreateFormulaEvaluator(this.workbook);
        }
    }

    //
    // Obtenemos el valor formateado como un string de la celda específica
    //
    protected string GetFormattedValue(ICell cell)
    {
        string returnValue = string.Empty;
        if (cell != null)
        {
            try
            {
                // Obtenemos el valor de la celda formateado
                returnValue = this.dataFormatter.FormatCellValue(cell, this.formulaEvaluator);
            }
            catch
            {
                if (cell.CellType == CellType.FORMULA)
                {
                    switch (cell.CachedFormulaResultType)
                    {
                        case CellType.STRING:
                            returnValue = cell.StringCellValue;
                            cell.SetCellValue(cell.StringCellValue);
                            break;
                        case CellType.NUMERIC:
                            returnValue = dataFormatter.FormatRawCellContents(cell.NumericCellValue, 0,  cell.CellStyle.GetDataFormatString())
                            cell.SetCellValue(cell.NumericCellValue);
                            break;
                        case CellType.BOOLEAN:
                            returnValue = cell.BooleanCellValue.ToString();
                            cell.SetCellValue(cell.BooleanCellValue);
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        return (returnValue ?? string.Empty).Trim();
    }

    //
    // Obtenemos el valor sin formato como un string de la celda específica
    //
    protected string GetUnformattedValue(ICell cell)
    {
        string returnValue = string.Empty;
        if (cell != null)
        {
            try
            {
                // Obtenemos el valor de la celda evaluado
                returnValue = (cell.CellType == CellType.NUMERIC || (cell.CellType == CellType.FORMULA && cell.CachedFormulaResultType == CellType.NUMERIC)) ?
                    formulaEvaluator.EvaluateInCell(cell).NumericCellValue.ToString() :
                    this.dataFormatter.FormatCellValue(cell, this.formulaEvaluator);
            }
            catch
            {
                if (cell.CellType == CellType.FORMULA)
                {
                    switch (cell.CachedFormulaResultType)
                    {
                        case CellType.STRING:
                            returnValue = cell.StringCellValue;
                            cell.SetCellValue(cell.StringCellValue);
                            break;
                        case CellType.NUMERIC:
                            returnValue = cell.NumericCellValue.ToString();
                            cell.SetCellValue(cell.NumericCellValue);
                            break;
                        case CellType.BOOLEAN:
                            returnValue = cell.BooleanCellValue.ToString();
                            cell.SetCellValue(cell.BooleanCellValue);
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        return (returnValue ?? string.Empty).Trim();
    }
}

Tienes que implementar esta clase abstracta ExcelFileReader, para que obtenga el objeto ISheet de this.workbook y así manipular su objeto IRow para obtener los valores de las celdas.

El bloque try-catch en la función GetFormattedValue() se encarga de los fallos en la evaluación de la fórmula de la celda (con referencia externa), tomando el valor almacenado en caché (si existe) en su lugar. El valor de la celda se ajusta entonces al valor almacenado en caché llamando a la función setCellValue() para cualquier fórmulas en otras celdas que referencian a la misma. Por valor numérico, los valores con formato se pueden obtener llamando a la función DataFormatter.FormatRawCellContents().

De manera similar, la función GetUnformattedValue() obtiene el valor de la celda como una cadena sin formato. En celdas numéricas, el formato se puede aplicar, para obtener el valor sin formato de la propiedad ICell.NumericCellValue.

La enum CellType no tiene ningún item como DATE para fechas/horas, por lo que son almacenadas en forma de número en Excel. Por lo tanto, no hay una manera directa de identificar la celda en caso de tener un valor de  fecha / hora. Creo que una forma de hacerlo sería comprobando su formato con la propiedad ICell.CellStyle.DataFormat o la función ICell.CellStyle.GetDataFormatString().

Espero que este tutorial haya sido de tu agrado y sepas sacarle el provecho necesario para que después sepas aplicarlo a tus futuros proyectos. Ya sabes que nos puedes proponer más temas que quieras ver convertidos en tutoriales a través de la zona de comentarios más abajo. ¡Feliz código amigos!

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
SIGUIENTE ARTÍCULO