none
Exibir relatório em popup,modal ou dialog RRS feed

  • Pergunta

  • Queria saber qual a melhor forma de se exibir um relatório. Estou refazendo um sistema feito em Webforms, quando esse sistema estava em desenvolvimento tive problemas exatamente nesse ponto, pois os relatórios são todos feitos em reportviewer, sendo que quando da exibição do relatório pelo reportviewer no navegador não aparece o botão de impressão, na época a solução que encontrei e que utilizo em todos os meus sistemas é converter os relatórios em PDF e os exibo em um pop-up, em webforms funciona perfeito, mais verifiquei que em MVC não funciona, eu até conseguir exibir o relatório em dialog mais ele perde a masterpage(_layout) a página sai totalmente e fica muito complicado para o usuário voltar pelo botão do próprio navegador.

    Será que alguém poderia me dizer como se exibe relatórios em MVC ?


    Junior

    terça-feira, 4 de outubro de 2016 12:33

Respostas

  • Primeiro eu gostaria de entender porque é importante mostar o PDF dentro de uma view com MasterPage.

    Creio que isso nao seja possivel, pois pdf nao sera renderizado como HTML. Voce obrigatoriamente tera que mostra-lo em uma janela à parte.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Junior_luiz quinta-feira, 6 de outubro de 2016 16:10
    quarta-feira, 5 de outubro de 2016 13:59
    Moderador

