Desenvolvimento - ASP. NET

ASP.NET: Como gerar arquivos a partir dos componentes DataTable e DataGrid

Este artigo tem como objetivo mostrar como é possível gerar relatórios para todas as versões do Office através do código C#.

por Artur Caliendo Prado



Introdução

Mostrar como é possível gerar relatórios para todas as versões do Office através do código C#. Para isso, implementaremos uma classe que transforma strings, DataTables e DataGrids em dados aceitos pelos formatos XLS, DOC e HTML

Implementação

Antes de começar é importante entender como o arquivo será gerado. Tudo o que faremos é criar um HTML, e colocar o cabeçalho adequado em seu content. Os componentes gráficos, como o DataGrid, possuem um método de Render, que irá criar automaticamente o código de que precisamos. Esta classe irá fornecer recursos para aplicações ASP.NET. Vamos chamá-la de Transforma.

1) Crie uma biblioteca de classes, e adicione a classe Transforma no projeto

2) Crie os atributos:

private HtmlTextWriter write;
private StringWriter strWrite;
private string fileName = "Sem_nome";
private string fileExtension = ".html";
private System.Text.Encoding encoding = System.Text.Encoding.Unicode;

Os dois primeiros atributos irão ser responsáveis por escrever no HttpResponse, para geração de nosso arquivo final. O nome do arquivo e a extensão servem para que seja possível escolher o arquivo de saída. Adicione também o atributo de encoding, porque, com o padrão unicode, não é possível exibir acentos.

Cuidado: alguns encoding podem impedir que a saída em HTML, seja feita da maneira correta. Se sua intenção for gerar um HTML, é recomendável que mantenha o encoding padrão.

3) Crie as propriedades para acessar os atributos. Trate a extensão para que somente as extensões .doc, .xls e .HTML sejam aceitas. Os dois primeiros atributos não precisam ter propriedades.

4) No construtor, inicie os atributos write e strWrite, com o seguinte código:

this.strWrite = new StringWriter();
this.write = new HtmlTextWriter(this.strWrite);

5) Vamos primeiro criar os métodos que geram o código HTML, a partir de strings, DataTables e DataGrids.

Para strings, ela já deve vir com tags HTML, então basta escrevermos no HtmlTextWriter:

public void _Add(string codigo)
{
    this.write.WriteLine(codigo);
}

Para DataGrids, devemos “renderizar” o componente, das seguinte maneira:

public void _Add(DataGrid dg)
{
    dg.RenderControl(this.write);
}

E, concluindo, o DataTable:

public void _Add(DataTable dt)
{
    DataGrid dg = new DataGrid();
    dg.DataSource = dt;
    dg.DataBind();
    this._Add(dg);
}

Neste método apenas criamos um DataGrid e adicionamos o DataTable como sua fonte de dados.

Agora faltam apenas duas etapas: gerar o cabeçalho dos arquivos e criar realmente o documento. Vamos começar criando o arquivo, e depois criaremos o método que coloca o cabeçalho. Vamos chamar o método que insere os cabeçalhos de content, e o método de gerar o arquivo, generate. Crie um método público sem parâmetros, com o nome de generate. Ele deve primeiro capturar o response da página WEB atual.

HttpResponse response = System.Web.HttpContext.Current.Response;

Agora, vamos limpar o Response, e alterá-lo para que imprima o que desejarmos. Coloque também um cabeçalho que contenha o nome do arquivo e sua extensão, como mostrado abaixo.

response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename="+this.fileName+this.fileExtension);

Mude o Encoding para o encoding da classe.

response.ContentEncoding = this._Encoding;

Aqui colocaremos o cabeçalho. Mais adiante explicaremos o método content. Apenas preste atenção que estamos passando o nosso HttpResponse como parâmetro.

content(response);

E, finalmente, geramos a saída e terminamos o método.

response.Write(strWrite.ToString());
response.End();

Agora que está claro como fazer para gerar os arquivos, vamos colocar o cabeçalho adequado. Sabemos que os cabeçalhos que utilizaremos são:

- Word: application/msword
- Excel: application/vnd.ms-excel
- HTML: text/html

O método que chamamos de content vai usar o HttpResponse, passado por parâmetro, para adicionar um dos três cabeçalhos. Então, basta utilizar uma estrutura como esta:

private void content(HttpResponse response)
{
    if (this._FileExtension == ".XLS")
        response.ContentType = "application/vnd.ms-excel";
    else if (this._FileExtension == ".DOC")
        response.ContentType = "application/msword";
    else if (this._FileExtension == ".HTML")
        response.ContentType = "text/html";
}

Assim, em nossa aplicação ASP.NET podemos instanciar a classe Transforma e adicionar os códigos ou componentes desejados através dos métodos “_Add”. É possível mudar os atributos de um DataGrid antes de adicioná-los ao Response, tornando possível gerar relatórios ricos, coloridos e fáceis de usar.

Com esta aplicação, podemos buscar dados da tabelas, no banco de dados, e gerar uma planilha ou um documento do Word. Podemos também colocar um DataGrid em nossa aplicação, adicionar colunas (incluindo templates) e criar tabelas em seus relatórios com links, as cores escolhidas para seu DataGrid e todos os dados que você precisar. Para exemplificar como utilizar a classe Transforma, vamos configurar um DataGrid com vários componentes diferentes.

Como utilizar

O primeiro passo é criar uma aplicação WEB. No formulário da aplicação, adicione um DataGrid, arrastando-o do Toolbox. Chame-o de dgDados. Agora, clicando com o botão direito do mouse sobre ele, vamos escolher a opção Auto-format.

Escolha o layout que mais lhe agradar. Agora, clicando novamente com o botão direito do mouse sobre o DataGrid, escolha a opção Property Builder. Na guia Columns, desmarque a opção “Create columns automatically at run time”. Adicione duas colunas do tipo Template column, e, se tiver um banco de dados para testar, coloque uma Bound Column para mostrar algum dado de suas tabelas. No Nosso exemplo, usaremos um campo chamado conteúdo. Edite os templates clicando com o botão direito do mouse sobre o DataGrid e escolhendo a coluna desejada. Em item template, coloque um Hyperlink, na primeira coluna, e um Image, na segunda.

Neste exemplo, nosso link apontará para www.ltia.fc.unesp.br/fellowship, e nossa imagem será a seguinte: . Coloque a imagem que desejar, mas coloque imagens pequenas. Para preencher a coluna conteúdo, no property builder, colocaremos seu Header e seu Data Field como Conteudo (nome da coluna do banco de dados).

Temos o seguinte DataGrid:

No Page Load, vamos inserir o código que irá transformar este DataGrid em um arquivo do Excel, chamado Teste.xls. Observe o código abaixo:

Transforma file = new Transforma();
DataSet ds = new DataSet();
ds = this.buscaDados();

O método busca dados faz acesso ao banco de dados e traz para o DataSet alguns dados, por exemplo o campo Conteudo, que vamos utilizar.

dgDados.DataSource = ds.Tables[0];
dgDados.DataBind();

//escolhendo o nome do arquivo
file._FileName = "TESTE";
//escolhendo a extensão do arquivo
file._FileExtension = ".xls";
//utilizaremos o encoding ASCII
file._Encoding = System.Text.Encoding.ASCII;
//Adicionamos à nossa classe transforma o DataGrid
file._Add(dgDados);
//Geramos o arquivo TESTE.xls
file._GenerateForDownload();

Neste exemplo ainda associamos ao DataGrid o evento ItemDataBound, e, se o conteúdo fosse igual a 100, ficaria azul, se fosse igual a zero, vermelho, e preto, caso contrário.

O resultado obtido no Excel é o seguinte:

Com a extensão .DOC a saída ficou assim:

Aviso: Cuidado ao inserir strings com HTML pelo método _Add da classe Transforma. Algumas propriedades, como o colspan das tabelas, podem não funcionar corretamente no Word, uma vez que ele não possui colunas como o Excel.

Artur Caliendo Prado

Artur Caliendo Prado - Membro da célula acadêmica Fellowship .net. Trabalha com .NET desde junho de 2003. Participou do Imagine Cup 2004, e sua equipe conseguiu o terceiro lugar na etapa brasileira. Participou do projeto Assignment Manager, da Microsoft, pela Unesp de Bauru, como coordenador da equipe de desenvolvimento. Atualmente trabalha com desenvolvimento de software em ASP.NET, além de realizar palestras sobre a plataforma .NET.