在项目中我们经常会遇到要求将一些数据导出成Excel或者Word表格的情况,比如中国移动(我是中国移动用户)网上查话费的页面中就有一个导出到Excel的功能,光大网上银行查看历史明细也有这些功能....,原本以为这个问题不难的,不过看到网上经常有朋友问,于是我整理了一下,供大家参考。
前台页面:
<% @ Page Language = " C# " AutoEventWireup = " true " CodeFile = " ExportDemo.aspx.cs " Inherits = " ExportDemo " %>
<! 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 > GridView导出到Excel或Word文件——周公的博客:http://blog.csdn.net </ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< asp:GridView ID ="gvPersonList" runat ="server" AutoGenerateColumns ="False" >
< Columns >
< asp:BoundField DataField ="Id" HeaderText ="编号" />
< asp:BoundField DataField ="Name" HeaderText ="姓名" />
< asp:TemplateField HeaderText ="性别" >
< ItemTemplate >
<% # Eval ( " Sex " ).ToString() == " true " ? " 男 " : " 女 " %>
</ ItemTemplate >
</ asp:TemplateField >
< asp:BoundField DataField ="Age" HeaderText ="年龄" />
< asp:TemplateField HeaderText ="婚否" >
< ItemTemplate >
<% # Boolean .Parse( Eval ( " Married " ).ToString()) == true ? " 是 " : " 否 " %>
</ ItemTemplate >
</ asp:TemplateField >
</ Columns >
</ asp:GridView >
< asp:Button ID ="btnToExcel" runat ="server" OnClick ="btnToExcel_Click" Text ="导出到Excel" />
< asp:Button ID ="btnToWord" runat ="server" OnClick ="btnToWord_Click" Text ="导出到Word" />
</ div >
</ form >
</ body >
</ html > 后台代码:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// 程序说明:这是一个GridView导出成Excel或者Word文件的实例。为了演示,我采用了自动生成DataTable,然后绑定。
/// 同时为了初学者查看代码方便,关键处我都做了注释。
/// 对程序说明,在asp.net 1.1中由于对控件呈现不是很严格,所以无需override void VerifyRenderingInServerForm(Control control)这个方法
/// 但在asp.net2.0中,控件的校验严格了,RenderControl代码只有走正常流程在render方法中它自己调用才能成功,
/// 在你自己写的事件方法中调用就会出现这个错误。这个错误信息有点误导,你明明写在服务器控件Form内,它照样会这样提醒你,
/// 实际上是asp.net2.0设置了内部变量控制RenderControl不允许在Render方法之外被轻易调用。如果不override VerifyRenderingInServerForm
/// 就会报错。我们override void VerifyRenderingInServerForm(Control control)这个方法,里面不写任何代码即可
/// 作者:周公
/// 日期:2008-5-16
/// </summary>
public partial class ExportDemo : System.Web.UI.Page
{
private string firstName = " 赵钱孙李周吴郑王冯陈诸卫蒋沈韩杨朱秦尤许何吕施张孔曹严华 " ;
private string lastName = " 猛勇刚强豹彪雁燕蓉菲 " ;
protected void Page_Load( object sender, EventArgs e)
{
if ( ! Page.IsPostBack)
{
BindGridView();
}
}
private void BindGridView()
{
DataTable myData
= CreateDataTable();
Session[
" MyData " ] = myData;
gvPersonList.DataSource
= myData;
gvPersonList.DataBind();
}
// 手动生成DataTable
private DataTable CreateDataTable()
{
DataTable data
= new DataTable();
DataColumn dcId
= new DataColumn( " ID " , typeof (Int32));
// 设置ID列自动递增
dcId.AutoIncrement = true ;
// 设置ID列初始值为1
dcId.AutoIncrementSeed = 1 ;
// 设置ID列递增步长为1
dcId.AutoIncrementStep = 1 ;
// 将ID列添加到DataTable中
data.Columns.Add(dcId);
data.Columns.Add(
new DataColumn( " Name " , typeof ( string )));
data.Columns.Add(
new DataColumn( " Age " , typeof ( int )));
data.Columns.Add(
new DataColumn( " Sex " , typeof ( bool )));
data.Columns.Add(
new DataColumn( " Married " , typeof ( bool )));
DataRow dataRow
= null ;
Random random
= new Random();
// 随机生成20条记录
for ( int i = 0 ; i < 20 ; i ++ )
{
dataRow
= data.NewRow();
// 随机生成姓名
dataRow[ " Name " ] = firstName.Substring(random.Next(firstName.Length), 1 ) + lastName.Substring(random.Next(lastName.Length), 1 );
// 随即生成介于20至100之间的年龄
int age = random.Next( 20 , 100 );
dataRow[
" Age " ] = age;
// 随即设置性别
bool sex = (random.Next( 100 ) % 2 == 0 ) ? true : false ;
dataRow[
" Sex " ] = sex;
if (((sex == true ) && (age >= 22 )) || ((sex == false ) && (age >= 20 ))) // 男性结婚年龄大于22周岁,女性结婚年龄大于20周岁
{
dataRow[
" Married " ] = (random.Next( 500 ) % 2 == 0 ) ? true : false ;
}
else
{
dataRow[
" Married " ] = false ;
}
data.Rows.Add(dataRow);
}
return data;
}
// override掉这个方法
public override void VerifyRenderingInServerForm(Control control)
{
// 注释掉下面的代码,否则在asp.net2.0下会报错(注:GridView是asp.net 2.0下的控件,1.1下一些控件也可以导出成Excel或者Word)
// base.VerifyRenderingInServerForm(control);
}
protected void btnToExcel_Click( object sender, EventArgs e)
{
Response.Clear();
Response.BufferOutput
= true ;
// 设定输出的字符集
Response.Charset = " GB2312 " ;
// 假定导出的文件名为FileName.xls
Response.AppendHeader( " Content-Disposition " , " attachment;filename=FileName.xls " );
Response.ContentEncoding
= System.Text.Encoding.GetEncoding( " GB2312 " );
// 设置导出文件的格式
Response.ContentType = " application/ms-excel " ;
// 关闭ViewState
EnableViewState = false ;
System.Globalization.CultureInfo cultureInfo
= new System.Globalization.CultureInfo( " ZH-CN " , true );
System.IO.StringWriter stringWriter
= new System.IO.StringWriter(cultureInfo);
System.Web.UI.HtmlTextWriter textWriter
= new System.Web.UI.HtmlTextWriter(stringWriter);
gvPersonList.RenderControl(textWriter);
// 把HTML写回浏览器
Response.Write(stringWriter.ToString());
Response.End();
}
// 导出成Word文件
protected void btnToWord_Click( object sender, EventArgs e)
{
Response.Clear();
Response.BufferOutput
= true ;
// 设定输出的字符集
Response.Charset = " GB2312 " ;
// 假定导出的文件名为FileName.doc
Response.AppendHeader( " Content-Disposition " , " attachment;filename=FileName.doc " );
Response.ContentEncoding
= System.Text.Encoding.GetEncoding( " GB2312 " );
/// /设置导出文件的格式
Response.ContentType = " application/ms-word " ;
// 关闭ViewState
gvPersonList.EnableViewState = false ;
System.Globalization.CultureInfo cultureInfo
= new System.Globalization.CultureInfo( " ZH-CN " , true );
System.IO.StringWriter stringWriter
= new System.IO.StringWriter(cultureInfo);
System.Web.UI.HtmlTextWriter textWriter
= new System.Web.UI.HtmlTextWriter(stringWriter);
gvPersonList.RenderControl(textWriter);
// // 把HTML写回浏览器
Response.Write(stringWriter.ToString());
Response.End();
}
}
运行效果:
需要说明的是:在asp.net2.0环境下,VerifyRenderingInServerForm(Control control)这个方法不override的话,则会出现“错误提示:类型“GridView”的控件“GridView1”必须放在具有 runat=server 的窗体标记内”这个错误。