C# 导出表格时表头优化思路

众所周知

众所周知,如果使用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表示还需要再次做反射尝试。

原文地址:https://www.cnblogs.com/yinghualuowu/p/13535863.html