使用.NET反射和泛型实现通用CSV导出功能

在软件开发过程中,经常需要将数据导出CSV格式。CSV格式因其简单和通用性而被广泛接受。在许多应用程序中,根据不同的需求,可能会有多个导出功能,每个功能针对不同的对象集合进行导出。然而,这往往会导致程序员需要为每种对象类型编写不同的导出方法,这无疑增加了工作量。本文的目的是提供一个使用.NET反射和泛型技术的通用解决方案,使得相同的导出功能可以在整个应用程序中重复使用,而不受对象类型的限制,从而节省程序员的宝贵时间。

问题陈述

观察到程序员们花费数小时构建满足不同需求的导出功能。对于不同的对象集合,程序员会编写不同的导出方法来解决特定的导出功能。为什么会这样?答案很简单——每个对象都有不同的属性,因此CSV包含了每个对象的不同列名。所以程序员会编写不同的导出函数来解决特定的对象类型,并静态地安排CSV列名。

反射如何帮助

为了解决这个问题,可以使用.NET泛型和反射。不会讨论这些出色的特性,而是会利用这些特性来找到解决方案。如果浏览MSDN,看看反射能做什么,会发现PropertyInfo(嗯,这正是需要的)。使用PropertyInfo可以发现诸如名称、数据类型、声明类型、反射类型以及属性的只读或可写状态等信息,并获取或设置属性值。

想法是使用泛型集合进行导出,并使用反射遍历所有属性,从而可以获取所有属性的名称/类型,无论提供的对象集合是什么。一旦有了属性名称/类型,就可以按照需求进行任何数据格式化或处理。例如,对于某个应用程序,如果规范是将日期时间导出到CSV,它应该格式化为ddMMYYY。现在有了属性类型,这不是很简单吗?

下面是一个方法,它接受泛型列表作为参数,并使用反射遍历类型并相应地导出。

public static void ExportListToCSV<T>(List<T> listToExport, string seperateChar) { Int32 success = 0; StringBuilder export = new StringBuilder(); try { string seperator = "\n"; StringBuilder builder = new StringBuilder(); PropertyInfo[] fieldInfo = listToExport[0].GetType().GetProperties(); foreach (PropertyInfo col in fieldInfo) { if (col.PropertyType != typeof(EntityKey) && col.PropertyType != typeof(EntityState)) { builder.Append(seperator).Append(col.Name); seperator = seperateChar; } } export.AppendLine(builder.ToString()); foreach (T dataItem in listToExport) { PropertyInfo[] allProperties = dataItem.GetType().GetProperties(); seperator = "\n"; StringBuilder builderTmp = new StringBuilder(); foreach (PropertyInfo thisProperty in allProperties) { if (thisProperty.PropertyType != typeof(EntityKey) && thisProperty.PropertyType != typeof(EntityKey)) { object value = thisProperty.GetValue(dataItem, null); String propetyValue = (value == null ? String.Empty : value.ToString()); builderTmp.Append(seperator).Append(propetyValue); seperator = seperateChar; } } ++success; export.AppendLine(builderTmp.ToString()); } } catch (Exception ex) { throw ex; } // ... HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Buffer = true; HttpContext.Current.Response.ContentType = "application/CSV"; HttpContext.Current.Response.AppendHeader("content-disposition", "attachment;filename=FileName.csv"); HttpContext.Current.Response.Charset = ""; HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.Write(export.ToString()); HttpContext.Current.Response.End(); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485