摘要:咳咳~入园快两年,工作也快将近两年了,这才打算写自己在园中的第一篇文章,主要因为之前只是小白一个,肚子里没有什么墨水,现如今,也喝了些许墨水~当然墨水来源也是受益于广大程序猿们的技术分享,感谢,共同进步!

  好了,废话不多说,直接切入今天要分享的主题。

主题:.net中数据集合导出为Excel

背景:如今越来越多的公司开始注重了大数据,公司开始通过数据来分析用户的行为习惯或者某些产品给公司带来的利害,总之这些数据都可以很好的帮助公司做的更好,了解自身的优缺点从而更好的为用户服务获取更大的利益。既然公司明确了方向要做数据,那么这些数据必然需要展示给人们来看,来做数据分析。当然,这些数据仅仅是在页面上显示出来,并不能满足每个想看数据的人,他们都想根据自己的理解使用这些数据来做自己的分析。当然现在最流行的他们都想使用Excel来处理这些数据,所以我们就需要将这些数据导出到Excel中去,来满足众多的用户群体。

内容:因为俺是做.net开发的猿人,所以在这里只分析.net中如何将数据导出Excel文档了。

  首先,我们既然做数据,数据来源必然很多,那么很多地方都需要做数据导出。为了代码的通用性,我们就需要定义一个通用的类DataExportHelper.cs 代码如下:

  public class DataExportHelper
    {     
        /// <summary>
        /// 导出EXCEL
        /// </summary>
        /// <typeparam name="T">集合类型</typeparam>
        /// <param name="data">数据集合</param>
        /// <param name="exportFileName">要显示的列名(类字段名)</param>
        /// <param name="columnNames"></param>
        public static void ExcelExport<T>(List<T> data, string exportFileName, List<string> columnNames)
        {
            StringWriter sw = GetStringWriter(data,columnNames);
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
            string fileName = exportFileName;
            //判断浏览器如果是IE则对文件名进行URL编码处理
            string ua = HttpContext.Current.Request.UserAgent;
            if (!string.IsNullOrEmpty(ua))
            {
                if (ua.ToLower().IndexOf("msie", System.StringComparison.Ordinal)>=0)
                {
                    fileName = HttpUtility.UrlEncode(exportFileName, Encoding.UTF8);
                }
            }

            
            string str = "attachment;filename= " + fileName + ".xls ";
            HttpContext.Current.Response.AppendHeader("Content-Disposition", str);
            HttpContext.Current.Response.ContentType = "application/ms-excel";
            HttpContext.Current.Response.Write(sw);
            HttpContext.Current.Response.End();
        }

        /// <summary>
        /// 数据字串拼接  
        /// </summary>
        /// <typeparam name="T">集合类型</typeparam>
        /// <param name="data">数据集合</param>
        /// <param name="columnNames">要显示的列名(类字段名)</param>
        /// <returns></returns>
        public static StringWriter GetStringWriter<T>(List<T> data,List<string> columnNames )
        {
            StringWriter sw = new StringWriter();

            var type = typeof(T);
            var properties = type.GetProperties();
            if (columnNames!=null&&columnNames.Count > 0)
            {
               // properties = properties.Where(t => columnNames.Contains(t.Name)).ToArray();
                //为了与指定字段顺序一致,才如此循环
                PropertyInfo[] property=new PropertyInfo[columnNames.Count];
                for (int i = 0; i < columnNames.Count; i++)
                {
                    property[i] = properties.FirstOrDefault(t => t.Name == columnNames[i]);
                }
                properties = property;
            }
            sw.Write(sw.NewLine);
            if (data != null)
            {
                //添加列名:
                var colName = "";
                foreach (var property in properties)
                {
                    colName = property.Name;
                    if (property.CustomAttributes.LongCount() >0)
                    {
                       colName = property.CustomAttributes.First().ConstructorArguments.First().Value.ToString();
                    }
                    sw.Write(colName + "\t");
                }
                sw.Write(sw.NewLine);

                foreach (var row in data)
                {
                    foreach (var property in properties)
                        sw.Write(property.GetValue(row, null) + "\t");

                    sw.Write(sw.NewLine);
                }
            }
            sw.Close();
            return sw;
        }
 
    }

必要的注释代码中都有了,这里就不过多叙述了,从上面代码中我们可以看到这个方法转换出来的并不是真的Excel文件,只是采用字符串换行分割的方式来让Excel程序识别成表格的格式。

缺点是:不能设置复杂的样式,每次下载后打开文件可能都会提示“不是有效的Excel文件,是否继续打开?”之类的提示,你只要点是就可以了。当然打开文件后你另存为标准的Excel文件就成为真正的Excel文件了,所以这点可以接受的。

优点是:这种导出方式只是通过拼接字符串来合成的内容,所以执行效率上相对导出到标准的Excel文件的效率要提高很多,而且没有设置格式功能也没有大的影响,因为每个业务人员都想按照自己的想法去编辑表格的样式。

调用方式:

      protected void CreateExecl(int classId)
        {
            StudentManager marager = new StudentManager();
            List<StudentModel> list = marager.StudentList(classId);
            string fileName = "XX班学生数据";
            var listfiled = new List<string>
            {
                "Id",
                "Name",
                "Birthday"
            };
            DataExportHelper.ExcelExport(list, fileName, listfiled);
        }

数据导出后表格列显示的顺序由listfiled集合中值的顺序来决定的,集合中的值都是传入的数据集合StudentModel类中的字段。导出数据支持泛型,请注意,要显示的字段集合必须是传入数据类型中有的字段。

接下来我们看下如果我们想让导出的表格每列的标题显示出对应的中文描述应该如何做?下面是StudentModel的定义。

public class StudentModel
    {
        [Description("学号")]
        public DateTime Id { get; set; }

        [Description("姓名")]
        public double Name { get; set; }

         [Description("生日")]
        public double Birthday { get; set; }
    }

从上面代码中可以看出导出的中文标题是根据字段的Description属性来获取的。

以上就是简单的数据导出方法。如有此文有错误的地方,或者大侠们有更好的解决方法,欢迎指正和指导~

注:如有转载或引用请注明出处 http://www.cnblogs.com/sev7en/p/4021994.html ~

posted on 2014-10-13 12:58  Sev7en  阅读(676)  评论(0编辑  收藏  举报