/// <summary> /// Generic extension method yielding objects of specified type from table. /// </summary> /// <remarks> /// Only primitives and enums are supported as property. /// Currently supports only tables with header. /// </remarks> /// <typeparam name="T">Type to map to. Type should be a class and should have parameter-less constructor.</typeparam> /// <param name="table">Table object to fetch</param> /// <param name="configurationAction"></param> /// <returns>An enumerable of the generating type</returns> public static IEnumerable <T> AsEnumerable <T>(this ExcelTable table, Action <ExcelReadConfiguration <T> > configurationAction = null) where T : new() { ExcelReadConfiguration <T> configuration = ExcelReadConfiguration <T> .Instance; configurationAction?.Invoke(configuration); if (table.IsEmpty(configuration.HasHeaderRow)) { yield break; } List <ExcelTableColumnDetails> mapping = PrepareMappings(table, configuration).Where(x => x.ColumnPosition >= 0).ToList(); ExcelAddress bounds = table.GetDataBounds(); // Parse table for (int row = bounds.Start.Row; row <= bounds.End.Row; row++) { var item = new T(); foreach (ExcelTableColumnDetails map in mapping) { var exists = table.WorkSheet.Cells[row, map.ColumnPosition + table.Address.Start.Column]; object cell = exists.Value; PropertyInfo property = map.PropertyInfo; try { TrySetProperty(item, property, cell); } catch (Exception ex) { var exceptionArgs = new ExcelExceptionArgs { ColumnName = table.Columns[map.ColumnPosition].Name, ExpectedType = property.PropertyType, PropertyName = property.Name, CellValue = cell, CellAddress = new ExcelCellAddress(row, map.ColumnPosition + table.Address.Start.Column) }; if (configuration.ThrowValidationExceptions && ex is ValidationException) { throw new ExcelValidationException(ex.Message, ex) .WithArguments(exceptionArgs); } if (configuration.ThrowCastingExceptions) { throw new ExcelException(string.Format(configuration.CastingExceptionMessage, exceptionArgs.ColumnName, exceptionArgs.CellAddress.Address, exceptionArgs.CellValue, exceptionArgs.ExpectedType.Name), ex) .WithArguments(exceptionArgs); } } } configuration.OnCaught?.Invoke(item, row); yield return(item); } }
/// <summary> /// Generic extension method yielding objects of specified type from table. /// </summary> /// <remarks> /// Only primitives and enums are supported as property. /// Currently supports only tables with header. /// </remarks> /// <typeparam name="T">Type to map to. Type should be a class and should have parameterless constructor.</typeparam> /// <param name="table">Table object to fetch</param> /// <param name="configurationAction"></param> /// <returns>An enumerable of the generating type</returns> public static IEnumerable <T> AsEnumerable <T>(this ExcelTable table, Action <ExcelReadConfiguration <T> > configurationAction = null) where T : class, new() { ExcelReadConfiguration <T> configuration = DefaultExcelReadConfiguration <T> .Instance; configurationAction?.Invoke(configuration); if (!table.IsEmpty(configuration.HasHeaderRow)) { List <KeyValuePair <int, PropertyInfo> > mapping = PrepareMappings(table, configuration).ToList(); ExcelAddress bounds = table.GetDataBounds(); // Parse table for (int row = bounds.Start.Row; row <= bounds.End.Row; row++) { var item = (T)Activator.CreateInstance(typeof(T)); foreach (KeyValuePair <int, PropertyInfo> map in mapping) { object cell = table.WorkSheet.Cells[row, map.Key + table.Address.Start.Column].Value; PropertyInfo property = map.Value; try { TrySetProperty(item, property, cell); } catch (Exception ex) { var exceptionArgs = new ExcelExceptionArgs { ColumnName = table.Columns[map.Key].Name, ExpectedType = property.PropertyType, PropertyName = property.Name, CellValue = cell, CellAddress = new ExcelCellAddress(row, map.Key + table.Address.Start.Column) }; if (configuration.ThrowValidationExceptions && ex is ValidationException) { throw new ExcelValidationException(ex.Message, ex) .WithArguments(exceptionArgs); } if (configuration.ThrowCastingExceptions) { throw new ExcelException(string.Format(configuration.CastingExceptionMessage, exceptionArgs.ColumnName, exceptionArgs.CellAddress.Address, exceptionArgs.CellValue, exceptionArgs.ExpectedType.Name), ex) .WithArguments(exceptionArgs); } } } configuration.OnCaught?.Invoke(item, row); yield return(item); } } }