zoukankan      html  css  js  c++  java
  • 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
    
        }

     补充一个例子

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

  • 相关阅读:
    Centos7 关闭防火墙
    Linux下磁盘挂载
    Sqlserver游标复习
    Redis-benchmark测试Redis性能
    将treeview控件内容导出图片
    使用redis进行消息推送
    web性能优化系列之网站瓶颈识别
    SqlServer时间格式化
    PHP二位数组/多维数组 根据某个键值排序
    VIM Taglist + ctags
  • 原文地址:https://www.cnblogs.com/ariklee/p/3881529.html
Copyright © 2011-2022 走看看