Todas as Respostas

  • Realmente nao é trivial. Como eu disse em um post anterior, pdf nao é html para ser renderizado no interior de um view (ou partialview). Para isso ele depende de uma extensao (alguns navegadores adicionam isso nativamente, como o chrome)

    Mas o reportviewer consegue exibir seus relatorios em HTML, e nesse caso é possivel exibi-lo no interior de uma partialview.

    Existe um projeto que fazia exatamente isso:

    https://reportviewerformvc.codeplex.com/

    Mas a ultima atualizaçao é de 2014

    Outra possibilidade é fazer no braço:

    https://blogs.msdn.microsoft.com/sajoshi/2010/06/16/asp-net-mvc-handling-ssrs-reports-with-reportviewer-part-i/

    E uma ultima possibilidade, que particularmente eu acho deselegante, é criar o visualizador em ASP.NET e chamar essa pagina no c#, como discutido aqui:

    http://stackoverflow.com/questions/30709782/mvc5-ssrs-reportviewer-how-to-implement

    considero essa salada bem indigesta, mas funciona.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    terça-feira, 4 de outubro de 2016 13:55
    Moderador
  • William realmente montar na mão ou usar um webforms dentro de um projeto MVC não acho viável e tb terei muitos relatórios então teria que criar muitas aspx dentro do projeto, já estou usando o ReportViewer for MVC, mais como falei eu conseguir emitir o relatório em pdf usando um dialog, só que não abre um popup abre uma página sem a masterpage, fiz assim :

    No meu controller 

    Relatorios Controller

    public ActionResult Departamento()
     {
         return View();
     }
    
    public PartialViewResult ListaDepartamento()
     {
        aqui monto meu relatorio e converto para pdf
        return PartialView();
     }
    
    

    Na View Departamento

    @{
        ViewBag.Title = "Departamento";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>Relatório Departamento</h2>
    
    @Html.ActionLink("Imprimir", "ListaDepartamento", "Relatorios", new { @class = "popupLink" })
    
    @section Scripts{
        <script>
            $(function () {
                $('.popupLink').click(function () {
                    $('<div id="popupfooterdiv"/>').appendTo('body').dialog({
                        close: function (event, ui) {
                            dialog.remove();
                        },
                        modal: false,
                        draggable: false,
                        width: 500,
                        height: 400,
                        resizable: false,
                        //open: function (event, ui) {
                        //    $(‘.ui-dialog-title’).remove();
                        //}
                    }).load(this.href, {});
                    return false;
                });
            });
    </script>
    }

    Na Partial View

    @using ReportViewerForMvc;
    
    @Html.ReportViewer(ViewBag.ReportViewer as Microsoft.Reporting.WebForms.ReportViewer, new { frameborder = "0", width = "800", height = "800", style = "overflow:hidden;", scrolling = "no" })


    Junior

    terça-feira, 4 de outubro de 2016 14:45
  • O que costumo fazer é quando vou exibir um relatório em PDf abro em uma nova aba do navegador preservando a aba com o sistema.

    Se a resposta contribuiu com seu aprendizado por favor marque como Útil
    Se solucionou seu problema por favor marque como Resposta
    Atenção, se seu problema foi resolvido não deixe o post aberto 

    Visite : www.codigoexpresso.com.br

    terça-feira, 4 de outubro de 2016 16:23
  • Como vc faz isso ?

    Junior

    terça-feira, 4 de outubro de 2016 17:13
  • Mais ou menos deste jeito:

    http://www.codeproject.com/Tips/697733/Display-PDF-within-web-browser-using-MVC

    Mas eu nao sei se o caso do Codigo Expresso é o mesmo que o seu.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    terça-feira, 4 de outubro de 2016 17:20
    Moderador
  • quando for chamar carregue target="_blank"

    <a href="@Url.Action("RelatorioClientes", "Clientes", new { idCidade = 1 })" target="_blank">Relatorio de Clientes</a>

    Se a resposta contribuiu com seu aprendizado por favor marque como Útil
    Se solucionou seu problema por favor marque como Resposta
    Atenção, se seu problema foi resolvido não deixe o post aberto 

    Visite : www.codigoexpresso.com.br

    terça-feira, 4 de outubro de 2016 17:27
  • Luiz,

    Voce ja viu o artigo do André:

    http://www.andrealveslima.com.br/blog/index.php/2016/02/10/utilizando-o-report-viewer-no-asp-net-mvc/

    Creio que ele seja a melhor pessoa para responder a sua questao.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    terça-feira, 4 de outubro de 2016 17:28
    Moderador
  • William eu estudei exatamente por esse tutorial do Andre Lima, mais lá ele exibe o relatório pelo report viewer, mais ai tem o detalhe que falei por ele não mostra o botão de imprimir, isso acontece tb em webforms, foi por isso que converti meus relatórios em PDF.


    Junior

    terça-feira, 4 de outubro de 2016 18:45
  • O problema dessa abordagem é que tenho que salvar o pdf em uma pasta, e se o relatório for executado simultaneamente por 2 ou mais usuários como fica ?


    Junior

    terça-feira, 4 de outubro de 2016 18:47
  • Se tiver que salvar, salve no cliente e não no servidor

    Se a resposta contribuiu com seu aprendizado por favor marque como Útil
    Se solucionou seu problema por favor marque como Resposta
    Atenção, se seu problema foi resolvido não deixe o post aberto 

    Visite : www.codigoexpresso.com.br

    terça-feira, 4 de outubro de 2016 19:34
  • e vai exibir eu salvando no cliente ?

    Junior

    terça-feira, 4 de outubro de 2016 19:46
  • Em que momento voce gera o PDF? Tem como postar o tercho da geraçao do PDF aqui?

    No meu caso eu gero PDF usando o Memory Stream e depois e depois eu retorno o bytearray gerado como um FileAction. Assim dois usuarios podem gerar o mesmo relatorio ao mesmo tempo sem nenhum conflito.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    terça-feira, 4 de outubro de 2016 19:49
    Moderador
  • Está aqui minha Action

    public PartialViewResult ListaDepartamento()
            {
              var departamento = new DataSet1.RelatorioDepartamentoDataTable();
                var reportViewer1 = new ReportViewer
                {
                    ProcessingMode = ProcessingMode.Local
                };
                reportViewer1.LocalReport.ReportPath = "Relatorios/RptDepartamento.rdlc";
                reportViewer1.LocalReport.EnableExternalImages = true;
                reportViewer1.LocalReport.EnableHyperlinks = true;
                List<ReportParameter> parametros = new List<ReportParameter>();
    
                parametros.Add(new ReportParameter("usuario", usuario));
                parametros.Add(new ReportParameter("codempr", cdempr.ToString()));
    
                reportViewer1.LocalReport.SetParameters(parametros);
    
               Executo meu SQL
    
               // Variaveis
                Warning[] warnings;
                string[] streamIds;
                string mimeType = string.Empty;
                string encoding = string.Empty;
                string extension = string.Empty;
                string fileName = "Departamento.pdf";
    
                var dt1 = GetData(sql);
                reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", dt1));
                reportViewer1.SizeToReportContent = true;
                reportViewer1.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                reportViewer1.Height = System.Web.UI.WebControls.Unit.Percentage(100);
                ViewBag.ReportViewer = reportViewer1;
                byte[] bytes = reportViewer1.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
                Response.Buffer = true;
                Response.ContentType = mimeType;
                Response.AddHeader("content-disposition", "attachment; filename=" + fileName + "." + extension);
                Response.BinaryWrite(bytes);
                Response.Flush(); 
                Response.Clear();
                return PartialView();
            }


    Junior

    quarta-feira, 5 de outubro de 2016 12:03
  • Você sabe que não precisa salvar ne?

    Pode exibir no cliente e se ele quiser faz o download do pdf e guarda.

    Se a resposta contribuiu com seu aprendizado por favor marque como Útil
    Se solucionou seu problema por favor marque como Resposta
    Atenção, se seu problema foi resolvido não deixe o post aberto 

    Visite : www.codigoexpresso.com.br

    quarta-feira, 5 de outubro de 2016 12:07
  • Luiz, 

    Creio que deveria ser algo do tipo:

    ReportDataSource ds1 = new ReportDataSource("DS", (DataTable)ta1.GetData(Parm1));
                            lr.DataSources.Add(ds1);
                            Microsoft.Reporting.WebForms.Warning[] warnings;
                            string[] streamids;
                            string mimeType;
                            string encoding;
                            string filenameExtension;
                            byte[] bytes;
                            lr.Refresh();
                            bytes = lr.Render("PDF", null, out mimeType, out encoding, out filenameExtension, out streamids,
                                              out warnings);
                            
                            Page.Response.Buffer = false;
                            Page.Response.BufferOutput = false;
                            Page.Response.Clear();
                            Page.Response.ClearContent();
                            Page.Response.ClearHeaders();
                            Response.AppendHeader("content-disposition", "attachment; filename=report.pdf");
                            Response.ContentType = "application/pdf";
                            using (MemoryStream memoryStream = new MemoryStream(bytes))
                            {
                                memoryStream.Seek(0, SeekOrigin.Begin);
                                var streamBytes = memoryStream.ToArray();
                                Response.BinaryWrite(streamBytes);
                            }
                            Response.End();

    Note que o relatorio é criado usando o MemoryStream. Neste caso nenhum arquivo fisico é criado. 

    att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    quarta-feira, 5 de outubro de 2016 13:33
    Moderador
  • William está acontece algo estranho ou estou fazendo algo errado mesmo antes de alterar para o seu está dando o seguinte erro e alterando para o que vc me mandou o erro continua :

    OutputStream não está disponível quando TextWriter personalizado é usado.

    Minha view 

    <a href="/modal/content/" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Launch demo modal
    </a>
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="myModalLabel">Departamentos</h4>
                </div>
                <div class="modal-body">
                    @{Html.RenderAction("ListaDepartamento", "Relatorios");}
                </div>
                <div class="modal-footer">
                    
                </div>
            </div><!-- /.modal-content -->
        </div>

    Como está dá o erro se eu tiro  @{Html.RenderAction("ListaDepartamento", "Relatorios");} não dá o erro e mostra o relatório em PDF sendo que perde a referencia da masterPage.

    O que estou fazendo de errado ?


    Junior

    quarta-feira, 5 de outubro de 2016 13:47
  • Primeiro eu gostaria de entender porque é importante mostar o PDF dentro de uma view com MasterPage.

    Creio que isso nao seja possivel, pois pdf nao sera renderizado como HTML. Voce obrigatoriamente tera que mostra-lo em uma janela à parte.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Junior_luiz quinta-feira, 6 de outubro de 2016 16:10
    quarta-feira, 5 de outubro de 2016 13:59
    Moderador
  • William abrindo outra janela funciona, só acho meio estranho olhando pelo lado do usuário, se fosse possível pelo menos abrir um pop-up na minha opinião seria visualmente melhor me colocando como usuário.

    Junior

    quarta-feira, 5 de outubro de 2016 14:28
  • Seria mais facil se o relatorio fosse renderizado em HTML ao inves de PDF, mas existe esse possibilidade:

    public void EmployeesNumberPerYearToPDF()
            {
             string dtatSetName = "DsENPerYear";
             var dataSource = 
                     EmployeeReports.EmployeesNumberPerYear(employeeRepository);
             string reportFilePath = 
                     Server.MapPath("~/RDLC/Employee/EmployeesNumberPerYear.rdlc");
             string reportType = "PDF";
     
             string mimeType;
             string encoding;
             string fileNameExtension;
     
             byte[] renderedBytes = 
                HotelReport.GenerateReport(dtatSetName, dataSource, reportFilePath,
                    reportType, out mimeType, out encoding, out fileNameExtension);
     
            System.Web.HttpContext.Current.Response.ContentType = mimeType;
            System.Web.HttpContext.Current.Response.BinaryWrite(renderedBytes);
     
            }



    Usando o Iframe:

    <iframe src="http://docs.google.com/gview?url=@Url.Action("EmployeesNumberPerYearToPDF", "EmployeeReports", null, Request.Url.Scheme)&embedded=true" style="width:600px; height:500px;" frameborder="0"></iframe>
    fonte:http://www.codeproject.com/Questions/358165/Use-MVC-show-RDLC-in-div

    Note que voce invoca o visualizador de documentos do google. Com isso voce é capaz de visualizar um PDF dentro de um Popup.

    Mas iFrames sao considerados como "Bad Practice":

    http://blog.hiregroundsoftware.com/technology/4-reasons-you-need-to-stop-using-iframes/

    att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------


    quarta-feira, 5 de outubro de 2016 14:48
    Moderador