Epplus下的一个将Excel转换成List的范型帮助类

因为前一段时间公司做项目的时候,用到了Excel导入和导出,然后自己找了个插件Epplus进行操作,自己将当时的一些代码抽离出来写了一个帮助类。

因为帮助类是在Epplus基础之上写的,项目需要引用Epplus.dll。自己基础不是很扎实,有问题的地方欢迎指导。

1.用法,默认excel第一列是头部信息。

    public class UserInfo : XlsRow
    {
        public int id { get; set; }
        public string username { get; set; }
        public string address { get; set; }
        public int userage { get; set; }
        public DateTime birthday { get; set; }
        public decimal total { get; set; }
        public string grade { get; set; }
    }

      static void Main(string[] args)
        {
            string filePath = "E:\\ExcelConvertEntity\\datatest.xlsx";

            //转换address列的时候在所有地址钱添加“上海市”三个字
            ECEntityCOM<UserInfo>.ForMember(e => e.address, e => "上海市:" + e);

            //excel列name对应实体username进行映射
            ECEntityCOM<UserInfo>.ForMember("name", e => e.username);

            //列名age映射到实体userage属性,映射过程中给所有age加5
            ECEntityCOM<UserInfo>.ForMember("age", e => e.userage, e => Convert.ToInt32(e) + 5);

            //读取excel转换成List<UserInfo>
            List<UserInfo> list = ECEntityCOM<UserInfo>.LoadFromExcel(filePath);

            Console.WriteLine("ok");
            Console.ReadLine();
        }

a.实体需要继承我的自定义实体XlsRow,这个实体会记录转换过程出错信息,转换这一行的时候,是否出现过错误,具体是那一列出错的。转换出错单元格内内容是什么,还有错误信息。

 

  public class XlsRow
    {
        /// <summary>
        /// 错误信息
        /// </summary>
        public List<string> ErrMessage { get; set; }

        /// <summary>
        /// 错误列名
        /// </summary>
        public List<string> ErrColumn { get; set; }

        /// <summary>
        /// 错误内容
        /// </summary>
        public List<string> ErrValue { get; set; }

        /// <summary>
        /// 是否转换出错(false:未出错,true:出错)
        /// </summary>
        public bool IsErr { get; set; }
    }

 

然后转换过程中提供了几个方法,用来更好的自定义转换形式。

b.转换过程中,某一列统一进行某些处理操作,最后把处理后的信息存进实体列名里。

        //转换address列的时候在所有地址钱添加“上海市”三个字
            ECEntityCOM<UserInfo>.ForMember(e => e.address, e => "上海市:" + e);

c.实体名跟excel列头部名称不一致,可以自定义映射。

       //excel列name对应实体username进行映射
            ECEntityCOM<UserInfo>.ForMember("name", e => e.username);

d.自定义映射对excel单元格信息进行处理。

           //列名age映射到实体userage属性,映射过程中给所有age加5
            ECEntityCOM<UserInfo>.ForMember("age", e => e.userage, e => Convert.ToInt32(e) + 5);    

