错误备忘_ASP.NET_ASP.NET GridView 导出 Excel 时发现的有趣现象
当我还在之前的公司时(那时刚毕业,我在之前的公司干了三年)领导让我能够将 GridView 显示出来的数据导出成 Excel 和 TXT 文件。本来这是一个很简单的功能,但是在实现过程中,还是经历了很多波折,期间还发现了一个很有趣的现象——原来微软的 Word 和 Excel 文件可以识别 HTML 标记。
本文内容
- GridView 导出
- 导出分析
- 多 sheet 的 Excel
- 补充
导出
本文旨在说明微软的 Word 和 Excel 文件可以识别 HTML 标记,它们的内部实现也是使用 HTML 标记。因此,只是简单说明一下。
对于导出时,涉及的一些问题,暂不考虑,如:
- 导出的编码,否则,导出的 Excel 文件会乱码;
- 要重构 VerifyRenderingInServerForm 方法,否则,会出现如下错误信息:
- 导出时的文件名应为 ".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>
运行界面:
图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> </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 打开该文件:
图2 用 Microsoft Excel 打开
注意:
对比代码段1 和 图2。代码段1的最外层是一个 <div>,里边是一个 <table>。这个 HTML 代码让 Microsoft Excel 出来后,就变成了图2。
多 sheet 的 Excel
现在,在这个 Excel 文件里新建一个 sheet。
图3 新建一个名为 "NewMyExcel" sheet
这么看不出什么来,看下你的电脑,Microsoft Excel 竟然为 "MyExcel.xls" 创建了一个文件夹。
图4 Microsoft Excel 为 "MyExcel.xls" 创建了一个文件夹
图5 MyExcel.files 文件夹的内容
补充
当初,我有两方面的导出工作要做。
- 一方面是像系统日志、统计信息等,这样简单导出,只要按本文的 GridView 导出即可。
- 另一方面是业务的导出,需要在服务端进行相当复杂的处理后导出成 Excel 或 文本文件。现在想来,这种情况的导出,导出成 Excel 完全是扯淡,客户完全用不了,这些数据是通过机器采集记录到文本文件,也就是说,每行的每列都有特殊含义(对应数据库某个表的某个字段),用程序搞到数据库的多个表里,导出是想把这些数据恢复成文本文件。
起初,我想用微软的 COM 组件,但是在 Web 系统下,总出现权限问题,服了,领导催得急,我又突然发现这个现象,于是就用程序,直接创建 HTML 标记,导出得了。考虑若是导出超过 6 万行,就用程序创建多个 sheet。
我还没扩展我的程序,就跳槽了……谢天谢地……