MVC 将IList<T>导出Excel文档的泛型类(继承自ActionResult)
最近MVC项目中要使用到Excel导出功能,在网上找了些资料,自己写了一个通用的泛型类(ExcelResult)。因为是直接继承自ActionResult这个抽象类的,所以用起来很方便,在控制器的Action中直接实例化返回即可。本人的代码功底不是很好,写的代码有点烂,希望大伙指正。
废话少说,直接上类完整代码:
///<summary>
/// 提供将泛型集合数据导出Excel文档。
///</summary>
///<typeparam name="T"></typeparam>
public class ExcelResult<T> : ActionResult where T : new()
{
public ExcelResult(IList<T> entity, string fileName)
{
this.Entity = entity;
this.FileName = fileName;
}
public ExcelResult(IList<T> entity)
{
this.Entity = entity;
DateTime time = DateTime.Now;
this.FileName = string.Format("{0}_{1}_{2}_{3}",
time.Month, time.Day, time.Hour, time.Minute);
}
public IList<T> Entity
{
get;
set;
}
public string FileName
{
get;
set;
}
public override void ExecuteResult(ControllerContext context)
{
if (Entity == null)
{
new EmptyResult().ExecuteResult(context);
return;
}
SetResponse(context);
}
///<summary>
/// 设置并向客户端发送请求响应。
///</summary>
///<param name="context"></param>
private void SetResponse(ControllerContext context)
{
StringBuilder sBuilder = ConvertEntity();
context.HttpContext.Response.Write("<script>document.close();</script>");
context.HttpContext.Response.Clear();
context.HttpContext.Response.Buffer = true;
context.HttpContext.Response.Charset = "UTF-8";
context.HttpContext.Response.ContentEncoding = System.Text.Encoding.Default;
context.HttpContext.Response.ContentType = "application/vnd.ms-excel";
context.HttpContext.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + FileName + ".xls\"");
System.IO.StringWriter tmpSW = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter tmpHTW = new System.Web.UI.HtmlTextWriter(tmpSW);
tmpHTW.WriteLine(sBuilder);
context.HttpContext.Response.Write(tmpSW.ToString());
context.HttpContext.Response.End();
}
///<summary>
/// 把泛型集合转换成组合Excel表格的字符串。
///</summary>
///<returns></returns>
private StringBuilder ConvertEntity()
{
StringBuilder sb = new StringBuilder();
AddTableHead(sb);
AddTableBody(sb);
return sb;
}
///<summary>
/// 根据IList泛型集合中的每项的属性值来组合Excel表格。
///</summary>
///<param name="sb"></param>
private void AddTableBody(StringBuilder sb)
{
if (Entity == null || Entity.Count <= 0)
{
return;
}
PropertyDescriptorCollection properties = FindProperties();
if (properties.Count <= 0)
{
return;
}
for (int i = 0; i < Entity.Count; i++)
{
for (int j = 0; j < properties.Count; j++)
{
string sign = j == properties.Count - 1 ? "\n" : "\t";
object obj = properties[j].GetValue(Entity[i]);
obj = obj == null ? string.Empty : obj.ToString();
sb.Append(obj + sign);
}
}
}
///<summary>
/// 根据指定类型T的所有属性名称来组合Excel表头。
///</summary>
///<param name="sb"></param>
private void AddTableHead(StringBuilder sb)
{
PropertyDescriptorCollection properties = FindProperties();
if (properties.Count <= 0)
{
return;
}
for (int i = 0; i < properties.Count; i++)
{
string sign = i == properties.Count - 1 ? "\n" : "\t"; sb.Append(properties[i].Name + sign);
} }
///<summary>
/// 返回指定类型T的属性集合。
///</summary>
///<returns></returns>
private static PropertyDescriptorCollection FindProperties()
{
return TypeDescriptor.GetProperties(typeof(T));
}
}
在控制器中调用方法:
public ActionResult Index()
{
List<Product> products = new List<Product
for (int i = 0; i < 100; i++)
{
products.Add(new Product()
{
ID = "000001",
Name = "测试",
Description = "测试"
});
}
return new ExcelResult<Product>(products);
}
上面代码中用到的Product类定义:
public class Product
{ public Product()
{
}
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
结果导出的Excel文档截图: