• List<T>生成Excel类,请大家指教


    最近比较闲,随手写了个类来生成Excel文件,写完用的时候发现几个问题。找不到人帮忙,所以发出来请大家指点指点。

    先贴代码吧!

    Excel生成
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Reflection;

    namespace AFS.Service.Common
    {
    /// <summary>
    /// Excel字段特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class ExcelColumnAttribute : Attribute
    {
    public ExcelColumnAttribute(String colhead, int colindex)
    {
    this.ColumnHeader = colhead;
    this.ColumnIndex = colindex;
    }

    /// <summary>
    /// 列名称
    /// </summary>
    public String ColumnHeader
    {
    get;
    set;
    }

    /// <summary>
    ///
    /// </summary>
    public int ColumnIndex
    {
    get;
    set;
    }
    }


    /// <summary>
    /// Excel工具类
    /// </summary>
    public class ExcelUtility
    {
    /// <summary>
    /// 生成Excel文件
    /// </summary>
    /// <param name="list"></param>
    public void CreateExcelFile<T>(IList<T> list)
    {

    #region 文件头
    //Response.Clear();
    HttpContext.Current.Response.Buffer = true;
    HttpContext.Current.Response.Charset
    = "GB2312";
    HttpContext.Current.Response.ContentEncoding
    = System.Text.Encoding.GetEncoding("GB2312");
    HttpContext.Current.Response.AppendHeader(
    "Content-Disposition", "attachment;filename=Report.xls");
    HttpContext.Current.Response.ContentType
    = "application/vnd.ms-excel";

    StringBuilder htmlBuilder
    = new StringBuilder();
    htmlBuilder.AppendLine(
    "<html><head><meta http-equiv=Content-Type content=\"text/html; charset=GB2312\"></head><body>")
    .AppendLine(
    "<table width='100%' id='jigou' cellspacing='0' rules='all' bgcolor='#FFFFFF' border='1' style='border-color:#95BCDD;100%;border-collapse:collapse;'>")
    .AppendLine(
    "\t<tr align='center' style='background-color:#EDF6FF;height:30px;'>")
    .AppendLine(
    "{0}")
    .Append(
    "</tr>");

    #endregion


    //列头控制
    Boolean columnHeader = true;
    //列头内容
    StringBuilder columnHeaderStr = new StringBuilder();

    if (list.Count < 1)
    {
    //无数据时只添加表头
    PropertyInfo[] plist = typeof(T).GetProperties();
    //对所有属性进行排序
    OrderPropertys(ref plist);

    foreach (PropertyInfo p in plist)
    {
    Object[] a
    = p.GetCustomAttributes(typeof(ExcelColumnAttribute), true);
    if (a.Length > 0)
    {
    ExcelColumnAttribute d
    = ((ExcelColumnAttribute)a[0]);

    //填充列头
    columnHeaderStr.AppendFormat("<td>{0}</td>", d.ColumnHeader);
    }
    }
    }
    else
    {
    foreach (T t in list)
    {
    Type ut
    = t.GetType();

    PropertyInfo[] plist
    = ut.GetProperties();

    //对所有属性进行排序
    OrderPropertys(ref plist);

    htmlBuilder.AppendLine(
    "<tr>");

    foreach (PropertyInfo p in plist)
    {
    Object[] a
    = p.GetCustomAttributes(typeof(ExcelColumnAttribute), true);
    if (a.Length > 0)
    {
    ExcelColumnAttribute d
    = ((ExcelColumnAttribute)a[0]);

    //填充列头
    if (columnHeader)
    {
    columnHeaderStr.AppendFormat(
    "<td>{0}</td>", d.ColumnHeader);
    }

    Object value
    = ut.GetProperty(p.Name).GetValue(t, null);

    //填充列数据
    htmlBuilder.AppendFormat("<td>{0}</td>", (value == null ? "" : value.ToString()));
    }
    }

    //列头控制
    if (columnHeader)
    {
    columnHeader
    = false;
    }

    htmlBuilder.AppendLine(
    "</tr>");
    }
    }

    htmlBuilder.Append(
    "</table></body></html>");
    HttpContext.Current.Response.Write(String.Format(htmlBuilder.ToString(), columnHeaderStr));
    HttpContext.Current.Response.End();
    }

    /// <summary>
    /// 对所有属性进行排序
    /// </summary>
    /// <param name="plist"></param>
    private void OrderPropertys(ref PropertyInfo[] plist)
    {
    //对所有属性排序
    for (int i = 0; i < plist.Length; i++)
    {
    Object[] pi
    = plist[i].GetCustomAttributes(typeof(ExcelColumnAttribute), true);
    for (int j = 0; j < plist.Length; j++)
    {
    Object[] pj
    = plist[j].GetCustomAttributes(typeof(ExcelColumnAttribute), true);
    if (pi.Length > 0 && pj.Length > 0)
    {
    if (((ExcelColumnAttribute)pi[0]).ColumnIndex > ((ExcelColumnAttribute)pj[0]).ColumnIndex)
    {
    Object temp
    = plist[i];
    plist[i]
    = plist[j];
    plist[j]
    = (PropertyInfo)temp;
    }
    }
    }
    }
    }


    }
    }
    用的时候需要在T的实体类上添加特性后调用

    实体
    public class Entity
    {
    [ExcelColumn(
    "编号",1)]
    public int Id{set;get;}

    [ExcelColumn(
    "名称",1)]
    public String Name{set;get;}
    }

    public static void Main()
    {
    IList
    <Entity> list = GetData();
    ExcelUtility excelUtility
    = new ExcelUtility();
    excelUtility.CreateExcelFile
    <Entity>(list);
    }
    现在有两个问题,首先是CreateExcelFile这个方法,感觉太长了点,没啥好的方案来优化。这个倒是也无所谓。

    关键问题是,这样的生成方式很不方便对数据做额外的处理,很多实体类都是根据数据表来生成的,比如可能实体类中性别存的是1,2,我先 导出Excel要变成男,女;类似这样的情况,这个类就没办法处理。除非在实体类上做手脚,但是那样感觉背离了把生成Excel操作封装起来的原意,因为可能非Excel不需要变成男,女。

    大家有什么想法没?小弟这里拜谢了。

  • 相关阅读:
    面向对象
    数据库,连接查询
    主外键,子查询
    字符串函数
    数据库。模糊查询,聚合函数,时间日期函数
    数据库。增,删,改,查
    数据库
    多窗体及菜单
    winform公共控件及其常用属性
    winform 客户端应用程序(c/s b/s)
  • 原文地址:https://www.cnblogs.com/breezeli/p/1872516.html
Copyright © 2020-2023  润新知