GridView 导出到 Excel文件

来源:互联网 发布:手机淘宝卖家版下载 编辑:程序博客网 时间:2024/05/18 00:36

  GridView 导出到 Excel文件

    值得注意的是VerifyRenderingInServerForm重载方法:
    MSDN
上的 VerifyRenderingInServerForm 方法的描述:
  必须位于 <form runat=server> 标记中的控件可以在呈现之前调用此方法,以便在控件被置于标记外时显示错误信息。发送回或依赖于注册的脚本块的控件应该在 Control.Render 方法的重写中调用此方法。呈现服务器窗体元素的方式不同的页可以重写此方法以在不同的条件下引发异常。
  如果回发或使用客户端脚本的服务器控件没有包含在 HtmlForm 服务器控件 (<form runat="server">) 标记中,它们将无法正常工作。这些控件可以在呈现时调用该方法,以在它们没有包含在 HtmlForm 控件中时提供明确的错误信息。
  开发自定义服务器控件时,通常在为任何类型的输入标记重写 Render 方法时调用该方法。这在输入控件调用 GetPostBackEventReference 或发出客户端脚本时尤其重要。复合服务器控件不需要作出此调用。

没有这个方法,程序将报错。

<%@ Page Language="C#" EnableEventValidation="false" %>

<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat=
"server">
ICollection CreateDataSource( )
...{
System.Data.DataTable dt =
new System.Data.DataTable();
System.Data.DataRow dr;
dt.Columns.Add(
new System.Data.DataColumn("id", typeof(Int32)));
dt.Columns.Add(
new System.Data.DataColumn("PkID", typeof(string)));
dt.Columns.Add(
new System.Data.DataColumn("Title", typeof(string)));
for (int i = 0; i < 6; i++)
...{
dr = dt.NewRow();
dr[
0] = i;
dr[
1] = "123456789123456789123456789";
dr[
2] = "<a href='http://dotnet.aspx.cc/'>欢迎光临【孟宪会之精彩世界】</a>";
dt.Rows.Add(dr);
}
System.Data.DataView dv =
new System.Data.DataView(dt);
return dv;
}

protected void Page_Load( object sender, EventArgs e )
...{
if (!IsPostBack)
...{
GridView1.BorderWidth = Unit.Pixel(
2);
GridView1.BorderColor = System.Drawing.Color.DarkOrange;
GridView1.DataSource = CreateDataSource();
GridView1.DataBind();
}
}

protected void Button1_Click( object sender, System.EventArgs e )
...{
Response.Clear();
Response.Buffer =
true;
Response.Charset =
"GB2312";
Response.AppendHeader(
"Content-Disposition", "attachment;filename=FileName.xls");
// 如果设置为 GetEncoding("GB2312");导出的文件将会出现乱码!!!
Response.ContentEncoding = System.Text.Encoding.UTF7;
Response.ContentType =
"application/ms-excel";//设置输出文件类型为excel文件。
System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter oHtmlTextWriter =
new System.Web.UI.HtmlTextWriter(oStringWriter);
this.GridView1.RenderControl(oHtmlTextWriter);
Response.Output.Write(oStringWriter.ToString());
Response.Flush();
Response.End();

}
public override void VerifyRenderingInServerForm( Control control )
...{ }
protected void GridView1_RowDataBound( object sender, GridViewRowEventArgs e )
...{
if (e.Row.RowType == DataControlRowType.DataRow)
...{
e.Row.Cells[
1].Attributes.Add("style", "vnd.ms-excel.numberformat:@;");
}
}
</script>

<html xmlns=
"http://www.w3.org/1999/xhtml">
<head runat=
"server">
<title>
GridView 导出到 Excel 文件中</title>
</head>
<body>
<form id=
"form1" runat="server">
<asp:GridView ID=
"GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound"
AutoGenerateColumns=
"false">
<Columns>
<asp:BoundField HeaderText=
"序号" DataField="id" />
<asp:BoundField HeaderText=
"身份证号" DataField="PkID" />
<asp:BoundField HeaderText=
"网址" DataField="Title" ReadOnly="true" HtmlEncode="false" />
</Columns>
</asp:GridView>
<asp:Literal ID=
"HiddenOut" runat="server" />
<asp:Button ID=
"Button1" runat="server" Text="导出" OnClick="Button1_Click" />
</form>
</body>
</html>

Exporting GridView to Excel With Style:
您是否注意到了以上代码存在一些的问题?是的,ID列开头的0都被截去了。如果你的ID000345,导出后就编程了345。这个问题可以通过把css添加到输出流中来解决。为了使ID列正确显示,您需要将其储存为文本格式。Excel中的文本格式表示为"mso-number-format:"/@"

protected void Btn_ExportClick(object sender, EventArgs e)

{

string style = @"<style> .text { mso-number-format:/@; } </script> ";

Response.ClearContent();

Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gvUsers.RenderControl(htw);

// Style is added dynamically

Response.Write(style);

Response.Write(sw.ToString());

Response.End();

}

public override void VerifyRenderingInServerForm(Control control)

{

}

 在上面的代码中,我通过”style”变量来控制GridView列的样式。并通过Respnose.Write方法将其添加到输出流中。最后把样式添加到ID列。这一步需要在RowDataBound事件中完成

protected void gvUsers_RowDataBound(object sender, GridViewRowEventArgs e)

{

if (e.Row.RowType == DataControlRowType.DataRow)

{

    e.Row.Cells[1].Attributes.Add("class", "text");

}

}

 修改的结果如下:

 GridView导出Excel - li_crane - 未来之路(The road ahead)
Exporting GridView With LinkButtons and Paging: 

如果要导出的GridView中包含LinkButton或者分页(出现分页码时,译者注) 则将出现错误:

GridView导出Excel - li_crane - 未来之路(The road ahead)

 

通过修改页文件可以修正这个问题:EnableEventValidation = "false".

<%@ Page Language="C#" EnableEventValidation="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

看一下导出的文件
 GridView导出Excel - li_crane - 未来之路(The road ahead)

在导出的文件中可以看见linkbuttondropdownlist控件,虽然dropdownlist控件显示的数据的确是用户所选的项,但怎么看也不像是一个导出文件(我倒是觉的挺cool的:)译者注),现在应如何移除dropdownlist并显示选择的文字呢?

 
我写了一个DisableControls函数,用使循环的方法将linkbuttondropdownlist替换成literal控件

private void DisableControls(Control gv)

{

LinkButton lb = new LinkButton();

Literal l = new Literal();

string name = String.Empty;

for (int i = 0; i < gv.Controls.Count; i++)

{

if (gv.Controls[i].GetType() == typeof(LinkButton))

{

l.Text = (gv.Controls[i] as LinkButton).Text;

gv.Controls.Remove(gv.Controls[i]);

gv.Controls.AddAt(i, l);

}

else if (gv.Controls[i].GetType() == typeof(DropDownList))

{

l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text;

gv.Controls.Remove(gv.Controls[i]);

gv.Controls.AddAt(i, l);

}

 

if (gv.Controls[i].HasControls())

{

DisableControls(gv.Controls[i]);

}

}

}

方法非常简单,只需将linkbutondropdownlist替换成literal控件,并将选择项赋值给literal控件的文本属性。该方法需要在导出前调用

protected void Btn_ExportExcelPaging(object sender, EventArgs e)

{

DisableControls(gvUsers);

Response.ClearContent();

Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");

Response.ContentType = "application/excel";

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gvUsers.RenderControl(htw);

Response.Write(sw.ToString());

Response.End();

}

 

现在的Excel中就只剩下选中文本了

GridView导出Excel - li_crane - 未来之路(The road ahead)

在实现"GridView中的数据导出到Excel"的时候出现了如下错误情况:

1、用户代码未处理 InvalidOperationException
只能在执行 Render() 的过程中调用 RegisterForEventValidation;

     EnableEventValidation属性是 .NET Framework 2.0 中是新增的属性,默认的情况下该属性的值为true;通过这个新增的功能ASP.NET会检查 POST方法中的所带的参数,如果认为不合法,就会抛出异常。这个设计的目的是为了防止恶意用户利用post 方法发送一些恶意数据,但是有时也会出现类似上面的错误。

只要禁止这个功能,问题就能得到解决。可以通过以下两种途径解决:
1、在
Web.Config文件中:在<system.web></system.web>标记中添加如下代码:
<system.web>
      <pages enableEventValidation="false"> </pages>
 </system.web>
2、在具体的
.aspx页面的源代码中修改代码,如下:
<%@ Page Language="C#" EnableEventValidation="false"
AutoEventWireup="true" CodeFile="GridView_Export_Excel.aspx.cs" Inherits="GridView_Export_Excel" %>

 

2、导出excel时报错,内容如下:

Problem Exporting GridView to Excel.Error Parsing Near <Div>…..

解决方法:

Use

</ContentTemplate>

<Triggers>
<asp:PostBackTrigger ControlID="" />

</Triggers>

</asp:UpdatePanel>

where ControlID="UR UserControl ID"

3、格式问题

1)两位小数:

string style = @"<style> .text { mso-number-format:'0.00'; } </script> ";

2)数字格式

string style = @"<style> .text { mso-number-format:/@; } </script> ";

 

 

参考资料:

当我们把web页面上的数据导成excel形式时,有时候我们的数据需要以特定的格式呈现出来,这时候我们就需要给cell添加一些样式规格信息。

       首先,我们了解一下excelweb页面上导出的原理。当我们把这些数据发送到客户端时,我们想让客户端程序(浏览器)以excel的格式读取它,所以把mime类型设为:application/vnd.ms-excel,当excel读取文件时会以每个cell的格式呈现数据,如果cell没有规定的格式,则excel会以默认的格式去呈现该cell的数据。这样就给我们提供了自定义数据格式的空间,当然我们必须使用excel支持的格式。下面就列出常用的一些格式:

1 文本:vnd.ms-excel.numberformat:@

2 日期:vnd.ms-excel.numberformat:yyyy/mm/dd

3 数字:vnd.ms-excel.numberformat:#,##0.00

4 货币:vnd.ms-excel.numberformat:#,##0.00

5 百分比:vnd.ms-excel.numberformat: #0.00%

这些格式你也可以自定义,比如年月你可以定义为:yy-mm等等。那么知道了这些格式,怎么去把这些格式添加到cell中呢?很简单,我们只需要把样式添加到对应的标签对(即闭合标签)即可。如<td></td>,给标签对<td></td>添加样式,如下:

<td style="vnd.ms-excel.numberformat:@">410522198402161833</td>

 

同样,我们也可以给<div></div>添加样式,也可以给<tr></tr><table></table>添加样式,这样就会引入一个问题,你注意到了吗?先看如下的代码:

<table style=vnd.ms-excel.numberformat:#,##0.00>
    
<tr>
        
<td>542</td>
        
<td style=vnd.ms-excel.numberformat: #0.00%>0.25</td>
    
</tr>
</table>

 

对,当我们在父标签对和子标签对都添加样式时,数据会以哪一个样式呈现呢?经过测试,会以离数据最近的样式呈现,这也是符合我们的意愿的(好像也符合一句俗话:县官不如现管)。这样我们就可以通过改变样式而改变数据在excel中呈现的方式(这些样式规格你可以在前台页面上添加也可以在后台代码里给相应的控件如:DataGrid等添加这些样式)。如果你的应用比较简单,那么这已经足够满足你的需求。但如果你的应用比较复杂,那么你也可以采取一种方式来达到不同的数据呈现效果。下面,我就举一个稍微复杂一点的应用。

       例如:你的数据要呈现给不同国家和地区的用户查看,这样数据的呈现的格式就会不一样,那么我们怎么解决这个问题呢?当然了,你可以手工把这些数据处理好,但这毕竟不是最好的方法,因为如果我们每增加一个其他国家或地区的用户,那么我们就需要把所有的数据以客户要求的格式处理一遍,当数据量很大时,这无疑是一件很沉重且无聊的工作。那么我们究竟应该怎样解决类似这样的问题呢?下面我说一下,我自己的看法:把这些格式化的信息抽取到一个xml文件中,程序运行时根据不同的客户读取不同的格式化信息,然后把这些格式化信息动态的添加到我们的数据上,这样,当我们每增加一个其他国家或地区的用户时,我们只需要多增加一个xml文件,把对应的格式化信息写入这个xml文件,然后当这个国家或地区的用户查看时,就把对应的格式化信息读取出来应用到数据上即可。

       以上这个例子是我突然想到的,相信跨国企业的公司会遇到类似的问题,解决方法只是提供给大家一个思路,希望可以起到抛砖引玉的效果。

 

 

 

导出excel,数字以字符导出

      添加单元格的样式

                e.Row.Cells[i].Attributes.Add("style", "mso-number-format://@;");

这样就可以了 

 

原创粉丝点击