RSS

ASP.NET MVC – Exportando dados para planilha Excel

07 nov

Neste post irei demonstrar como uma aplicação ASP.NET MVC pode exportar dados para uma planilha Excel. Iremos obter os dados que estão em uma tabela de usuários, podendo assim ainda, definir quais colunas desejamos exportar.

Importante: Atente-se que, não será explicado o fluxo de ação de uma aplicação MVC, portanto, espera-se o conhecimento básico para a criação e entendimento de uma aplicação deste tipo.

Criando a estrutura do projeto e o banco

Com o Visual Studio 2010 aberto, vamos iniciar criando um projeto do tipo ASP.NET MVC 2 Web Application com o nome de ExportacaoExcel. Podemos também criar um DB no SQL Server com o nome de sua preferência, dentro do DB criamos uma tabela de Usuários com a seguinte estrutura:

CREATE TABLE [dbo].[tbUsuarios]

(

[codUsuario] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,

[nome] [varchar](200) NULL,

[idade] [int] NULL,

[codContato] [int] NULL,

[dataCadastro] [datetime] NULL,

[login] [varchar](100) NULL,

[senha] [varchar](100) NULL,

[ativo] [bit] NULL,

[observacao] [varchar](max) NULL

)

No diretório Model do projeto vamos criar um novo item do tipo LINQ to SQL Classes com o nome de DB.dbml. Com o mesmo aberto, arrastamos a tabela criada anteriormente para dentro do mesmo e a renomeamos para Usuario.

Agora sim, mão a obra

Na Master Page vamos adicionar a referencia ao jQuery conforme o código abaixo:


<head runat="server">

<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />

<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

<asp:ContentPlaceHolder ID="HeadContent" runat="server" />

</head>

Agora vamos adicionar um botão na View Index.aspx:

<input type="button" id="btnExportar" value="Exportar Usuários" />

E o evento referente ao click do botão:

<asp:Content ID="Content3" ContentPlaceHolderID="HeadContent" runat="server">

<script type="text/javascript">

$(document).ready(function () {

$("#btnExportar").click(function () {

var campos = "codUsuario,nome";

window.location = "/Home/GeraExcel/?nomeEntidade=Usuario&campos=" + campos;

});

});

</script>

</asp:Content>

Note que, o parâmetro nomeEntidade é o nome da tabela definida no arquivo DB.dbml que queremos obter, e a propriedade campos é justamente os campos que desejamos exportar da tabela.

Agora no HomeController vamos criar um método do tipo ActionResult chamado GeraExcel que é justamente o método chamado no evento acima, e um outro chamado SelecionaDados, conforme é exibido abaixo:

public ActionResult GeraExcel(string nomeEntidade, string campos)
{

Type tipoEntidade = Type.GetType("ExportacaoExcel.Models." + nomeEntidade);

return this.Excel(new DBDataContext(),

this.SelecionaDados(tipoEntidade),

nomeEntidade + ".xls",

campos.Split(','));

}

public IQueryable SelecionaDados(Type tb)

{

DBDataContext _db = new DBDataContext();

return _db.GetTable(tb).AsQueryable();

}

Observe, o método GeraExcel recebe os parâmetro (nomeEntidade e campos) enviados pela nossa View Index.aspx, a propriedade tipoEntidade como o próprio nome diz, recebe o tipo da entidade enviada como parâmetro. Porém, será exibida uma mensagem de que não existe uma definição para Excel e que não existe nenhum ExtesionMethod.

Para um melhor entendimento sobre ExtensionMethods veja: http://msdn.microsoft.com/en-us/library/bb383977.aspx

Vamos então criar um, na raiz do projeto criaremos um diretório chamado Helpers e dentro do mesmo adicionaremos uma classe chamada ExtensionMethods.cs com o seguinte código:

using System.Web.Mvc;
using System.Data.Linq;

using System.Linq;

using System.Web.UI.WebControls;

namespace ExportacaoExcel.Helper

{

public static class ExcelControllerExtensions

{

public static ActionResult Excel

(

this Controller controller,

DataContext dataContext,

IQueryable rows,

string fileName

)

{

return new ExcelResult(dataContext, rows, fileName, null, null, null, null);

}

public static ActionResult Excel

(

this Controller controller,

DataContext dataContext,

IQueryable rows,

string fileName,

string[] headers

)

{

return new ExcelResult(dataContext, rows, fileName, headers, null, null, null);

}

public static ActionResult Excel

(

this Controller controller,

DataContext dataContext,

IQueryable rows,

string fileName,

string[] headers,

TableStyle tableStyle,

TableItemStyle headerStyle,

TableItemStyle itemStyle

)

{

return new ExcelResult(dataContext, rows, fileName, headers, tableStyle, headerStyle, itemStyle);

}

}

}

Note agora que é apresentado um novo erro, explicando que não existe o tipo ou namespace ExcelResult, portanto vamos cria-lo também.

Dentro do diretório Helpers adicionaremos outra classe, agora chamada ExcelResult.cs, da seguinte forma:

using System;
using System.Data.Linq;

using System.Drawing;

using System.IO;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

using TesteExcel.Models;

namespace ExportacaoExcel.Helper

