ASP.NET 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, bool showDisplayName = true) { this.Entity = entity; this.FileName = fileName; this.ShowDisplayName = showDisplayName; } public ExcelResult(IList<T> entity, bool showDisplayName = true) { this.Entity = entity; DateTime time = DateTime.Now; this.FileName = string.Format("{0}_{1}_{2}_{3}", time.Month, time.Day, time.Hour, time.Minute); this.ShowDisplayName = showDisplayName; } public IList<T> Entity { get; set; } public string FileName { get; set; } public bool ShowDisplayName { 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(); byte[] bytestr = Encoding.Unicode.GetBytes(sBuilder.ToString()); context.HttpContext.Response.Clear(); context.HttpContext.Response.ClearContent(); context.HttpContext.Response.Buffer = true; context.HttpContext.Response.Charset = "GB2312"; context.HttpContext.Response.ContentEncoding = Encoding.GetEncoding("GB2312"); context.HttpContext.Response.ContentType = "application/ms-excel"; context.HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ".xls"); context.HttpContext.Response.AddHeader("Content-Length", bytestr.Length.ToString()); context.HttpContext.Response.Write(sBuilder); context.HttpContext.Response.Flush(); context.HttpContext.Response.Close(); 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; } PropertyInfo[] properties = typeof(T).GetProperties(); if (properties.Length <= 0) { return; } for (int i = 0; i < Entity.Count; i++) { for (int j = 0; j < properties.Length; j++) { string sign = j == properties.Length - 1 ? "\n" : "\t"; object obj = properties[j].GetValue(Entity[i], null); sb.Append(obj ?? string.Empty).Append(sign); } } } /// <summary> /// 根据指定类型T的所有属性名称来组合Excel表头。 /// </summary> /// <param name="sb"></param> private void AddTableHead(StringBuilder sb) { PropertyInfo[] properties = typeof(T).GetProperties(); if (properties.Length <= 0) { return; } for (int i = 0; i < properties.Length; i++) { string headName = properties[i].Name; string sign = i == properties.Length - 1 ? "\n" : "\t"; if (!ShowDisplayName) { sb.Append(headName).Append(sign); continue; } Attribute attribute = Attribute.GetCustomAttribute(properties[i], typeof(DisplayNameAttribute)); if (attribute != null) { DisplayNameAttribute displayNameAttribute = attribute as DisplayNameAttribute; if (displayNameAttribute != null && !string.IsNullOrWhiteSpace(displayNameAttribute.DisplayName)) { headName = displayNameAttribute.DisplayName; } } sb.Append(headName).Append(sign); } } }
在控制器中调用方法:
public ActionResult Index() { List<Student> students = new List<Student>(); for (int i = 1; i <= 100; i++) { students.Add(new Student { Name = "Name " + i.ToString(), Age = i, Address = "Address " + i.ToString() }); } return new ExcelResult<Student>(students); }
上面代码中用到的Student类定义:
public class Student { [DisplayName("姓名")] public string Name { get; set; } [DisplayName("年龄")] public int Age { get; set; } [DisplayName("家庭住址")] public string Address { get; set; } }
结果导出的Excel文档截图: