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

最近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不成功。原来是少了这一句代码!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值