Olá pessoal, tudo certo?

A ideia desse post surgiu à algumas semanas atrás, ao acompanhar uma dúvida postada pelo Duan Brito.

A dúvida era como utilizar o controle ReportViwer em uma página asp.net mvc, sugeri ao Duan exibir o relatório em .pdf, pois, o controle não seria possível, uma vez que ele faz parte do WebForms. Mas isso era o que eu pensava, até que o Fabio Galante e o José Romualdo sugeriram uma solução. Achei interessante, logo criei um teste, e funcionou perfeitamente, resolvi compartilhar e aqui estou.

Em uma discussão sobre asp.net mvc x webforms surgiu a seguinte questão:

Em qual cenário poderíamos usar uma página webforms em um projeto asp.net mvc?

A ideia desse post seria um cenário?

Esse post não tem o objetivo de mostrar recursos do ReportViwer, mas como utilizar o controle ReportViwer do webforms em um projeto asp.net mvc.

Criando a aplicação

Os exemplos aplicados nesse post foram feitos utilizando o Visual Studio 2013 com uma aplicação asp.net mvc 5.

Para começar, crie um novo projeto no visual studio, com o nome UtilizandoControleReportViwer, do tipo C#  >>  Web  >>  ASP.NET Web Application  >>  MVC.

Na pasta Models, crie uma nova classe chamada ProdutoModels e insira o código da Listagem 1.

[sourcecode language="csharp"]
namespace UtilizandoControleReportViwer.Models
{
public class ProdutoModels
{
public int Codigo { get; set; }
public string Nome { get; set; }
public double Preco { get; set; }
public double QtdEmEstoque { get; set; }
}
}
[/sourcecode]

Listagem 1 - Código da classe ProdutoModels.

Na pasta Controllers, abra o controller Home e insira o código da Listagem 2 ao já existente nesse arquivo.

[sourcecode language="csharp"]
public void Relatorio()
{
Response.Redirect("~/Relatorio/Relatorio.aspx");
}
[/sourcecode]

Listagem 2 - Inserindo novo método no controller Home.

Crie uma nova pasta em seu projeto com nome Relatorio. Feito isso, botão direito na pasta criada Add New Item  >>  Web  >>  WebForms  >>  WebForm. Dê o nome de Relatorio.

[caption id="attachment_1701" align="alignnone" width="1600"]Figura 1 - Add New Item >> Web >> WebForms >> WebForm Figura 1 - Add New Item >> Web >> WebForms >> WebForm[/caption]

Abra o aquivo Relatorio.aspx que acabamos de criar. Nele iremos adicionar o controle ReportViwer e um ScriptManager, encontramos ambos na toolbox em Reporting e AjaxExtensions respectivamente. Após adicionados, o arquivo Relatório.aspx deverá estar da seguinte forma:

[sourcecode language="html"]

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Relatorio.aspx.cs" Inherits="UtilizandoControleReportViwer.Views.Produto.Relatorio" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div>
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Width="722px"></rsweb:ReportViewer>
</div>
</form>
</body>
</html>
[/sourcecode]

 Listagem 3 - Código da página Relatorio.aspx

Ainda na pasta Relatorio, adicionaremos mais dois itens, sendo eles, um DataSet e um arquivo rdlc.

Para adicionar o DataSet, botão direito na pasta Relatorio Add New Item  >>  Data  >>  DataSet. Dê o nome de dsProduto.xsd

[caption id="attachment_1821" align="alignnone" width="1600"]Figura 2 - Criando um DataSet Figura 2 - Criando um DataSet[/caption]

Após criar o DataSet, abra-o. Ao abri-lo, iremos visualizar uma tela de design. Nessa tela, clique com o botão direito em qualquer local, Add  >>  DataTable.

[caption id="attachment_1831" align="alignnone" width="818"]Figura 4 - Criando um DataTable no dataset. Figura 3 - Criando um DataTable no dataset.[/caption]

 

Renomeie o DataTable para dsProduto. Adicione as seguintes colunas nesse DataTable:

As colunas adicionadas ao DataTable são referentes a classe produto. Vale ressaltar que deve estar escrito exatamente igual ao nome das propriedades da classe. Dando continuidade, vamos criar o arquivo rdlc. Botão direito na pasta Relatorio Add New Item  >>  Reporting  >>  Report. Dê o nome de ListaProduto.rdlc

[caption id="attachment_1811" align="alignnone" width="1313"]Figura 2 - Adicionando o arquivo rdlc. Figura 4 - Adicionando o arquivo rdlc.[/caption]

Ao criar o arquivo rdlc abra seu modo design dando dois click's em ListaProduto.rdlc. Com o modo design aberto, clique com o botão direito em qualquer local e insira uma Table.

[caption id="attachment_1851" align="alignnone" width="1600"]Figura 5 - Inserindo uma table no report. Figura 5 - Inserindo uma table no report.[/caption]

Após clicar em Insert  >>  Table, a janela DataSet Properties será aberta para selecionarmos o data source que usaremos nessa tabela. Defina a opção Name como dsProduto. Na opção data source selecione o dataset dsProduto que criamos.

[caption id="attachment_1861" align="alignnone" width="1600"]Figura 6 - Configurando o dataset da table. Figura 6 - Configurando o data source da table.[/caption]

Nesse momento, a table está vinculada ao dataset dsProduto. Só precisamos informar em qual coluna cada dado será apresentado. Para isso, coloque o mouse na segunda linha da table e clique no canto superior direito da célula para que sejam mostradas as opções disponíveis.

[caption id="attachment_1871" align="alignnone" width="1600"]Figura 7 - Configurando dados na table. Figura 7 - Configurando dados na table.[/caption]

