ASP.NET MVC 将IList<T>导出Excel文档的泛型类(继承自ActionResult)
最近MVC项目中要使用到Excel导出功能,在网上找了些资料,自己写了一个通用的泛型类(ExcelResult)。因为是直接继承自ActionResult这个抽象类的,所以用起来很方便,在控制器的Action中直接实例化返回即可。本人的代码功底不是很好,写的代码有点烂,希望大伙指正。
废话少说,直接上类完整代码:
View Code
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文档截图:
摘自:iJerome