帮助类:

    #region 需要用到的实体

    public class XlsEntity
    {
        /// <summary>
        /// 实体名称
        /// </summary>
        public string EntityName { get; set; }

        /// <summary>
        /// 列名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 列下标
        /// </summary>
        public int ColumnIndex { get; set; }

        /// <summary>
        /// 转换方法
        /// </summary>
        public Func<string, object> ConvertFunc { get; set; }
    }

    public class XlsRow
    {
        /// <summary>
        /// 错误信息
        /// </summary>
        public List<string> ErrMessage { get; set; }

        /// <summary>
        /// 错误列名
        /// </summary>
        public List<string> ErrColumn { get; set; }

        /// <summary>
        /// 错误内容
        /// </summary>
        public List<string> ErrValue { get; set; }

        /// <summary>
        /// 是否转换出错(false:未出错,true:出错)
        /// </summary>
        public bool IsErr { get; set; }
    }

    #endregion

    public class ECEntityCOM<T> where T : XlsRow, new()
    {
        
        private static List<XlsEntity> xlsHeader = new List<XlsEntity>();

        #region 初始化转换形式

        
        public static void ForMember(Expression<Func<T, object>> entityExpression, Func<string, object> func)
        {
            XlsEntity xlsEntity = new XlsEntity();
            xlsEntity.EntityName = GetPropertyName(entityExpression);
            xlsEntity.ColumnName = xlsEntity.EntityName;
            xlsEntity.ConvertFunc = func;
            xlsHeader.Add(xlsEntity);
        }

        
        public static void ForMember(string columnName, Expression<Func<T, object>> entityExpression)
        {
            XlsEntity xlsEntity = new XlsEntity();
            xlsEntity.ColumnName = columnName;
            xlsEntity.EntityName = GetPropertyName(entityExpression);
            xlsHeader.Add(xlsEntity);
        }

        public static void ForMember(string columnName, string entityName)
        {
            XlsEntity xlsEntity = new XlsEntity();
            xlsEntity.ColumnName = columnName;
            xlsEntity.EntityName = entityName;
            xlsHeader.Add(xlsEntity);
        }

        public static void ForMember(string columnName, string entityName, Func<string, object> func) 
        {
            XlsEntity xlsEntity = new XlsEntity();
            xlsEntity.ColumnName = columnName;
            xlsEntity.EntityName = entityName;
            xlsEntity.ConvertFunc = func;
            xlsHeader.Add(xlsEntity);
        }

        public static void ForMember(string columnName, Expression<Func<T, object>> entityExpression, Func<string, object> func)
        {
            XlsEntity xlsEntity = new XlsEntity();
            xlsEntity.ColumnName = columnName;
            xlsEntity.EntityName = GetPropertyName(entityExpression);
            xlsEntity.ConvertFunc = func;
            xlsHeader.Add(xlsEntity);
        }

        #endregion

        #region 从Excel中加载数据(泛型)

        public static List<T> LoadFromExcel(string filePath)
        {
            FileInfo existingFile = new FileInfo(filePath);
            List<T> resultList = new List<T>();
            
            using (ExcelPackage package = new ExcelPackage(existingFile))
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets[1];

                int colStart = worksheet.Dimension.Start.Column;  
                int colEnd = worksheet.Dimension.End.Column; 
                int rowStart = worksheet.Dimension.Start.Row; 
                int rowEnd = worksheet.Dimension.End.Row;
                
                PropertyInfo[] propertyInfoList = typeof(T).GetProperties();
                XlsEntity xlsEntity;

                #region 将实体和excel列标题进行对应绑定,添加到集合中
                
                for (int i = colStart; i <= colEnd; i++)
                {
                    string columnName = worksheet.Cells[rowStart, i].Value.ToString();

                    xlsEntity = xlsHeader.FirstOrDefault(e => e.ColumnName == columnName);
                    
                    for (int j = 0; j < propertyInfoList.Length; j++)
                    {
                        
                        if (xlsEntity != null && xlsEntity.ColumnName == columnName)
                        {
                            xlsEntity.ColumnIndex = i;
                            xlsHeader.Add(xlsEntity);
                        }
                        else if (propertyInfoList[j].Name == columnName)
                        {
                            xlsEntity = new XlsEntity();
                            xlsEntity.ColumnName = columnName;
                            xlsEntity.EntityName = propertyInfoList[j].Name;
                            xlsEntity.ColumnIndex = i;
                            xlsHeader.Add(xlsEntity);
                            break;
                        }
                    }
                }

                #endregion

                #region 根据对应的实体名列名的对应绑定就行值的绑定
                
                for (int row = rowStart + 1; row < rowEnd; row++)
                {
                    T result = new T();
                    foreach (PropertyInfo p in propertyInfoList)
                    {
                        var xlsRow = xlsHeader.FirstOrDefault(e=> e.EntityName == p.Name);
                        if (xlsRow == null) continue;

                        ExcelRange cell = worksheet.Cells[row, xlsRow.ColumnIndex]; 
                        if (cell.Value == null) continue;
                        
                        try
                        {
                            if (xlsRow.ConvertFunc != null)
                            {
                                object entityValue = xlsRow.ConvertFunc(cell.Value.ToString());
                                p.SetValue(result, entityValue);
                            }
                            else 
                            {
                                cellBindValue(result, p, cell);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (result.ErrColumn == null) result.ErrColumn = new List<string>();
                            if (result.ErrMessage == null) result.ErrMessage = new List<string>();
                            if (result.ErrValue == null) result.ErrValue = new List<string>();
                            result.ErrColumn.Add(p.Name);
                            result.ErrMessage.Add(ex.Message);
                            result.ErrValue.Add(cell.Value.ToString());
                            result.IsErr = true;
                        }
                    }
                    resultList.Add(result);
                }

                #endregion
            }
            return resultList;
        }

        #endregion

        #region 给实体绑定值

        private static void cellBindValue(T result, PropertyInfo p, ExcelRange cell)
        {
            switch (p.PropertyType.Name.ToLower())
            {
                case "string":
                    p.SetValue(result, cell.GetValue<String>());
                    break;
                case "int16":
                    p.SetValue(result, cell.GetValue<Int16>());
                    break;
                case "int32":
                    p.SetValue(result, cell.GetValue<Int32>());
                    break;
                case "int64":
                    p.SetValue(result, cell.GetValue<Int64>());
                    break;
                case "decimal":
                    p.SetValue(result, cell.GetValue<Decimal>());
                    break;
                case "double":
                    p.SetValue(result, cell.GetValue<Double>());
                    break;
                case "datetime":
                    p.SetValue(result, cell.GetValue<DateTime>());
                    break;
                case "boolean":
                    p.SetValue(result, cell.GetValue<Boolean>());
                    break;
                case "byte":
                    p.SetValue(result, cell.GetValue<Byte>());
                    break;
                case "char":
                    p.SetValue(result, cell.GetValue<Char>());
                    break;
                case "single":
                    p.SetValue(result, cell.GetValue<Single>());
                    break;
                default:
                    p.SetValue(result, cell.Value);
                    break;
            }
        }

        #endregion

        #region 获取Lambda的属性名称

        private static string GetPropertyName(Expression<Func<T, object>> expression) 
        {
            Expression expressionToCheck = expression;
            bool done = false;
            while (!done)
            {
                switch (expressionToCheck.NodeType)
                {
                    case ExpressionType.Convert:
                        expressionToCheck = ((UnaryExpression)expressionToCheck).Operand;
                        break;
                    case ExpressionType.Lambda:
                        expressionToCheck = ((LambdaExpression)expressionToCheck).Body;
                        break;
                    case ExpressionType.MemberAccess:
                        var memberExpression = ((MemberExpression)expressionToCheck);
                        string propertyName = memberExpression.Member.Name;
                        return propertyName;
                    default:
                        done = true;
                        break;
                }
            }
            return "";
        }

        #endregion

    }

 补充一个例子

https://files.cnblogs.com/ariklee/ExcelConvertEntity.rar

posted @ 2014-07-31 19:21  十二月雨  阅读(2309)  评论(2编辑  收藏  举报