前几天要在后台查询数据库内容(用entity framework),将查询出来的信息(List或DataTable形式)转成EXCEL供用户下载。经过谷歌、百度搜索,终于搜出了一些代码。似乎可用了,结果问题一大堆。

/// <summary>
    /// 下载EXCEL
    /// </summary>
    /// <param name="dt">数据</param>
    /// <param name="fileName">下载的EXCEL文件名</param>
    public static void OutputToExcelGB2312(object dt, string fileName)
    {
        if (dt != null)
        {
            // 获取当前会话,并设置当前会话中Response的相关属性,让输出内容输出到文件中。
            System.Web.HttpContext curContext = System.Web.HttpContext.Current;
            curContext.Response.Charset = "GB2312";
            curContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
            curContext.Response.AddHeader("content-disposition", "attachment;filename="
             + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8) + ".xls");
            curContext.Response.ContentType = "application/ms-excel";

            //将要导出的数据绑定到DataGrid控件上
            System.Web.UI.WebControls.DataGrid dgExport = new System.Web.UI.WebControls.DataGrid();
            dgExport.DataSource = dt;
            dgExport.AllowPaging = false;
            dgExport.DataBind();
            //创建输出流用来保存输出内容
            System.IO.StringWriter strWriter = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(strWriter);

            //将DataGrid控件的内容输出到流中。
            dgExport.RenderControl(htmlWriter);

            curContext.Response.Write(strWriter.ToString());
            curContext.Response.End();
        }
    }

参数为DataTable形式的数据和str文件名。这个函数主要意思是利用dataGrid这类控件生成行列信息,最终转至EXCEL类型。

但这个函数通用性不好,因为我用entity framework或者LINQ查出来的数据大多是List或IEnumable泛型形式的,不便转换成DataTable形式(其实可以转,就是定义个DataTable dt;添加列名,最后定义行并填充数据,最后提交dt即可),是在麻烦,特别是列数据一多,代码杂糅,很是不爽。

我想, dataGrid这类控件不是有根据数据源自动生成列及填充数据项的功能吗?!那我就不用手动做DataTable定义列并赋值行了,让dataGrid自动生成吧!

MSDN上关于DataGrid或GridView这类控件的DataSource属性是这么说明的:

“使用 DataSource 属性指定要绑定到数据列表控件的值的源。 数据源必须是实现 System.Collections .IEnumerable 接口(例如 System.Data .DataViewSystem.Collections .ArrayListSystem.Collections .Hashtable)或 IListSource 接口的对象,才能绑定到从 BaseDataList 类派生的控件。 在设置 DataSource

必须手动编写代码才能执行数据绑定。”

也就是说,只要数据源(object形式)支持IEnumerable迭代,那控件就可以根据数据源自动生成列、填充行数据等。既然如此,我用entity framework或者LINQ查出的List或IEnumable泛型形式的数据当然可以生成啦!

下面把上述方法稍改造下,使之可以支持任意IEnumable接口的数据源:

  /// <summary>
     /// 下载EXCEL
     /// </summary>
     /// <param name="dt">数据</param>
     /// <param name="fileName">下载的EXCEL文件名</param>
     public static void OutputToExcelGB2312(object dt, string fileName)
     {
         if (dt != null)
         {
             // 获取当前会话,并设置当前会话中Response的相关属性,让输出内容输出到文件中。
             System.Web.HttpContext curContext = System.Web.HttpContext.Current;
             curContext.Response.Charset = "GB2312";
             curContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
             curContext.Response.AddHeader("content-disposition", "attachment;filename="
              + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8) + ".xls");
             curContext.Response.ContentType = "application/ms-excel";

             //将要导出的数据绑定到DataGrid控件上
             System.Web.UI.WebControls.DataGrid dgExport = new System.Web.UI.WebControls.DataGrid();
             dgExport.DataSource = dt;
             dgExport.AllowPaging = false;
             dgExport.DataBind();
             //创建输出流用来保存输出内容
             System.IO.StringWriter strWriter = new System.IO.StringWriter();
             System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(strWriter);

             //将DataGrid控件的内容输出到流中。
             dgExport.RenderControl(htmlWriter);

             curContext.Response.Write(strWriter.ToString());
             curContext.Response.End();
         }
     }

这样一些,清爽多了。

写个例子吧,各位如果有幸看到这些代码,算是抛砖引玉,给予启发了。

1.新建ASP.NET项目。加个窗体,在后台写代码,为了方便就在Page_Load()方法里写代码了。

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;
 using System.Web.UI;
 using System.Web.UI.WebControls;
 public class Info
 {
     public int a { get; set; }
     public Nullable<int> b { get; set; }

 }
 public partial class ExcelTest : System.Web.UI.Page
 {
     protected void Page_Load(object sender, EventArgs e)
     {
         Info i = , b =  };
         Info j = , b =  };
         List<Info> l = new List<Info>() { i, j };
         OutputToExcelGB2312(l, "test");

         //DataGrid1.DataSource = l;
         //DataGrid1.DataBind();
     }
 }

浏览运行,跳出下载对话框,下载EXCEL。以为大功告成,结果:

见鬼!!!!!只有只有列a,列b哪去了?!!!

多次调试,确认问题在OutputToExcelGB2312()方法里:

         System.Web.UI.WebControls.DataGrid dgExport = new System.Web.UI.WebControls.DataGrid();
             dgExport.DataSource = dt;
             dgExport.AllowPaging = false;
             dgExport.DataBind();  //查看属性的值,这时自动生成的列数是1,及 a,没有b.

