Criando Relatórios Report Viewer em Aplicações ASP.NET MVC – Parte 1 (Renderização pelo Controller)

Standard

Semanalmente recebo diversas dúvidas sobre como criar, manipular e trabalhar com relatórios em uma aplicação ASP.NET MVC. Realmente não existe muito material referente a este assunto, sendo a maioria voltados para a geração de relatórios com WebForms.

Vendo isto, irei destinar este post para sanar diversas dúvidas que recebo, e demonstrar de uma forma simples e produtiva como criar e renderizar relatórios e sub-relatórios com Report Viewer utilizando ASP.NET MVC. 😉

Tecnologias envolvidas

Para o artigo estarei utilizando o Visual Studio 2008 com SP1 e ASP.NET MVC2. Isto devido ao fato de que a maior parte das dúvidas que recebo serem referêntes a tais ferramentas e tecnologias, e também ao fato de não existir muito material disponível sobre tal assunto.

Contexto

Irei criar primeiramente um relatório de Pedidos, e em seguida um sub-relatório com os itens do Pedido.

Mãos a Massa

Iremos considerar as seguintes tabelas no banco:

Imagem 1

Primeiramente vamos criar um novo projeto em MVC2, para este artigo estarei utilizando Entity Framework para persistência e manipulação dos dados, vamos então cria-lo no diretório Model e selecionar as tabelas que iremos trabalhar, nossa estrutura deve ficar como na imagem abaixo:

Imagem 2

Criando uma Classe DTO para o relatório

Vamos criar agora uma classe DTO chamada DTO_RelatorioPedido.cs, esta classe servirá para transferência dos dados e representação das informações que nosso relatório irá conter, para tanto vamos cria-la da seguinte forma:

 

public class DTO_RelatorioPedido
{
   public int codPedido { get; set; }
   public string nomeCliente { get; set; }
   public DateTime dataEntrega { get; set; }
   public decimal valorTotalPedido { get; set; }
   public int quantidadeItens { get; set; }
}

 

Selecionando os Pedidos

Agora vamos criar uma classe que permita realizar a seleção dos Pedidos, nossa classe tera o nome RepositorioPedido.cs com a seguinte estrutura:

public partial class RepositorioPedido
{
    public static List<DTO_RelatorioPedido> SelecionaPedido(int codPedido)
    {
        DB db = new DB();

        return (from p in db.tbPedidos
                where p.codPedido == codPedido
                select new DTO_RelatorioPedido
                {
                    codPedido = p.codPedido,
                    dataEntrega = (DateTime)p.dataEntrega,
                    nomeCliente = p.tbClientes.nome,
                    quantidadeItens = p.tbPedidosItens.Count,
                    valorTotalPedido = (decimal)p.valorTotal
                }).ToList();
    }

}

NOTA: Para o artigo criei uma instância do nosso Contexto de Dados dentro do próprio método, porém em uma solução corporativa o melhor e mais correto seria a implementação de um Repositório Genérico.

Atente-se ao fato que nossa classe deve ser parcial e o método estático!!!

Criando o Relatório

Criaremos agora um relatório com Report Viewer chamado Pedido.rdlc, em seguida vamos definir seu DataSource com o tipo da classe DTO_RelatorioPedido conforme as imagens abaixo:

Imagem 3

Imagem 4

Em seguida vamos inserir em nosso relatório uma lista e definir seu DataSetName como DTO_RelatorioPedido, veja abaixo:

Imagem 5

Imagem 6

Depois é possivel formatar seu relatório como achar melhor, no momento vou deixa-lo como abaixo:

Imagem 7

Renderizando o Relatório pelo Controller

Para renderizarmos nosso relatório a primeira coisa precisamos fazer é utilizar a dll Microsoft.ReportViewer.WebForms, famos adiciona-la ao nosso projeto e em seguida vamos criar um novo Controller chamado SuporteController.cs.

Em seguida vamos criar um método que recebe como parâmetro o código do pedido a ser impresso e de fato renderiza nosso relatório:

public ActionResult RenderizaRelatorio(int codPedido)
{
   LocalReport relatorio = new LocalReport();

   //Caminho onde o arquivo do Report Viewer está localizado
   relatorio.ReportPath = Server.MapPath("~/Relatorio/Pedido.rdlc");

   //Define o nome do nosso DataSource e qual rotina irá preenche-lo, no caso, nosso método criado anteriormente
   relatorio.DataSources.Add(new ReportDataSource("DTO_RelatorioPedido", RepositorioPedido.SelecionaPedido(codPedido)));

   string reportType = "PDF";
   string mimeType;
   string encoding;
   string fileNameExtension;

   string deviceInfo =
    "<DeviceInfo>" +
    " <OutputFormat>PDF</OutputFormat>" +
    " <PageWidth>9in</PageWidth>" +
    " <PageHeight>11in</PageHeight>" +
    " <MarginTop>0.7in</MarginTop>" +
    " <MarginLeft>2in</MarginLeft>" +
    " <MarginRight>2in</MarginRight>" +
    " <MarginBottom>0.7in</MarginBottom>" +
    "</DeviceInfo>";

   Warning[] warnings;
   string[] streams;
   byte[] bytes;

   //Renderiza o relatório em bytes
   bytes = relatorio.Render(
   reportType,
   deviceInfo,
   out mimeType,
   out encoding,
   out fileNameExtension,
   out streams,
   out warnings);

   return File(bytes, mimeType);
}

 

NOTA: No código acima o relatório é renderizado e exibido conforme o tipo definido, no caso PDF. Caso deseje realizar o download do arquivo renderizado basta adicionar o seguinte código antes de seu return:

 

Response.AddHeader("content-disposition", "attachment; filename=PEDIDO." + fileNameExtension);

Agora falta apenas criarmos um link para chamar o método criado acima, podemos fazer isto na Master Page mesmo, apenas para teste:

 

<%= Html.ActionLink("Imprimir Pedido", "RenderizaRelatorio", "Suporte", new { codPedido = 1 }, null)%>

 

Testando

Agora podemos rodar nossa aplicação e veja o resultado:

Imagem 8

Imagem 9

 

 

6 thoughts on “Criando Relatórios Report Viewer em Aplicações ASP.NET MVC – Parte 1 (Renderização pelo Controller)

    • rafaelzaccanini

      DB é a representação do meu DataContext, é meu objeto para conexão com o Banco!

      A referência dele está dentro do arquivo .dbml

      Se você fizer o download do projeto entenderá melhor, abs!

Leave a Reply

Your email address will not be published. Required fields are marked *