ASP.NET - Exportando um DataGrid para o Excel


Continuando a nossa saga de interagir com o Excel, ja vimos como podemos importar dados de uma planilha ; neste artigo vamos ver como fazer o caminho de volta para o Excel, ou seja , exportar dados de um datagrid para o Excel.

Neste artigo eu vou usar o Web Matrix e o seu servidor para testar o exemplo que vamos tratar. O exemplo foi testado em uma máquina com Windows XP e a versão do Excel instalada era a Excel 97 SR1 (não riam...)

O objetivo é abrir uma tabela Customers/Clientes do banco de dados Northwind.mdb , exibir os dados em um componente DataGrid e a seguir exportar para um arquivo Excel.

Abra o Web Matrix e crie uma página ASP.NET , eu chamei a página de AspNetExcel.aspx. A seguir salve a página em um diretório virtual.

Na guia Desing do Web Matrix inclua um componente DataGrid que vou chamar apenas dg. Inclua também um TextBox - id=txtNomeArq -e um botão de comando - id=btnExportar. Conforme o layout abaixo:

Como vamos acessar uma base de dados Access usando OleDB serão necessários os seguintes imports:

<%@ Page Language="vb" %>
<%@
import Namespace="System.Data" %>
<%@
import Namespace="System.Data.OleDb" %>

Na guia Code vamos incluir o código no evento Load do formulário conforme abaixo. Este código apenas seleciona os registros da tabela Clientes/Customers e exibe o resultado no DataGrid.

 

    Sub Page_Load(Source as Object, E as EventArgs)
    
            Dim strConn as string = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\teste\Northwind.mdb"
            'seleciona as primeiras 10 linhas da tabela Costumers
            Dim strSql as string = "Select Top 10 * from Clientes"
    
           'cria uma nova conexao OLedb
            Dim con as New OleDbConnection(strConn)
            'cria um dataset
            Dim ds as DataSet=New DataSet()
            'cria um commando usando o DataAdapter
            Dim Cmd as New OleDbDataAdapter(strSql,con)
            'preenche o dataset com os dados da tabela
            Cmd.Fill(ds,"Clientes")
            'exibe os dados no datagrid
            dg.Datasource=ds.Tables("Clientes").DefaultView
            dg.DataBind()
    
    End Sub

Abaixo o resultado da execução do código do evento Load.

A seguir temos o código que será executado quando o evento Click do botão - Exportar para o Excel . for acionado.

( <asp:Button id="btnExportar" onclick="exportar" Runat="server" Text="Exportar para o Excel"></asp:Button>)

Sub exportar(Source as Object, E as EventArgs)
     exportarExcel(dg,txtnomeArq.text)
End Sub

A rotina exportar aciona a rotina exportarExcel() passando como parâmetro o datagrid e o nome do arquivo sem a extensão. Abaixo temos o código da rotina exportarExcel()

            Sub exportarExcel(grid As DataGrid, saveAsFile As String)
    
                 ' O limite de linhas do Excel é  65536
                 If grid.Items.Count.ToString + 1 < 65536 Then
                     HttpContext.Current.Response.Clear()
                     HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
                         HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" & saveAsFile & ".xls")
                     ' Remover caracteres do header - Content-Type
                     HttpContext.Current.Response.Charset = ""
                     ' desabilita o  view state.
                     grid.EnableViewState = False
                     Dim tw As New System.IO.StringWriter()
                     Dim hw As New System.Web.UI.HtmlTextWriter(tw)
                     grid.RenderControl(hw)
                     ' Escrever o html no navegador
                     HttpContext.Current.Response.Write(tw.ToString())
                     ' termina o response
                     HttpContext.Current.Response.End()
                 Else
                     HttpContext.Current.Response.Write("Muitas linhas para exportar para o Exel !!!")
                 End If
    
             End Sub


Após informar o nome do arquivo e clicar no botão - Exportar para o Excel - teremos o seguinte resultado:

1- Uma janela de diálogo  será aberta solicitando a confirmação para Salvar o arquivo

2- Em seguida a janela Salvar como irá solicitar o local onde deseja salvar o arquivo.

O código que vale a pena destacar é o seguinte :

HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" & saveAsFile & ".xls")
 
Neste código a classe HttpContext é usada para definir o tipo de conteúdo da página como sendo :  "application/vnd.ms-excel"
 
Obs: Veja também o artigo - ASP.NET -Persistindo valores entre Web Forms.-  onde usamos a classe HttpContext
 
A propriedade Current da classe HttpContext obtém o objeto HttpContext para a requisição HTTP atual.
 
O método AddHeader inclui um cabeçalho HTTP na saida do stream. Este método é fornecido por questão de compatibilidade com o ASP.
 
No cabeçalho estamos definindo que o arquivo é um anexo e será salvo com a extensão .xls:
"content-disposition", "attachment;filename=" & saveAsFile & ".xls"
 
Após salvar o arquivo se abrirmos o arquivo no Excel iremos obter o seguinte:

que é exatamente o conteúdo do datagrid. Bingo...

Usando a mesma classe poderíamos ter gerado um arquivo no formato do Word usando o seguinte código :

HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ClearContent()
HttpContext.Current.Response.ClearHeaders()
HttpContext.Current.Response.Buffer =true
HttpContext.Current.Response.ContentType="application/msword"
HttpContext.Current.Response.Write("<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">")
'HttpContext.Current.Response.AddHeader("Content-Disposition","attachment;filename=teste_gera.doc")
HttpContext.Current.Response.AddHeader("content-disposition", "inline; filename=ExportaWord.doc")
HttpContext.Current.Response.Charset = "utf-8"
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250")
HttpContext.Current.Response.Write("<font style='font-size:10.0pt; font-family:Verdana;'>")
HttpContext.Current.Response.Write("<BR><BR><BR>")
HttpContext.Current.Response.Write("<Table border='1' bgColor='#ffffff' borderColor='#ffffff' cellSpacing='0' _ 
            cellPadding='0' style='font-size:10.0pt; font-family:Verdana; background:white;border-collapse:collapse;_
            border:none;mso-border-alt:solid white .5pt;mso-border-right-alt:dotted white .5pt; mso-padding-alt:0in _ 
            0in 0in 0in;mso-border-insideh:.5pt dotted white; mso-border-insidev:.5pt dotted white'> <TR> _
            <TD width=300>")
HttpContext.Current.Response.Write("primeira linha da primeira célula de dados")
HttpContext.Current.Response.Write("</Td><TD>")
HttpContext.Current.Response.Write("Primeira linha segunda célula")
HttpContext.Current.Response.Write("</Td></TR><TR><TD width=300>")
HttpContext.Current.Response.Write("segunda linha primeira célula")
HttpContext.Current.Response.Write("</Td><TD>")
HttpContext.Current.Response.Write("segunda linha segunda célula")
HttpContext.Current.Response.Write("</Td></TR></TABLE>")
HttpContext.Current.Response.Write("<BR><BR><BR>")
HttpContext.Current.Response.Write("<U>")
HttpContext.Current.Response.Write("dados sublinhados")
HttpContext.Current.Response.Write("</U>")
HttpContext.Current.Response.Write("<BR><BR><BR>")
HttpContext.Current.Response.Write("<P>")
HttpContext.Current.Response.Write("Parágrafo com linha única. Data de hoje formatada::")
HttpContext.Current.Response.Write(String.Format("{0:d-MMMM-yyyy}", DateTime.Now))
HttpContext.Current.Response.Write("</P>")
HttpContext.Current.Response.Write("</font>")
HttpContext.Current.Response.Flush()
HttpContext.Current.Response.End()

 

Pegue o código completo aqui : AspNetExcel.zip

Eu sei, é só ASP.NET , mas , eu gosto !!!


José Carlos Macoratti