quinta-feira, 26 de março de 2009

Exportar dados de um GridView/DataGrid para excel em .NET



Código para exportação:



private void ExportExcel() {
Response.Clear();
exportando = true;

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

Response.Charset = "";

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Response.ContentType = "application/vnd.xls";

StringWriter stringWrite = new System.IO.StringWriter();

HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
this.EnableViewState = false;
gridview1.RenderControl(htmlWrite);

Response.Write(stringWrite.ToString());

Response.End();
}


Parece bem simples o código, mas em .NET sempre tem um truque para não receber aquela exception linda na tela...


A parte do segredo agora:

public override void VerifyRenderingInServerForm(Control control)
{
if (!exportando)
{
base.VerifyRenderingInServerForm(control);
}
}

Se não for incluido este override na página ocorre a seguinte exception:



Controle 'gridview1' do tipo 'GridView' deve ser inserido em uma marca de formato com runat=server.
Descrição: Ocorreu uma exceção não tratada durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.

Detalhes da Exceção: System.Web.HttpException: Controle 'gridview1' do tipo 'GridView' deve ser inserido em uma marca de formato com runat=server.

Erro de Origem:


Linha 57: HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
Linha 58: this.EnableViewState = false;
Linha 59: gridview1.RenderControl(htmlWrite);
Linha 60:
Linha 61: Response.Write(stringWrite.ToString());


Arquivo de Origem: c:\Inetpub\wwwroot\PublicadorTerraTV\trunk\PublisherWebSite\ExportTree.aspx.cs Linha: 59

Rastreamento de Pilha:


[HttpException (0x80004005): Controle 'gridview1' do tipo 'GridView' deve ser inserido em uma marca de formato com runat=server.]
System.Web.UI.Page.VerifyRenderingInServerForm(Control control) +2049759
System.Web.UI.WebControls.GridView.Render(HtmlTextWriter writer, Boolean renderPanel) +37
System.Web.UI.WebControls.GridView.Render(HtmlTextWriter writer) +30
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
Terra.Publicador.View.ExportTree.ExportExcel() in c:\Inetpub\wwwroot\PublicadorTerraTV\trunk\PublisherWebSite\ExportTree.aspx.cs:59
Terra.Publicador.View.ExportTree.lnkExport_OnClick(Object sender, EventArgs e) in c:\Inetpub\wwwroot\PublicadorTerraTV\trunk\PublisherWebSite\ExportTree.aspx.cs:41
System.Web.UI.WebControls.ImageButton.OnClick(ImageClickEventArgs e) +86
System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument) +115
System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746




--------------------------------------------------------------------------------



É aquele erro que vc pergunta que diabos eu fiz de errado...

5 comentários:

Anônimo disse...

ótimo post, procurei bastante sobre este erro, e apenas sua publicação revela o segredo que estava procurando, obrigado !!!

Anônimo disse...

Consegui resolver este problema adicionando um form da class de exportação, e adicionando o gridview dentro do form. assim não interessa qual a configuração da página de requisição.
Segue exemplo em C#:

//Crio um form que servirá de container para o GridView
HtmlForm frm = new HtmlForm();


//adiciono o HtmlForm à página
pagina.Controls.Add(frm);

//adiciono o GridView no HtmlForm
frm.Controls.Add(grid);

//Renderizo o Conteúdo do HtmlForm, que contém o GridView
frm.RenderControl(hWr);

//mando escrever na tela. Com todos os cabeçalhos setados, é aberto para salvar o XML
pagina.Response.Write(sWr.ToString());

Att. Jaqueline Maria

John disse...

Você sabe como faço para adicionar várias planilhas no mesmo arquivo excel, ou seja, gerar algumas abas na mesma planilha ? Com esse método, consigo gerar somente uma planilha.

Abraço :)

Marcelo disse...

Muito muito obrigado..
os cara da MS nem se preocupam em procurar a solução.. soh dizem q tem q por o runat=server...
e claro, ja esta com runat=server... senao nem rodava a pagina..

parabens brow! e valeu.. consegui exportar! :)

Anônimo disse...

Você é o cara! hheahea

Parabéns pelo artigo ae!

Postar um comentário