一个Excel导出类的实现过程(二):显示定制

导出操作中,我们常常不需要显示所有属性,比如Person类加入Guid属性:

public class Person
{
    public Int32 ID { get; set; }
    public Guid Guid { get; set; }
    public String Name { get; set; }
    public DateTime Birth { get; set; }
    public Double Salary { get; set; }
}

现在要求传入字符串数组headers,有什么显示什么,Type. GetProperty()方法可以取单个属性,我们加入Export的重载方法如下:

static void Export<T>(IList<T> records, IList<String> headers)
{
    if (records == null)
        throw new ArgumentNullException("records");
    if (headers == null || headers.Count == 0)
        throw new ArgumentNullException("headers");
    //像headers不可包含null元素、至少包含一个元素、元素不可重复等检查视需求而定, 下文不重重复

    PropertyInfo[] props = new PropertyInfo[headers.Count];
    for (Int32 i = 0; i < headers.Count; i++)
    {
        props[i] = typeof(T).GetProperty(headers[i]); //注意可能产生为null的元素
    }

    for (Int32 i = 0; i < headers.Count; i++)
    {
        Console.Write(headers[i]);
        Console.Write("\t");
    }
    Console.WriteLine();

    foreach (var record in records)
    {
        for (Int32 i = 0; i < props.Length; i++)
        {
            if (props[i] != null) //注意null检查
            {
                Object value = props[i].GetValue(record, null);
                Console.Write(value);
                Console.Write("\t");
            }
        }
        Console.WriteLine();
    }
}

第一个方法重构如下:

static void Export<T>(IList<T> records)
{
    if (records == null)
        throw new ArgumentNullException("records");

    String[] headers = typeof(T).GetProperties().Select(p => p.Name).ToArray();
    Export<T>(records, headers);
}

现在的导出操作,我们只打印提供的属性数组,同时请注意:小写的“birth”匹配不到任何属性。

Export<Person>(persons, new[] { "Name", "birth", "Salary" });

继续加入业务场景,以上代码使用了属性名,我们可以更友好,比如将“Name”打印为“名称”,“Salary”打印成“薪水”——题外话,好像没啥场景需要打印薪水,Whatever. 加一个辅助的Header类如下,并添加Export重载:

public class Header
{
    public String Name { get; private set; }
    public String PrintName { get; private set; }

    public Header(String name)
        : this(name, name)
    {
    }

    public Header(String name, String printName)
    {
        Name = name;
        PrintName = printName;
    }
}

新的Export方法第2个重载与第3个重载分别为:

static void Export<T>(IList<T> records, IList<String> headers)
{
    if (records == null)
        throw new ArgumentNullException("records");
    if (headers == null || headers.Count == 0)
        throw new ArgumentNullException("headers");

    Header[] newHeaders = typeof(T).GetProperties().Select(p => new Header(p.Name)).ToArray();
    Export<T>(records, newHeaders);
}

static void Export<T>(IList<T> records, IList<Header> headers)
{
    if (records == null)
        throw new ArgumentNullException("records");
    if (headers == null || headers.Count == 0)
        throw new ArgumentNullException("headers");

    PropertyInfo[] props = new PropertyInfo[headers.Count];
    for (Int32 i = 0; i < headers.Count; i++)
    {
        props[i] = typeof(T).GetProperty(headers[i].Name); //注意属性数组仍然可以有元素为null
    }

    for (Int32 i = 0; i < headers.Count; i++)
    {
        Console.Write(headers[i].PrintName);
        Console.Write("\t");
    }
    Console.WriteLine();

    foreach (var record in records)
    {
        for (Int32 i = 0; i < props.Length; i++)
        {
            if (props[i] != null) //注意null检查
            {
                Object value = props[i].GetValue(record, null);
                Console.Write(value);
                Console.Write("\t");
            }
        }
        Console.WriteLine();
    }
}

调用逻辑与输出如下:

List<Header> headers = new List<Header>();
headers.Add(new Header("ID"));
headers.Add(new Header("Name", "名称"));
headers.Add(new Header("Salary", "薪水"));
Export<Person>(persons, headers);
ID	名称	薪水	
1	Rattz	20.2	
2	Mike	20.2

posted @ 2013-05-16 16:30  Jusfr  阅读(563)  评论(0编辑  收藏  举报