今日在ASP.NET中使用GridView导出数据至Excel时,分别出现:控件必须放在具有“runat=server”的窗体标记内;只能在执行 Render()的过程中调用 RegisterForEventValidation;导出的内容出现中文乱码几个问题。。。特对此作总结。
ASP.NET中导出Excel的几个问题
1.控件必须放在具有“runat=server”的窗体标记内
ASP.Net的页面中的一个GridView需要把数据导出到Excel,从网上找了一段代码,整理后,写成一个类,供自己调用:
Code
/// <summary>
/// 2008-09-03
/// 导出报表数据存入word或execl文件
/// </summary>
public class clsExportData
{
#region 构造函数
public clsExportData()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#endregion
#region 导出页面或web控件方法
/// <summary>
/// 将Web控件或页面信息导出(不带文件名参数)
/// </summary>
/// <param name="source">控件实例</param>
/// <param name="DocumentType">导出类型:Excel或Word</param>
public void ExportControl(System.Web.UI.Control source, string DocumentType)
{
//设置Http的头信息,编码格式
if (DocumentType == "Excel")
{
//Excel
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode("下载文件.xls", System.Text.Encoding.UTF8));
HttpContext.Current.Response.ContentType = "application/ms-excel";
}
else if (DocumentType == "Word")
{
//Word
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode("下载文件.doc", System.Text.Encoding.UTF8));
HttpContext.Current.Response.ContentType = "application/ms-word";
}
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
//关闭控件的视图状态
source.Page.EnableViewState = false;
//初始化HtmlWriter
System.IO.StringWriter writer = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(writer);
source.RenderControl(htmlWriter);
//输出
HttpContext.Current.Response.Write(writer.ToString());
HttpContext.Current.Response.End();
}
/// <summary>
/// Web控件或页面信息导出(带文件名参数)
/// </summary>
/// <param name="source">控件实例</param>
/// <param name="DocumentType">导出类型:Excel或Word</param>
/// <param name="filename">保存文件名</param>
public void ExportControl(System.Web.UI.Control source, string DocumentType, string filename)
{
//设置Http的头信息,编码格式
if (DocumentType == "Excel")
{
//Excel
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename + ".xls", System.Text.Encoding.UTF8));
HttpContext.Current.Response.ContentType = "application/ms-excel";
}
else if (DocumentType == "Word")
{
//Word
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(filename + ".doc", System.Text.Encoding.UTF8));
HttpContext.Current.Response.ContentType = "application/ms-word";
}
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
//关闭控件的视图状态
source.Page.EnableViewState = false;
//初始化HtmlWriter
System.IO.StringWriter writer = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(writer);
source.RenderControl(htmlWriter);
//输出
HttpContext.Current.Response.Write(writer.ToString());
HttpContext.Current.Response.End();
}
#endregion
#region 调用说明
//方法ExportControl(System.Web.UI.Control source, string DocumentType,string filename)中
//第一个参数source表示导出的页面或控件名,当为datagrid或dataList控件时,在导出Excel/word文件时,必须把控件的分页、排序等属性去除并重新绑定,
//第二个参数DocumentType表示导出的文件类型word或excel
//第三个参数filename表示需要导出的文件所取的文件名
//调用方法:
//clsExportData export=new clsExportData();
//export.ExportControl(this, "Word","testfilename");//当为this时表示当前页面
//这是将整个页面导出为Word,并命名为testfilename
#endregion
}
客户代码:
clsExportData export = new clsExportData();
protected void btnToExcel_Click(object sender, EventArgs e)
{
export.ExportControl(gvTraceList, "Excel");
}
上述代码中有利用GridView控件的RenderControl()来输出数据,可是在运行的时候却遇到了类型“GridView”的控件“gvTraceList”必须放在具有 runat=server 的窗体标记内。的错误。看了HTML代码后,发现<form>标签是有runat="server"标记的(况且没有的话,其他地方也会报错的),于是上网搜了搜解决办法,发现别人也有此错误:
解决办法:在页面中重写Page基类的VerifyRenderingInServerForm方法
public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for
}
上面问题解决了之后,运行了一下,发现另一个问题有出现了,如下:
2.只能在执行 Render()的过程中调用 RegisterForEventValidation
继续上网找,答案:
当用GridView导出Execl的时候,会发生只能在执行Render()的过程中调用RegisterForEventValidation的错误提示。
有两种方法可以解决以上问题:
(1)修改web.config(不推荐)<pages enableEventValidation ="false" ></pages>
(2)直接在导出Execl的页面修改,加上EnableEventValidation = "false"属性
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="frmFormTrace.aspx.cs"
Inherits="frmFormTrace" EnableEventValidation = "false"%>
最后,运行没有问题了,但是。。。。
3.Excel中的中文数据为乱码
试了好多方法后,终于显示出中文来了(我的Excel版本是2003的,不知其他版本的是否有问题)
//HttpContext.Current.Response.Charset = "UTF-8";
//HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
//用下面的这语句代替上面两句,可避免Excel/Word内容出现乱码问题
HttpContext.Current.Response.Write("<meta http-equiv=Content-Type content=text/html;charset=UTF-8>");
出现的问题暂时都解决了,补充一点,上述语句中有运用到设计模式的装饰模式。。。
//初始化HtmlWriter
System.IO.StringWriter writer = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(writer);
source.RenderControl(htmlWriter);