npoi2.3+泛型+反射 根据配置统一解析excel数据到实体的基础方法
解析方法:
/// <summary> /// excel数据解析到实体 /// </summary> /// <typeparam name="T">实体类型</typeparam> /// <param name="sheet">npoi读取到的excel工作表,需要解析的工作表</param> /// <param name="startRowIndex">从第几行开始解析 从1开始</param> /// <param name="relations">excel和实体的对应关系</param> /// <param name="msg">可能存在的错误提示</param> /// <returns>实体数据</returns> public List<T> Parse<T>(ISheet sheet, int startRowIndex, List<SheetToEntityAttrRelation> relations, out string msg) { msg = ""; if (relations == null || relations.Count <= 0) { msg += "没有excel列名与实体属性的对应关系;"; return null; } if (sheet == null) { msg += "sheet为空;"; return null; } List<T> list = new List<T>(); int rows = sheet.LastRowNum; //行数 PropertyInfo[] props = typeof(T).GetProperties(); if (props == null || props.Count() <= 0) { msg += "类型T的对象中没有属性;"; return null; } //逐行读取sheet中的行 for (int i = startRowIndex - 1; i <= rows; i++) { var row = sheet.GetRow(i); //GetRow序号是从0开始的 if (row == null) continue; T obj = (T)Activator.CreateInstance(typeof(T)); list.Add(obj); foreach (SheetToEntityAttrRelation r in relations) { //检查配置关系中的属性名在实体中是否存在 var currProps = props.Where(e => e.Name.Equals(r.AttrName)); if (currProps == null || currProps.Count() <= 0) { msg += "类型T的对象中没有属性:" + r.AttrName + ";"; continue; } PropertyInfo prop = currProps.ToList()[0]; string data = GetCellValue(row.GetCell(r.ColumnIndex - 1)); //GetCell序号是从为开始的 if (!string.IsNullOrEmpty(data)) { switch (r.DataType) { case DbType.AnsiString: prop.SetValue(obj, data, null); break; case DbType.Double: prop.SetValue(obj, Convert.ToDouble(data), null); break; case DbType.Int32: prop.SetValue(obj, Convert.ToInt32(data), null); break; case DbType.DateTime: if (string.IsNullOrEmpty(r.TimeFormat)) r.TimeFormat = "yyyyMmdd"; DateTime dt; if (DateTime.TryParseExact(data, r.TimeFormat, null, DateTimeStyles.None, out dt)) { prop.SetValue(obj, dt, null); } else { msg += string.Format("第{0}行第{1}列不是有效的日期格式数据", i + 1, r.ColumnIndex); continue; } break; } } else { msg += string.Format("第{0}行第{1}数据为空", i + 1, r.ColumnIndex); continue; } } } return list; } private string GetCellValue(ICell cell) { string value = ""; if (cell != null) { if (cell.CellType.Equals(CellType.String)) { value = cell.StringCellValue; } if (cell.CellType.Equals(CellType.Numeric)) { value = cell.NumericCellValue.ToString(); } if (cell.CellType.Equals(CellType.Boolean)) { value = cell.BooleanCellValue.ToString(); } } return value; }
参数中定义的类型:
/// <summary> /// excel工作表字段名与实体字段对应关系 /// </summary> public class SheetToEntityAttrRelation { /// <summary> /// excel列序号,第一列从1开始 /// </summary> public int ColumnIndex { get; set; } /// <summary> /// 实体属性名 /// </summary> public string AttrName { get; set; } /// <summary> /// 数据类型:允许string,int32,double,datetime /// </summary> public DbType DataType { get; set; } /// <summary> /// 如果数据类型为日期时间,将字符串转为日期时需要指定日期格式:yyyyMMdd,yyyy-MM-dd,yyyyMMddHHmmss,yyyy-MM-dd HH:mm:ss /// </summary> public string TimeFormat { get; set; } }