{

public class ExcelResult : ActionResult

{

private DBDataContext _db = new DBDataContext();

private DataContext _dataContext;

private string _fileName;

private IQueryable _rows;

private string[] _headers = null;

private System.Web.UI.WebControls.TableStyle _tableStyle;

private TableItemStyle _headerStyle;

private TableItemStyle _itemStyle;

public string FileName

{

get { return _fileName; }

}

public IQueryable Rows

{

get { return _rows; }

}

public ExcelResult(DataContext dataContext, IQueryable rows, string fileName)

: this(dataContext, rows, fileName, null, null, null, null)

{

}

public ExcelResult(DataContext dataContext, IQueryable rows, string fileName, string[] headers)

: this(dataContext, rows, fileName, headers, null, null, null)

{

}

public ExcelResult(DataContext dataContext, IQueryable rows, string fileName, string[] headers, System.Web.UI.WebControls.TableStyle tableStyle, TableItemStyle headerStyle, TableItemStyle itemStyle)

{

_dataContext = dataContext;

_rows = rows;

_fileName = fileName;

_headers = headers;

_tableStyle = tableStyle;

_headerStyle = headerStyle;

_itemStyle = itemStyle;

if (_tableStyle == null)

{

_tableStyle = new System.Web.UI.WebControls.TableStyle();

}

if (_headerStyle == null)

{

_headerStyle = new TableItemStyle();

_headerStyle.BackColor = Color.LightGray;

}

}

public override void ExecuteResult(ControllerContext context)

{

// Cria um HtmlTextWriter

StringWriter sw = new StringWriter();

HtmlTextWriter tw = new HtmlTextWriter(sw);

if (_tableStyle != null)

_tableStyle.AddAttributesToRender(tw);

tw.RenderBeginTag(HtmlTextWriterTag.Table);

// Gera os headers

if (_headers == null)

{

_headers = _dataContext.Mapping.GetMetaType(_rows.ElementType).PersistentDataMembers.Select(m => m.Name).ToArray();

}

// Cria o header para as Rows

tw.RenderBeginTag(HtmlTextWriterTag.Thead);

foreach (String header in _headers)

{

if (_headerStyle != null)

_headerStyle.AddAttributesToRender(tw);

tw.RenderBeginTag(HtmlTextWriterTag.Th);

tw.Write(header);

tw.RenderEndTag();

}

tw.RenderEndTag();

// Cria Data Rows

tw.RenderBeginTag(HtmlTextWriterTag.Tbody);

foreach (Object row in _rows)

{

tw.RenderBeginTag(HtmlTextWriterTag.Tr);

foreach (string header in _headers)

{

string strValue = "";

if (row.GetType().GetProperty(header).GetValue(row, null) == null)

strValue = "";

else

strValue = row.GetType().GetProperty(header).GetValue(row, null).ToString().Trim();

strValue = ReplaceSpecialCharacters(strValue);

if (_itemStyle != null)

_itemStyle.AddAttributesToRender(tw);

tw.RenderBeginTag(HtmlTextWriterTag.Td);

tw.Write(HttpUtility.HtmlEncode(strValue));

tw.RenderEndTag();

}

tw.RenderEndTag();

}

tw.RenderEndTag();

tw.RenderEndTag();

WriteFile(_fileName, "application/ms-excel", sw.ToString());

}

private static string ReplaceSpecialCharacters(string value)

{

value = value.Replace("’", "'");

value = value.Replace("“", "\"");

value = value.Replace("”", "\"");

value = value.Replace("–", "-");

value = value.Replace("…", "...");

return value;

}

private static void WriteFile(string fileName, string contentType, string content)

{

HttpContext context = HttpContext.Current;

context.Response.Clear();

context.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);

context.Response.Charset = "";

context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

context.Response.ContentType = contentType;

context.Response.Write("<html xmlns:x=\"urn:schemas-microsoft-com:office:excel\">");

context.Response.Write("<head>");

context.Response.Write("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=windows-1252\">");

context.Response.Write("<!--[if gte mso 9]>");

context.Response.Write("<xml>");

context.Response.Write("<x:ExcelWorkbook>");

context.Response.Write("<x:ExcelWorksheets>");

context.Response.Write("<x:ExcelWorksheet>");

context.Response.Write("<x:Name>" + fileName.Replace(".xls", "").Replace(".xlsx", "") + "</x:Name>");

context.Response.Write("<x:WorksheetOptions>");

context.Response.Write("<x:Panes>");

context.Response.Write("</x:Panes>");

context.Response.Write("</x:WorksheetOptions>");

context.Response.Write("</x:ExcelWorksheet>");

context.Response.Write("</x:ExcelWorksheets>");

context.Response.Write("</x:ExcelWorkbook>");

context.Response.Write("</xml>");

context.Response.Write("<![endif]-->");

context.Response.Write("</head>");

context.Response.Write("<body>");

context.Response.Write(content);

context.Response.Write("</body>");

context.Response.Write("</html>");

context.Response.End();

}

}

}

Pronto, agora em HomeController basta adicionarmos a referência ao diretório Helpers:

using ExportacaoExcel.Helper;

Note que, ao executar a aplicação e clicar no botão de exportação, é disponibilizado o download do arquivo Excel

Em próximos artigos mostrarei como realizar a importação de um arquivo Excel.

 

Baixe o projeto: http://www.4shared.com/file/aEQ47nSy/Projeto_2.html

Até a próxima !!

 

Rafael Zaccanini

rafael.zaccanini@gmail.com

Anúncios
 
1 comentário

Publicado por em 07/11/2010 em ASP.NET MVC

 

Tags: , , ,

Uma resposta para “ASP.NET MVC – Exportando dados para planilha Excel

  1. José Terceiro

    16/05/2011 at 5:37 pm

    Parabéns pelo post. Bastante útil e muito bem explicado.

     

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

 
%d blogueiros gostam disto: