因为前一段时间公司做项目的时候,用到了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