Beispiel #1
0
        private object ProcessTable(IExcelDataReader reader, TablePropertyData tablePropertyData, bool hasHeader = true)
        {
            if (!hasHeader)
            {
                throw new Exception("Tables without headers are not yet supported!");
            }

            var tableRowType = tablePropertyData.ListElementType;
            var tableRowImplementationType = tablePropertyData.ListElementTypeImplementation;

            var instanceCreator = CreateInstanceInitializationAction(tableRowType, tableRowImplementationType);
            var listAdder       = CreateAddToListAction(tableRowType);

            var propertyProcessors = new Dictionary <string, PropertySetter>();

            foreach (var property in tablePropertyData.Columns)
            {
                propertyProcessors.Add(property.ExcelColumnName, CreateSetPropertyAction(tableRowImplementationType ?? tableRowType, property.PropertyName));
            }

            var columnOffset = 0;
            var rowOffset    = 0;

            if (!string.IsNullOrEmpty(tablePropertyData.StartingCellAddress))
            {
                columnOffset = ColumnPropertyData.GetColumnIndexFromCellAddress(tablePropertyData.StartingCellAddress) - 1;
                rowOffset    = ColumnPropertyData.GetRowIndexFromCellAddress(tablePropertyData.StartingCellAddress) - 1;
            }

            // reading header
            if (hasHeader)
            {
                for (int i = 0; i <= rowOffset; i++)
                {
                    reader.Read();
                }
            }

            var totalFieldCount = reader.FieldCount;
            var columns         = new List <ExcelColumn>();

            for (int i = columnOffset; i < totalFieldCount; i++)
            {
                var columnName   = reader.GetValue(i)?.ToString();
                var propertyData = tablePropertyData.Columns.FirstOrDefault(m => m.ExcelColumnName == columnName);

                if (!string.IsNullOrEmpty(columnName) && propertyData != null)
                {
                    columns.Add(new ExcelColumn {
                        ColumnIndex = i, ColumnName = columnName, IsMandatory = propertyData.IsMandatory, PropertyName = propertyData.PropertyName
                    });
                }

                if (columns.Count >= tablePropertyData.Columns.Count)
                {
                    break;
                }
            }

            if (tablePropertyData.OnHeaderRead != null)
            {
                var rowData = new object[totalFieldCount];
                for (int i = 0; i < totalFieldCount; i++)
                {
                    rowData[i] = reader.GetValue(i);
                }

                tablePropertyData.OnHeaderRead(rowData);
            }

            var fieldsToReadCount = columns.Count;

            object compatableList    = Activator.CreateInstance(typeof(List <>).MakeGenericType(tableRowType));
            var    rowIndex          = rowOffset + 2; //we skipped header
            var    readingShouldStop = false;

            while (reader.Read())
            {
                // create instance using lambdas:
                var instance = instanceCreator();

                foreach (var column in columns)
                {
                    var cellValue = reader.GetValue(column.ColumnIndex);
                    if (column.IsMandatory && (cellValue is null || cellValue.ToString() == string.Empty))
                    {
                        readingShouldStop = true;
                        break;
                    }

                    try
                    {
                        // set instance properties using lambdas
                        propertyProcessors[column.ColumnName](instance, cellValue);
                    }
                    catch (FormatException formatException)
                    {
                        propertyProcessors[column.ColumnName](instance, null);
                        this.Errors.Add($"{formatException.Message} - ['{column.ColumnName}':{rowIndex}]");
                    }
                    catch (NullReferenceException nullRefException)
                    {
                        throw new NullReferenceException($"{column.PropertyName} instance is null. Ensure that instance can be initialized (if it is an interface - specify implementation class with 'ImplementingClass()' method, if it is a nested property - ensure it is auto-initialized).");
                    }
                }

                if (readingShouldStop)
                {
                    break;
                }

                if (tablePropertyData.OnRowRead != null)
                {
                    var rowData = new object[totalFieldCount];
                    for (int i = 0; i < totalFieldCount; i++)
                    {
                        rowData[i] = reader.GetValue(i);
                    }

                    tablePropertyData.OnRowRead(instance, rowData);
                }

                listAdder(compatableList, instance);
                rowIndex++;
            }

            return(compatableList);
        }
Beispiel #2
0
 public SheetProcessingData(TablePropertyData tablePropertyData, PropertySetter propertySetter)
 {
     this.TablePropertyData = tablePropertyData;
     this.PropertySetter    = propertySetter;
 }