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不需要变成男,女。

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

原文地址:https://www.cnblogs.com/breezeli/p/1872516.html