ASP.NET MVC 将IList<T>导出Excel文档的泛型类(继承自ActionResult)

来源:互联网 发布:三角九九乘法表编程 编辑:程序博客网 时间:2024/06/05 02:48

最近MVC项目中要使用到Excel导出功能,在网上找了些资料,自己写了一个通用的泛型类(ExcelResult)。因为是直接继承自ActionResult这个抽象类的,所以用起来很方便,在控制器的Action中直接实例化返回即可。本人的代码功底不是很好,写的代码有点烂,希望大伙指正。

 

废话少说,直接上类完整代码:

复制代码
  1 /// <summary>  2     /// 提供将泛型集合数据导出Excel文档。  3     /// </summary>  4     /// <typeparam name="T"></typeparam>  5     public class ExcelResult<T> : ActionResult where T : new()  6     {  7         public ExcelResult(IList<T> entity, string fileName)  8         {  9             this.Entity = entity; 10             this.FileName = fileName; 11         } 12  13         public ExcelResult(IList<T> entity) 14         { 15             this.Entity = entity; 16  17             DateTime time = DateTime.Now; 18             this.FileName = string.Format("{0}_{1}_{2}_{3}", 19                 time.Month, time.Day, time.Hour, time.Minute); 20         } 21  22         public IList<T> Entity 23         { 24             get; 25             set; 26         } 27  28         public string FileName 29         { 30             get; 31             set; 32         } 33  34         public override void ExecuteResult(ControllerContext context) 35         { 36             if (Entity == null) 37             { 38                 new EmptyResult().ExecuteResult(context); 39                 return; 40             } 41  42             SetResponse(context); 43         } 44  45         /// <summary> 46         /// 设置并向客户端发送请求响应。 47         /// </summary> 48         /// <param name="context"></param> 49         private void SetResponse(ControllerContext context) 50         { 51             StringBuilder sBuilder = ConvertEntity(); 52             byte[] bytestr = Encoding.Unicode.GetBytes(sBuilder.ToString()); 53  54             context.HttpContext.Response.Clear(); 55             context.HttpContext.Response.ClearContent(); 56             context.HttpContext.Response.Buffer = true; 57             context.HttpContext.Response.Charset = "GB2312"; 58             context.HttpContext.Response.ContentEncoding = System.Text.Encoding.UTF8; 59             context.HttpContext.Response.ContentType = "application/ms-excel"; 60             context.HttpContext.Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ".xls"); 61             context.HttpContext.Response.AddHeader("Content-Length", bytestr.Length.ToString()); 62             context.HttpContext.Response.Write(sBuilder); 63             context.HttpContext.Response.End(); 64         } 65  66         /// <summary> 67         /// 把泛型集合转换成组合Excel表格的字符串。 68         /// </summary> 69         /// <returns></returns> 70         private StringBuilder ConvertEntity() 71         { 72             StringBuilder sb = new StringBuilder(); 73  74             AddTableHead(sb); 75             AddTableBody(sb); 76  77             return sb; 78         } 79  80         /// <summary> 81         /// 根据IList泛型集合中的每项的属性值来组合Excel表格。 82         /// </summary> 83         /// <param name="sb"></param> 84         private void AddTableBody(StringBuilder sb) 85         { 86             if (Entity == null || Entity.Count <= 0) 87             { 88                 return; 89             } 90  91             PropertyDescriptorCollection properties = FindProperties(); 92  93             if (properties.Count <= 0) 94             { 95                 return; 96             } 97  98             for (int i = 0; i < Entity.Count; i++) 99             {100                 for (int j = 0; j < properties.Count; j++)101                 {102                     string sign = j == properties.Count - 1 ? "\n" : "\t";103                     object obj = properties[j].GetValue(Entity[i]);104                     obj = obj == null ? string.Empty : obj.ToString();105                     sb.Append(obj + sign);106                 }107             }108         }109 110         /// <summary>111         /// 根据指定类型T的所有属性名称来组合Excel表头。112         /// </summary>113         /// <param name="sb"></param>114         private void AddTableHead(StringBuilder sb)115         {116             PropertyDescriptorCollection properties = FindProperties();117 118             if (properties.Count <= 0)119             {120                 return;121             }122 123             for (int i = 0; i < properties.Count; i++)124             {125                 string sign = i == properties.Count - 1 ? "\n" : "\t";126                 sb.Append(properties[i].Name + sign);127             }128         }129 130         /// <summary>131         /// 返回指定类型T的属性集合。132         /// </summary>133         /// <returns></returns>134         private static PropertyDescriptorCollection FindProperties()135         {136             return TypeDescriptor.GetProperties(typeof(T));137         }138     }
复制代码

 

在控制器中调用方法:

复制代码
 1       public ActionResult Index() 2         { 3             List<Product> products = new List<Product>(); 4             for (int i = 0; i < 100; i++) 5             { 6                 products.Add(new Product() 7                 { 8                     ID = "000001", 9                     Name = "测试",10                     Description = "测试"11                 });12             }13             return new ExcelResult<Product>(products);14         }
复制代码


上面代码中用到的Product类定义:

复制代码
 1 public class Product 2     { 3         public Product() 4         { 5  6         } 7  8         public string ID { get; set; } 9         public string Name { get; set; }10         public string Description { get; set; }11     }
复制代码


结果导出的Excel文档截图:



最后几句代码有错误,希望请修正,不要误导了后来者:

context.HttpContext.Response.Write(sBuilder);
context.HttpContext.Response.Flush();//少了这一行,太致命了!
context.HttpContext.Response.Close();
context.HttpContext.Response.End();

少了 context.HttpContext.Response.Flush();这一行,太致命,一开始我没注意看,本地调试的时候没有任何问题,但发布到线上,就一直导出Excel不成功。原来是少了这一句代码!


0 0
原创粉丝点击