我当时一时难理解,为什么?!突然瞥见我查数据库信息是有的信息是int?及Nullable<int>类型的。这ORM关系(entity framework,linq)很常见,因为数据库里有些字段是可以为空的,这些字段ORM转换后就成为了Nullable<T>类型。

在这个例子里就是数据项类型是:

public Nullable<int> b { get; set; }

难道是dataGrid不识别Nullable<int>?!果断换个声明public int b { get; set; }就这样,问题解决了。。。。

不过,我依然只知大概,不知为什么(内部绑定原理比较复杂).应该有反射、动态绑定、IEnumable、数据项生成等知识吧。大家可以百度谷歌下,例如以下资料:http://kb.cnblogs.com/kb/70077/

个人理解dataGrid是.NET1.0就有的东西,那时Nullable类型还没有出现,所以可能不认识(dadaGrid向后兼容有点问题吧)基于此,我想到还有另外一种方法,在OutputToExcelGB2312()中将dataGrid改成GridView,这样Gridview就认识Nullable类型,当然就可以实现了(但是Gridview会对bool等类型转换,成为checkBox类型。)有点自作主张了,最后转化为EXCEL时里面就会存在checkBox,原数据为true则打钩,false则不打勾。

.NET细节隐藏的太好,新手入门很简单,拖拖控件即可。但开源的东西较少,有时用的多了真是迷糊了,不知内部到底怎么实现的,结果错漏摆出。哎!!看来要好好学习了,适当研究研究内部源码。包括C#,CLR,IL等东西了,只有这样才能抓住本质,深刻理会;同时不易犯错,程序才能高效稳定,程序员也能省省心,提高效率!
												





											

ASP.NET网页生成EXCEL并下载(利用DataGrid或GridView等)的更多相关文章

  1. Asp.net MVC 简单实现生成Excel并下载

    由于项目上的需求,需要导出指定条件的Excel文件.经过一翻折腾终于实现了. 现在把代码贴出来分享 (直接把我们项目里面的一部份辅助类的代码分享一下) 我们项目使用的是Asp.Net MVC4.0模式 ...

  2. 使用node.js生成excel报表下载(excel-export express篇)

    引言:日常工作中已经有许多应用功能块使用了nodejs作为web服务器,而生成报表下载也是我们在传统应用. java中提供了2套类库实现(jxl 和POI),.NET 作为微软的亲儿子更加不用说,各种 ...

  3. asp.net+nopi生成Excel遇到设置单元格值null问题

    Npoi 生成excel报表功能很不错,功能也不用给大家介绍了.首先看遇到的问题吧! FileStream file = new FileStream(Server.MapPath("Tem ...

  4. java动态生成excel打包下载

    @SuppressWarnings("unchecked") public String batchExport() throws DBException{ @SuppressWa ...

  5. Asp.net MVC 生成zip并下载

    前面有生成Excel或Word的示例,所以就不再重新写了. 这里只提供将指定文件以ZIP的方式下载. 创建一个 Zip工具类 public class ZIPCompressUtil { public ...

  6. phpexcel生成excel并下载

    Loader::import('PHPExcel.Classes.PHPExcel'); // tp5中只需将phpexcel文件放入extend文件夹中,即可采用该方法引入,需要先 use thin ...

  7. asp.net 生成 excel导出保存时, 解决迅雷下载aspx页面问题

    网络上搜索,一大堆废话,以下为简单的导出生成Excel代码: string excelFile = Server.MapPath("~/SB/UpFile/20151104111008/Bo ...

  8. JAVA利用JXL导出/生成 EXCEL

    /** * 导出导出采暖市场部收入.成本.利润明细表 * @author JIA-G-Y */ public String exporExcel(String str) { String str=Se ...

  9. .net生成Excel,并下载

    生成Excel的方式有很多种,这里记录两个最简单的: 1.将数据保存为html,然后输出到客户端,保存为Excel文件: 2.通过\t\n生成字符串,然后输出到客户端,保存为Excel. 以上两者的原 ...

随机推荐

  1. Awesome

    DotNet 资源大全中文版(Awesome最新版) http://www.cnblogs.com/best/p/5876596.html Java资源大全中文版(Awesome最新版) http:/ ...

  2. Android first--SharedPreferences

    public class MainActivity extends Activity { private EditText et_name;    private EditText et_pass; ...

  3. .net平台下获取高精度时间类

    原文:http://www.it118.org/specials/321869dd-98cb-431b-b6d2-82d973cd739d/d940a15c-0d36-4369-8de0-b07cf3 ...

  4. python pep8

    有这个自动的规范检查工具 pip install pep8 具体使用不说了 ==. 百度一堆  http://blog.sae.sina.com.cn/archives/4781  看这里

  5. android_view自定义中的几个方法

    1.onDraw ,改变View绘制的图像 2.onMeasure,改变View的大小 3.onLayout,改变View在父控件的位置

  6. jquery json ajax -2

    如果使用的是虚拟空间, 那么你不能操纵/配置服务器上的php.ini配置文件 但是可以在自己的php文件中, 通过ini_set(...), 和一些对应的函数, 去重置(临时的,仅在当前文件中生效的) ...

  7. 封装application类

    <?php  //判断用户是否是通过入口文件访问   if(!defined('ACCESS')){     echo '非法请求';     die;   }   //封装初始化类   cla ...

  8. JavaScript中对于闭包的理解

    1.什么是闭包? 闭包,官方对闭包的解释是:一个拥有很多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 闭包的特点: (1).作为一个函数变量的一个引用,当函 ...

  9. (C/C++ )Interview in English - Virtual

    Q: What is virtual function?A: A virtual function or virtual method is a function or method whose be ...

  10. Python内置数据类型之List篇

    List的定义: li = ["one" , "two" , "three" , "four"] List是一个有序的集 ...