Пример #1
0
        public List <TEntity> Map(ExcelData data)
        {
            try
            {
                if (data == null)
                {
                    return(null);
                }

                PropertyInfo[] properties;
                try
                {
                    properties = typeof(TEntity)
                                 .GetProperties()
                                 .OrderBy(p => p.GetCustomAttributes().OfType <ExcelColumnAttribute>().First().Order)
                                 .Select(p => p).ToArray();
                }
                catch (InvalidOperationException)
                {
                    throw new Exception(
                              string.Format("{0} Data can't be import to Excel. Please check than ExcelColumn attribute is specified for each columns",
                                            typeof(TEntity)));
                }

                if (!data.DataRows.Any())
                {
                    return(new List <TEntity>());
                }

                var entities = new List <TEntity>();

                var excelColumnProperties = new Dictionary <string, PropertyInfo>(StringComparer.OrdinalIgnoreCase);
                var excelColumnAttributes =
                    new Dictionary <string, ExcelColumnAttribute>(StringComparer.OrdinalIgnoreCase);

                for (int i = 0; i < data.DataRows.Count; i++)
                {
                    var row = data.DataRows[i];

                    // skip a row if all cells are empty
                    if (row.All(string.IsNullOrEmpty))
                    {
                        continue;
                    }

                    var entity = (TEntity)Activator.CreateInstance(typeof(TEntity), new object[] {});

                    for (int j = 0; j < data.Headers.Count; j++)
                    {
                        if (i == 0 && !string.IsNullOrEmpty(data.Headers[j]))
                        {
                            ExcelColumnAttribute excelColumnAttribute = null;
                            var excelColumnProperty = properties
                                                      .FirstOrDefault(p =>
                            {
                                if (p.CanWrite &&
                                    p.Name.Equals(data.Headers[j], StringComparison.CurrentCultureIgnoreCase))
                                {
                                    return(true);
                                }
                                var item = p.GetCustomAttributes()
                                           .OfType <ExcelColumnAttribute>()
                                           .FirstOrDefault();
                                if (item != null && item.Name != null)
                                {
                                    if (item.Name.Equals(data.Headers[j], StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        excelColumnAttribute = item;
                                        return(true);
                                    }
                                }
                                return(false);
                            });

                            if (excelColumnProperty != null)
                            {
                                if (excelColumnProperties.ContainsKey(data.Headers[j]))
                                {
                                    throw new InvalidDataException(string.Format("Input excel contains more than one columns with '{0}' name", data.Headers[j]));
                                }

                                excelColumnProperties.Add(data.Headers[j], excelColumnProperty);
                            }

                            if (excelColumnAttribute != null)
                            {
                                excelColumnAttributes.Add(data.Headers[j], excelColumnAttribute);
                            }
                        }

                        if (j >= row.Count)
                        {
                            continue;
                        }
                        var cell = row[j];

                        // don't write values of a column if a header is empty
                        if (!excelColumnProperties.ContainsKey(data.Headers[j]))
                        {
                            continue;
                        }
                        var property = excelColumnProperties[data.Headers[j]];
                        ExcelColumnAttribute excelAttribute;
                        excelColumnAttributes.TryGetValue(data.Headers[j], out excelAttribute);
                        Type   propertyType = property.PropertyType;
                        object propertyValue;
                        try
                        {
                            propertyValue = _excelDataFormatConvertor.ConvertStringToValue(cell, propertyType, excelAttribute?.Format ?? ExcelColumnFormat.None);
                            Type   t         = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
                            object safeValue = (propertyValue == null) ? null : Convert.ChangeType(propertyValue, t);
                            property.SetValue(entity, safeValue, null);
                        }
                        catch (Exception ex) when(ex is InvalidCastException || ex is FormatException)
                        {
                            var columnName = data.Headers[j];
                            var rowNumber  = i + 2;

                            throw new InvalidFormatOfExcelCellException(data.SheetName, columnName, rowNumber, ex);
                        }
                    }

                    entities.Add(entity);
                }

                return(entities);
            }
            catch (InvalidFormatOfExcelCellException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new Exception("An exception occurs during Excel data reading", ex);
            }
        }
Пример #2
0
        public ExcelData Map(List <TEntity> entities, string sheetName)
        {
            try
            {
                ExcelData data = new ExcelData();
                data.SheetName = sheetName;
                data.Headers   = new List <string>();
                data.DataRows  = new List <List <string> >();
                PropertyInfo[] properties;
                try
                {
                    properties = typeof(TEntity)
                                 .GetProperties()
                                 .OrderBy(p => p.GetCustomAttributes().OfType <ExcelColumnAttribute>().First().Order)
                                 .Select(p => p).ToArray();
                }
                catch (InvalidOperationException)
                {
                    throw new Exception(string.Format("{0} Data can't be import to Excel. Please check than ExcelColumn attribute is specified for each columns", typeof(TEntity)));
                }

                if (entities == null || !entities.Any())
                {
                    data.Headers.AddRange(GetHeaders(properties));
                    return(data);
                }

                var propertiesFormat = new Dictionary <string, string>();
                for (int i = 0; i < entities.Count; i++)
                {
                    var rowCellsValues = new List <string>();
                    foreach (var property in properties)
                    {
                        // add headers based on entity properties names
                        if (i == 0)
                        {
                            var excelAttribute =
                                property.GetCustomAttributes().First(attr => attr is ExcelColumnAttribute) as
                                ExcelColumnAttribute;
                            if (excelAttribute != null)
                            {
                                data.Headers.Add(!string.IsNullOrEmpty(excelAttribute.Name)
                                    ? excelAttribute.Name
                                    : property.Name);

                                if (excelAttribute.Format != ExcelColumnFormat.None)
                                {
                                    propertiesFormat.Add(property.Name, _excelDataFormatConvertor.GetFormatByFormatType(excelAttribute.Format));
                                }
                            }
                        }

                        object propertyValue = property.GetValue(entities[i], null);
                        string customFormat  = propertiesFormat.ContainsKey(property.Name) ? propertiesFormat[property.Name] : null;
                        var    cellValue     = _excelDataFormatConvertor.ConvertValueToString(propertyValue, customFormat);
                        rowCellsValues.Add(cellValue);
                    }

                    data.DataRows.Add(rowCellsValues);
                }

                return(data);
            }
            catch (Exception ex)
            {
                throw new Exception("An exception occurs during Excel data writing", ex);
            }
        }