Apresente os dados na seguinte ordem:

  1. Codigo
  2. Nome
  3. Preco
  4. QtdEmEstoque

Agora precisamos inserir dados no dataset dsProduto e vincula-lo ao controle ReportViwer. Antes de fazer isso, iremos baixar e referenciar a dll do reportviwer webforms no projeto, iremos fazer isso através do nugget. Abra o package manager console e execute o seguinte comando:

Install-Package MicosoftReportViewerWebForms

Ao finalizar a instalação, abra o codebehind da página Relatorio.aspx (botão direito no arquivo  >>  View Code). Feito isso, insira o seguinte código:

[sourcecode language="csharp"]
using Microsoft.Reporting.WebForms;
using System;
using System.Collections.Generic;
using UtilizandoControleReportViwer.Models;

namespace UtilizandoControleReportViwer.Views.Produto
{
public partial class Relatorio : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var listaProduto = new List<ProdutoModels>()
{
new ProdutoModels{Codigo = 1, Nome = "Teclado", Preco = 31.50, QtdEmEstoque = 100},
new ProdutoModels{Codigo = 2, Nome = "Mouse", Preco = 20, QtdEmEstoque = 75},
new ProdutoModels{Codigo = 3, Nome = "Monitor", Preco = 350.99, QtdEmEstoque = 83},
new ProdutoModels{Codigo = 4, Nome = "Fone de ouvido", Preco = 59.60, QtdEmEstoque = 18},
new ProdutoModels{Codigo = 5, Nome = "Mousepad", Preco = 8.30, QtdEmEstoque = 33},
new ProdutoModels{Codigo = 6, Nome = "Notebook", Preco = 2500.70, QtdEmEstoque = 20},
new ProdutoModels{Codigo = 7, Nome = "HD SSD 120 GB", Preco = 240, QtdEmEstoque = 17},
new ProdutoModels{Codigo = 8, Nome = "Placa de vídeo", Preco = 999, QtdEmEstoque = 42},
new ProdutoModels{Codigo = 9, Nome = "Gabinete", Preco = 60, QtdEmEstoque = 23},
new ProdutoModels{Codigo = 10, Nome = "Iphone 6", Preco = 3000, QtdEmEstoque = 50}
};

var reportDS = new ReportDataSource();
reportDS.Name = "dsProduto";
reportDS.Value = listaProduto;

ReportViewer1.LocalReport.DataSources.Add(reportDS);
ReportViewer1.LocalReport.ReportPath = "Relatorio/ListaProduto.rdlc";
}
}
}
}
[/sourcecode]

Listagem 4 - CodeBehind da página Relatorio.aspx
O código da listagem 4 é bem simples, basicamente o que está sendo feito é popular uma lista de produto e adicionar essa lista a um objeto ReportDatasource. Esse objeto também está sendo vinculado ao dataset dsProduto através da propriedade Name. Após isso, adiciono o objeto ReportDatasource ao controle ReportViwer1 e informo o caminho do arquivo rdlc.

Estamos com 99% do projeto exemplo pronto, só precisamos adicionar o link na tela inicial que nos redirecione para a página Relatorio.aspx. Abra a pasta Views  >>  Home e dê um duplo clique na View Index. Apague todo o conteúdo dessa View e adicione o seguinte código:

[sourcecode language="html"]

@{
ViewBag.Title = "Home Page";
}

<a href="~/Relatorio/Relatorio.aspx">Lista de Produtos</a>

[/sourcecode]

Listagem 5 - View Home Index

Na listagem 5 só estamos adicionando um link que nos redirecionará para a página Relatorio.aspx.

Execute a aplicação e clique no link Lista de Produtos. Se tudo der certo, uma lista de produtos será apresentada no controle do ReportViwer.

[caption id="attachment_1891" align="alignnone" width="759"]Figura 8 - Lista de produtos no controle do ReportViwer Figura 8 - Lista de produtos no controle do ReportViwer[/caption]

Abrir relatórios na tela de navegação do usuário pode ser um tanto quanto ruim para usabilidade. Pensando nisso, podemos fazer a chamada da página Relatorio.aspx através do javascript. Para fazer isso altere o código da view Home Index, deixando-o dessa forma:

[sourcecode language="html"]

@{
ViewBag.Title = "Home Page";
}

<a id="linkRelatorio">Lista de Produtos</a>

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<script>
 $(document).ready(function () {
  $("#linkRelatorio").on("click", function () {
   window.open("Relatorio/Relatorio.aspx", "_blank", "toolbar=no, scrollbars=yes, resizable=yes, width=600, height=600");
  });
});
</script>

[/sourcecode]

Listagem 6 - Código para abrir a página Relatorio.aspx em janela.

Execute a aplicação novamente, agora a tela Relatorio.aspx será aberta em janela.

[caption id="attachment_1901" align="alignnone" width="1600"]Figura 9 - Abrindo o relatório em janela. Figura 9 - Abrindo o relatório em janela.[/caption]

Você pode optar por não usar dataset e ter o mesmo resultado usando um dto, veja como em http://rafaelzaccanini.net.br/2011/04/05/criando-relatorios-report-viewer-em-aplicacoes-asp-net-mvc-parte-1-renderizacao-pelo-controller/

E aê, tem uma opinião sobre essa abordagem? Consegue responder a pergunta feita no inicio do post?

Em qual cenário poderíamos usar uma página webforms em um projeto asp.net mvc?

A ideia desse post seria um cenário?

Baixe o código fonte aqui.

Era isso que eu queria mostrar pessoal.

Até o próximo post!