众所周知
众所周知,如果使用DataTable。一般的思路是这么写的
var exprotData = new DataTable("Datas"); exprotData.Columns.Add("编号", Type.GetType("System.String")); exprotData.Columns.Add("交易号", Type.GetType("System.String"));
然后数据组装,需要
dr["编号"] = item.Id; dr["交易号"] = item.TransNumber;
这样倒是没有啥毛病,但一来二去修改字段要去修改多处代码。多的话可能会漏掉
优化思路
这里没有经过严格的测试。只是进行尝试
自己写一个Attribute(或者用现成的displayName)
public class DataGridPropertyAttribute : Attribute { public string Name { get; set; } public bool IsHaveChild { get; set; } /// <summary> /// 标记导出到表格的属性 /// </summary> /// <param name="name">列表头</param> /// <param name="isHaveChild">是否含有二级数据</param> public DataGridPropertyAttribute(string name,bool isHaveChild = false) { Name = name; IsHaveChild = isHaveChild; } }
然后写一个扩展方法。把标记号的全部用dictionary保存
public static class CustomAttributeExtensions { public static Dictionary<DataGridPropertyAttribute, object> GetCustomAttributeEntity<TEntity>(this TEntity entity) where TEntity : class { var dic = new Dictionary<DataGridPropertyAttribute, object>(); var type = entity.GetType(); var propInfos = type.GetProperties(); foreach (var propertyInfo in propInfos) { if (!propertyInfo.IsDefined(typeof(DataGridPropertyAttribute), false)) continue; DataGridPropertyAttribute attribute = (DataGridPropertyAttribute)propertyInfo.GetCustomAttribute(typeof(DataGridPropertyAttribute), false); var name = attribute.Name; if(string.IsNullOrEmpty(name)) continue; if(dic.ContainsKey(attribute)) continue; var value = propertyInfo.GetValue(entity); dic.Add(attribute,value); } return dic; } }
为什么设定一个 isHaveChild
因为有些数据可能是无限套娃的。比如数据其实存在于OrderMallInfo里面,需要导出为店铺名称。标记为true以便于递归下去找到应该导出的字段(如果有更好的方法请评论告诉我~~)
[DataGridProperty("店铺",true)] [JsonProperty("mall_info")] public OrderMallInfo OrderMallInfo { get; set; }
public class OrderMallInfo { [DataGridProperty("店铺名称")] [JsonProperty("platform_mall_name")] public string PlatformMallName { get; set; } }
实际运行
false表示已经到尾。这个值需要作为列名,true表示还需要再次做反射尝试。