zoukankan      html  css  js  c++  java
  • 错误备忘_ASP.NET_ASP.NET GridView 导出 Excel 时发现的有趣现象

    当我还在之前的公司时(那时刚毕业,我在之前的公司干了三年)领导让我能够将 GridView 显示出来的数据导出成 Excel 和 TXT 文件。本来这是一个很简单的功能,但是在实现过程中,还是经历了很多波折,期间还发现了一个很有趣的现象——原来微软的 Word 和 Excel 文件可以识别 HTML 标记。

    本文内容

    • GridView 导出
    • 导出分析
    • 多 sheet 的 Excel
    • 补充

    导出

    本文旨在说明微软的 Word 和 Excel 文件可以识别 HTML 标记,它们的内部实现也是使用 HTML 标记。因此,只是简单说明一下。

    对于导出时,涉及的一些问题,暂不考虑,如:

    • 导出的编码,否则,导出的 Excel 文件会乱码;
    • 要重构 VerifyRenderingInServerForm 方法,否则,会出现如下错误信息:

    1_1R0Y3[@}28GAFQ%NG_GDR

    • 导出时的文件名应为 ".xls",而不能是 ".xlsx",这样,Word 2003 和 2007 都能打开。

    导出 GridView 的数据代码如下:

    <%@ Page Language="C#" %>
     
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.IO" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
     
        <script runat="server">
       1:  
       2:         protected void Page_Load(object sender, EventArgs e)
       3:         {
       4:             if (!IsPostBack)
       5:             {
       6:                 DataTable dt = ExcelCharacteristic.DS.GetDataSource();
       7:                 this.GridView1.DataSource = dt;
       8:                 this.GridView1.DataBind();
       9:             }
      10:         }
      11:         protected void Button1_Click(object sender, EventArgs e)
      12:         {
      13:             Response.ClearContent();
      14:             Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
      15:             Response.AddHeader("content-disposition", "attachment; filename=MyExcel.xls");
      16:             Response.ContentType = "application/excel";
      17:             StringWriter sw = new StringWriter();
      18:             HtmlTextWriter htw = new HtmlTextWriter(sw);
      19:             this.GridView1.RenderControl(htw);
      20:             Response.Write(sw.ToString());
      21:             Response.End();
      22:         }
      23:         /// <summary>
      24:         /// 必须有
      25:         /// </summary>
      26:         /// <param name="control"></param>
      27:         public override void VerifyRenderingInServerForm(Control control)
      28:         {
      29:  
      30:         }
      31:     
    </script>
     
    </head>
    <body>
        <form id="form1" runat="server">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
            <Columns>
                <asp:BoundField DataField="EMPNO" HeaderText="员工编号" />
                <asp:BoundField DataField="ENAME" HeaderText="员工姓名" />
                <asp:BoundField DataField="JOB" HeaderText="职位" />
                <asp:BoundField DataField="MGR" HeaderText="上级编号" />
                <asp:BoundField DataField="HIREDATE" HeaderText="出生日期" />
                <asp:BoundField DataField="SAL" HeaderText="工资" />
                <asp:BoundField DataField="DEPTNO" HeaderText="部门" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="导出" />
        </form>
    </body>
    </html>

    运行界面:

    L$1[1H_T579M]])]K(RCN}G

    图1 运行界面

    说明:

    1,导出的文件为 "MyExcel.xls"。

    导出分析

    当点击“导出”按钮并保存后,用文本编辑器查看导出后的 "MyExcel.xls" 文件,看到的竟然是 HTML 代码。 如下所示:

    <div>
        <table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
            <tr>
                <th scope="col">员工编号</th><th scope="col">员工姓名</th><th scope="col">职位</th><th scope="col">上级编号</th><th scope="col">出生日期</th><th scope="col">工资</th><th scope="col">部门</th>
            </tr><tr>
                <td>7369</td><td>SMITH</td><td>CLERK</td><td>7902</td><td>1980-12-17</td><td>800</td><td>20</td>
            </tr><tr>
                <td>7499</td><td>ALLEN</td><td>SALESMAN</td><td>7698</td><td>1981-02-20</td><td>1600</td><td>30</td>
            </tr><tr>
                <td>7521</td><td>WARD</td><td>SALESMAN</td><td>7698</td><td>1981-02-22</td><td>1250</td><td>30</td>
            </tr><tr>
                <td>7566</td><td>JONES</td><td>MANAGER</td><td>7839</td><td>1981-04-02</td><td>2975</td><td>20</td>
            </tr><tr>
                <td>7654</td><td>MARTIN</td><td>SALESMAN</td><td>7698</td><td>1981-09-28</td><td>1250</td><td>30</td>
            </tr><tr>
                <td>7698</td><td>BLAKE</td><td>MANAGER</td><td>7839</td><td>1981-05-01</td><td>2850</td><td>30</td>
            </tr><tr>
                <td>7782</td><td>CLARK</td><td>MANAGER</td><td>7839</td><td>1981-06-09</td><td>2450</td><td>10</td>
            </tr><tr>
                <td>7788</td><td>SCOTT</td><td>ANALYST</td><td>7566</td><td>1987-04-19</td><td>3000</td><td>20</td>
            </tr><tr>
                <td>7839</td><td>KING</td><td>PRESIDENT</td><td>&nbsp;</td><td>1981-11-17</td><td>5000</td><td>10</td>
            </tr><tr>
                <td>7844</td><td>TURNER</td><td>SALESMAN</td><td>7698</td><td>1981-09-08</td><td>1500</td><td>30</td>
            </tr><tr>
                <td>7876</td><td>ADAMS</td><td>CLERK</td><td>7788</td><td>1987-05-23</td><td>1100</td><td>20</td>
            </tr><tr>
                <td>7900</td><td>JAMES</td><td>CLERK</td><td>7698</td><td>1981-12-03</td><td>950</td><td>30</td>
            </tr><tr>
                <td>7902</td><td>FORD</td><td>ANALYST</td><td>7566</td><td>1981-12-03</td><td>3000</td><td>20</td>
            </tr><tr>
                <td>7934</td><td>MILLER</td><td>CLERK</td><td>7782</td><td>1982-01-23</td><td>1300</td><td>10</td>
            </tr>
        </table>
    </div>

    代码段1 用 文本编辑器打开

    而用 Microsoft Excel 打开该文件:

    用 Microsoft Excel 打开

    图2 用 Microsoft Excel 打开

    注意:

    对比代码段1 和 图2。代码段1的最外层是一个 <div>,里边是一个 <table>。这个 HTML 代码让 Microsoft Excel 出来后,就变成了图2。

    多 sheet 的 Excel

    现在,在这个 Excel 文件里新建一个 sheet。

    新建一个名为 "NewMyExcel" sheet

    图3 新建一个名为 "NewMyExcel" sheet

    这么看不出什么来,看下你的电脑,Microsoft Excel 竟然为 "MyExcel.xls" 创建了一个文件夹。

    Microsoft Excel 为 "MyExcel.xls" 创建了一个文件夹

    图4 Microsoft Excel 为 "MyExcel.xls" 创建了一个文件夹

    MyExcel.files 文件夹的内容

    图5 MyExcel.files 文件夹的内容

    补充

    当初,我有两方面的导出工作要做。

    • 一方面是像系统日志、统计信息等,这样简单导出,只要按本文的 GridView 导出即可。
    • 另一方面是业务的导出,需要在服务端进行相当复杂的处理后导出成 Excel 或 文本文件。现在想来,这种情况的导出,导出成 Excel 完全是扯淡,客户完全用不了,这些数据是通过机器采集记录到文本文件,也就是说,每行的每列都有特殊含义(对应数据库某个表的某个字段),用程序搞到数据库的多个表里,导出是想把这些数据恢复成文本文件。

    起初,我想用微软的 COM 组件,但是在 Web 系统下,总出现权限问题,服了,领导催得急,我又突然发现这个现象,于是就用程序,直接创建 HTML 标记,导出得了。考虑若是导出超过 6 万行,就用程序创建多个 sheet。

    我还没扩展我的程序,就跳槽了……谢天谢地……

    下载 Demo

  • 相关阅读:
    python 代码规范
    Helm 入门指南
    思路和决断
    awk替换第几行第几列的值
    一个awk命令的demo
    装饰模式
    Java多线程Thread.yield(),thread.join(), Thread.sleep(200),Object.wait(),Object.notify(),Object.notifyAll()的区别
    类继承时,构造函数和析构函数的调用次序
    C++中delete和 delete[]的区别
    回溯
  • 原文地址:https://www.cnblogs.com/liuning8023/p/2199038.html
Copyright © 2011-2022 走看看