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

时间:2023-03-09 20:45:17
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) + ); //读取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) + );

帮助类:

    #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[]; 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 = ; 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 + ; 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