André Alves de Lima

Talking about Software Development and more…

Como podemos exportar relatórios do Crystal Reports?

Há algumas semanas atrás eu mostrei como exportar relatórios do Report Viewer. Esta semana eu decidi escrever novamente sobre o tema exportação de relatórios, só que dessa vez mostrando como exportar relatórios do Crystal Reports.

Muito parecido com o Report Viewer, nos controles do Crystal Reports podemos habilitar ou desabilitar a exportação por completo e escolher quais formatos de exportação estarão disponíveis. Além disso, caso seja necessário, conseguimos também fazer a exportação sem utilizar o controle visualizador (ou seja, somente com as dlls de negócio do Crystal Reports). E aí, bora conferir como conseguimos fazer tudo isso?

Criando o projeto de exemplo

Como mencionado anteriormente, o objetivo desse artigo é mostrar coisas relacionadas à exportação dos relatórios do Crystal Reports. Dessa forma, criaremos um relatório extremamente simples em um projeto “Windows Forms“, que mostrará uma listagem de Clientes. Se você quiser dar uma olhada em um tutorial que mostra um relatório mais complexo do Crystal Reports, confira o meu artigo sobre Crystal Reports com Entity Framework.

Primeiramente, vamos começar criando um projeto do tipo “Windows Forms” e, dentro desse projeto, vamos adicionar uma nova classe chamada “Cliente“:

    // C#
    public class Cliente
    {
        public string Nome { get; set; }
        public DateTime DataCadastro { get; set; }
        public string Regiao { get; set; }
        public DateTime DataPrimeiraCompra { get; set; }
        public DateTime DataUltimaCompra { get; set; }
    }
' VB.NET
Public Class Cliente
    Public Property Nome As String
    Public Property DataCadastro As DateTime
    Public Property Regiao As String
    Public Property DataPrimeiraCompra As DateTime
    Public Property DataUltimaCompra As DateTime
End Class

Feito isso, vamos adicionar um novo relatório do Crystal Reports dentro da nossa aplicação, dando o nome de “RelatorioClientes“. Os relatórios do Crystal Reports ficam dentro da categoria “Reporting” da tela “Add New Item“:

Nota: Caso você não consiga encontrar o item “Crystal Reports” na tela “Add New Item”, isso quer dizer que você provavelmente não instalou a versão correta do Crystal Reports. Para resolver esse problema, confira o meu artigo onde eu mostro como instalar o Crystal Reports no Visual Studio 2013 e 2015.

Uma vez adicionado o relatório no projeto, precisamos escolher o conjunto de dados que alimentará o relatório. Para isso, vamos clicar com o botão direito em “Database Fields” e, logo em seguida, escolhemos a opção “Database Expert“:

Na tela “Database Expert“, encontre a classe “Cliente” e mova-a para o lado direito da tela:

Por fim, arraste os campos para dentro do relatório de forma que ele fique parecido com a imagem abaixo:

Pronto! Agora vamos até o formulário, encontramos o controle do Crystal Reports na caixa de ferramentas do Visual Studio e arrastamos para dentro do nosso formulário:

Em seguida, escolhemos o relatório que criamos anteriormente:

Agora vamos até o code-behind do formulário para criarmos uma lista de instâncias da classe “Cliente” e passamos essa lista como DataSource do relatório:

        // C#
        public FormRelatorio()
        {
            InitializeComponent();

            var clientes = new List<Cliente>();
            clientes.Add(new Cliente() { Nome = "André Lima", DataCadastro = new DateTime(2008, 5, 17), Regiao = "Norte", DataPrimeiraCompra = new DateTime(2008, 6, 1), DataUltimaCompra = new DateTime(2016, 3, 12) });
            clientes.Add(new Cliente() { Nome = "Fulano de Tal", DataCadastro = new DateTime(2015, 12, 15), Regiao = "Nordeste", DataPrimeiraCompra = new DateTime(2016, 1, 16), DataUltimaCompra = new DateTime(2016, 1, 16) });
            clientes.Add(new Cliente() { Nome = "Beltrano Silva", DataCadastro = new DateTime(2011, 2, 23), Regiao = "Sudeste", DataPrimeiraCompra = new DateTime(2011, 2, 23), DataUltimaCompra = new DateTime(2013, 4, 12) });
            clientes.Add(new Cliente() { Nome = "João Souza", DataCadastro = new DateTime(2014, 8, 14), Regiao = "Sul", DataPrimeiraCompra = new DateTime(2014, 8, 24), DataUltimaCompra = new DateTime(2015, 12, 31) });
            RelatorioClientes1.SetDataSource(clientes);
            crystalReportViewer1.RefreshReport();
        }
    ' VB.NET
    Private Sub FormRelatorio_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim Clientes As New List(Of Cliente)
        Clientes.Add(New Cliente() With {.Nome = "André Lima", .DataCadastro = New DateTime(2008, 5, 17), .Regiao = "Norte", .DataPrimeiraCompra = New DateTime(2008, 6, 1), .DataUltimaCompra = New DateTime(2016, 3, 12)})
        Clientes.Add(New Cliente() With {.Nome = "Fulano de Tal", .DataCadastro = New DateTime(2015, 12, 15), .Regiao = "Nordeste", .DataPrimeiraCompra = New DateTime(2016, 1, 16), .DataUltimaCompra = New DateTime(2016, 1, 16)})
        Clientes.Add(New Cliente() With {.Nome = "Beltrano Silva", .DataCadastro = New DateTime(2011, 2, 23), .Regiao = "Sudeste", .DataPrimeiraCompra = New DateTime(2011, 2, 23), .DataUltimaCompra = New DateTime(2013, 4, 12)})
        Clientes.Add(New Cliente() With {.Nome = "João Souza", .DataCadastro = New DateTime(2014, 8, 14), .Regiao = "Sul", .DataPrimeiraCompra = New DateTime(2014, 8, 24), .DataUltimaCompra = New DateTime(2015, 12, 31)})
        RelatorioClientes1.SetDataSource(Clientes)
        CrystalReportViewer1.RefreshReport()
    End Sub

Por fim, antes de executarmos o nosso projeto precisamos configurar o elemento “useLegacyV2RuntimeActivationPolicy” como “true” no nosso arquivo app.config, caso contrário receberemos um erro ao tentarmos executar a nossa aplicação:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

Agora sim, execute o projeto e veja o resultado:

Desabilitando a exportação

Ao utilizarmos o controle padrão do Crystal Reports, podemos exportar os relatórios utilizando o primeiro botão da barra de ferramentas:

Na janela que se abre, podemos escolher o local onde a exportação será salva e o formato que queremos utilizar:

E se quisermos desabilitar o botão de exportação no controle visualizador? Simples, basta alterarmos a propriedade “ShowExportButton” para “false“:

Desabilitando alguns formatos de exportação

OK, acabamos de ver logo acima como podemos desabilitar por completo a exportação do relatório. Mas, e se quisermos habilitar somente alguns formatos específicos de exportação? Por exemplo, digamos que nós só queiramos deixar habilitado para o usuário os formatos “PDF” e “Excel“. Como é que podemos fazer isso?

Não se preocupe, o processo é muito fácil e não envolve nenhuma gambiarra (diferente do que vimos no caso do Report Viewer, com o qual precisamos utilizar reflection para conseguir desabilitar alguns formatos de exportação!). A única coisa que temos que fazer é alterar a propriedade AllowedExportFormats passando a lista de formatos que queremos deixar habilitado:

// C#
crystalReportViewer1.AllowedExportFormats = (int)(CrystalDecisions.Shared.ViewerExportFormats.PdfFormat | CrystalDecisions.Shared.ViewerExportFormats.ExcelFormat);
' VB.NET
CrystalReportViewer1.AllowedExportFormats = (CrystalDecisions.Shared.ViewerExportFormats.PdfFormat Or CrystalDecisions.Shared.ViewerExportFormats.ExcelFormat)

Dessa forma, a lista de formatos será limitada conforme configuramos no nosso código:

Exportando sem o preview

Tudo isso que vimos até agora vale para o caso em que exibiremos o relatório no controle visualizador do Crystal Reports. Mas, e se não quisermos exibir o relatório? E se quisermos exportá-lo diretamente para o disco ou para uma Stream? Nesse caso, temos que utilizar os métodos “Export*” do ReportDocument:

Como você pode observar na imagem acima, temos algumas opções de métodos que começam com a palavra “Export“. Primeiramente, temos o método “Export“, que é o mais flexível de todos. Com ele, temos que configurar um objeto do tipo ExportOptions, onde informamos se queremos exportar para o disco, o caminho, o formato, etc. Devido à complexidade desse método, não recomendo a sua utilização. Conseguimos facilmente satisfazer às nossas necessidades com os outros métodos que começam com “Export“.

O método “ExportToDisk“, como o próprio nome diz, exporta o relatório para o disco. Na chamada desse método, temos que passar o formato desejado e o caminho onde queremos salvar o relatório exportado. Já o método “ExportToHttpResponse” exporta o relatório para uma HttpResponse. Essa opção só faz sentido para aplicações web, onde podemos exportar o relatório diretamente para uma janela do browser ou para exibir o diálogo de “salvar arquivo” no lado cliente. Por fim, o método “ExportToStream“, como o nome diz, exporta o relatório para uma Stream. Nesse caso podemos escolher salvar essa Stream em um banco de dados, por exemplo.

Neste artigo eu vou mostrar para você a utilização do método “ExportToDisk“. Primeiramente, vamos criar um novo formulário no nosso projeto, contendo um botão para exportar o relatório em PDF e outro para exportar o relatório em DOC:

Uma vez ajustado o layout do formulário, vamos adicionar o código no code-behind para fazermos o carregamento do relatório em memória:

        // C#
        private RelatorioClientes _relatorio = new RelatorioClientes();

        public FormExport()
        {
            InitializeComponent();

            var clientes = new List<Cliente>();
            clientes.Add(new Cliente() { Nome = "André Lima", DataCadastro = new DateTime(2008, 5, 17), Regiao = "Norte", DataPrimeiraCompra = new DateTime(2008, 6, 1), DataUltimaCompra = new DateTime(2016, 3, 12) });
            clientes.Add(new Cliente() { Nome = "Fulano de Tal", DataCadastro = new DateTime(2015, 12, 15), Regiao = "Nordeste", DataPrimeiraCompra = new DateTime(2016, 1, 16), DataUltimaCompra = new DateTime(2016, 1, 16) });
            clientes.Add(new Cliente() { Nome = "Beltrano Silva", DataCadastro = new DateTime(2011, 2, 23), Regiao = "Sudeste", DataPrimeiraCompra = new DateTime(2011, 2, 23), DataUltimaCompra = new DateTime(2013, 4, 12) });
            clientes.Add(new Cliente() { Nome = "João Souza", DataCadastro = new DateTime(2014, 8, 14), Regiao = "Sul", DataPrimeiraCompra = new DateTime(2014, 8, 24), DataUltimaCompra = new DateTime(2015, 12, 31) });
            _relatorio.SetDataSource(clientes);
            _relatorio.Refresh();
        }
    ' VB.NET
    Private Relatorio As New RelatorioClientes()

    Private Sub FormExport_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim Clientes As New List(Of Cliente)
        Clientes.Add(New Cliente() With {.Nome = "André Lima", .DataCadastro = New DateTime(2008, 5, 17), .Regiao = "Norte", .DataPrimeiraCompra = New DateTime(2008, 6, 1), .DataUltimaCompra = New DateTime(2016, 3, 12)})
        Clientes.Add(New Cliente() With {.Nome = "Fulano de Tal", .DataCadastro = New DateTime(2015, 12, 15), .Regiao = "Nordeste", .DataPrimeiraCompra = New DateTime(2016, 1, 16), .DataUltimaCompra = New DateTime(2016, 1, 16)})
        Clientes.Add(New Cliente() With {.Nome = "Beltrano Silva", .DataCadastro = New DateTime(2011, 2, 23), .Regiao = "Sudeste", .DataPrimeiraCompra = New DateTime(2011, 2, 23), .DataUltimaCompra = New DateTime(2013, 4, 12)})
        Clientes.Add(New Cliente() With {.Nome = "João Souza", .DataCadastro = New DateTime(2014, 8, 14), .Regiao = "Sul", .DataPrimeiraCompra = New DateTime(2014, 8, 24), .DataUltimaCompra = New DateTime(2015, 12, 31)})
        Relatorio.SetDataSource(Clientes)
        Relatorio.Refresh()
    End Sub

Por fim, vamos implementar o handler para o evento “Click” de cada um dos botões, onde faremos a exportação do relatório utilizando o formato escolhido:

        // C#
        private void pdfButton_Click(object sender, EventArgs e)
        {
            _relatorio.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, "relatorio2.pdf");
        }

        private void docButton_Click(object sender, EventArgs e)
        {
            _relatorio.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.WordForWindows, "relatorio2.doc");
        }
    ' VB.NET
    Private Sub pdfButton_Click(sender As Object, e As EventArgs) Handles pdfButton.Click
        Relatorio.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, "relatorio2.pdf")
    End Sub

    Private Sub docButton_Click(sender As Object, e As EventArgs) Handles docButton.Click
        Relatorio.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.WordForWindows, "relatorio2.doc")
    End Sub

Pronto! Execute a aplicação mostrando o formulário de exportação, clique em cada um dos botões e veja o resultado sendo gerado no diretório da aplicação:

Concluindo

Nesse artigo você conferiu tudo relacionado à exportação de relatórios do Crystal Reports, que, como você conferiu, é um processo muito simples. Em primeiro lugar, temos a opção de exportar diretamente no controle visualizador do Crystal Reports. Conseguimos, inclusive, escolher quais os formatos de exportação estarão disponíveis para o usuário. Além disso, temos também a opção de exportar os relatórios do Crystal Reports sem utilizar o controle visualizador, diretamente via código.

E você, já precisou exportar relatórios do Crystal Reports na sua aplicação? Sabia que dava para escolher os formatos de exportação disponíveis para o usuário? Como foi a sua experiência quanto à exportação de relatórios do Crystal Reports? Os arquivos gerados foram satisfatórios? Conte-nos os detalhes na caixa de comentários logo abaixo!

Antes de me despedir, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado, ficará sabendo em primeira mão sobre o artigo da próxima semana e receberá também dicas “bônus” que eu só compartilho por e-mail. Além disso, você já deve ter percebido que eu recebo muitas sugestões de temas e eu costumo dar prioridade às sugestões vindas de inscritos da minha newsletter. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Image by Jake Przespo used under Creative Commons
https://www.flickr.com/photos/jakeprzespo/4566115233/

Newsletter do André Lima

* indicates required



Powered by MailChimp

15 thoughts on “Como podemos exportar relatórios do Crystal Reports?

  • Jair Souza disse:

    Usando o visualizador do CR, como se faz para que sugira o nome do relatório na janela de exportar, tu sabe?
    Não acho nada na net…

    • andrealveslima disse:

      Olá Jair!

      É só configurar o nome que você quiser na propriedade SummaryInfo.ReportTitle:

      SeuReportDocument.SummaryInfo.ReportTitle = "NomeDoArquivo";
      

      Abraço!
      André Lima

      • Jair Souza disse:

        Olá, eu já tinha tentado esta linha de código, mas como estava depois de um messagebox não funcionava, agora coloquei antes do messagebox, funcionou, Valeu !

        Outra dúvida tem como especificar para que sugira salvar sempre na área de trabalho?

        • andrealveslima disse:

          Olá Jair!

          Que bom que deu certo! Quanto à pasta, acredito que não seja possível.. O componente do Crystal Reports usa o SaveFileDialog do Windows Forms e o comportamento padrão dele é sempre lembrar a última pasta onde o usuário salvou um arquivo.. A primeira vez vem na pasta “Meus Documentos”, as próximas vezes o componente sempre lembra a última pasta que o usuário selecionou.. Ou seja, se ele selecionar uma vez o Desktop e salvar alguma coisa lá, nas próximas vezes o componente sempre abrirá no Desktop automaticamente..

          Abraço!
          André Lima

          • Jair Souza disse:

            …mais uma dúvida, tem um form de filtro para pesquisa dos dados para o relatório,antes de abrir o visualizador do Crystal Report, tem com se ao filtrar não houverem os dados relativos a esta pesquisa, Não abrir o visualizador CR e mostrar um MessageBox ?

          • andrealveslima disse:

            Olá Jair!

            Depende.. Como você está fazendo para filtrar? Você está filtrando as informações na aplicação e só está mandando os dados já filtrados para o relatório? Ou você está mandando as informações de filtro via parâmetro e filtrando as informações somente no relatório?

            Abraço!
            André Lima

  • Jair Souza disse:

    Olá, é por parâmetro, assim :

    ReportDocument rd = new ReportDocument();
    rd.Load(@”C:\Sist Biblio\SLNSistBiblio\Sist Biblio\Relatorios_Crystal_Reports\RelEditoraNomeComeca.rpt”);
    ParameterField parametro = rd.ParameterFields[“nomeEditoraComeca”];
    parametro.CurrentValues.AddValue(this.NomeEditoraComeca);
    crystalRVEditoraNomeComeca.ReportSource = rd;

    • andrealveslima disse:

      Olá Jair!

      Hmm, dessa forma fica mais complicado.. A única opção que eu consigo pensar agora para solucionar essa demanda seria checar pala propria aplicação se o relatório vai exibir algum dado ou não.. Ou seja, fazer uma consulta direto no banco utilizando o mesmo filtro para ver se existe algum registro sendo retornado ou não.. Aí você só exibe o relatório se tiver algum registro retornado pelo banco..

      Abraço!
      André Lima

      • Jair Souza disse:

        Exatamente isto que fiz, por ser iniciante de aprendiz, não me dei conta disto antes.
        Valeu muito a sua ajuda !

        • Jair Souza disse:

          Se alguém vier a precisar ficou assim :

          private void btnGerarRel_Click(object sender, EventArgs e)
          {
          try
          {
          ConexaoAccess.Conectar();

          OleDbCommand comando = new OleDbCommand(“SELECT NomeDaEditora FROM Editora WHERE(NomeDaEditora LIKE ? + ‘%’)”, ConexaoAccess.conexao);

          comando.Parameters.AddWithValue(“@nome”, tbNomeComecaCom.Text);

          OleDbDataReader reader = null;

          reader = comando.ExecuteReader();

          if ((reader.HasRows) && (reader.Read()))
          {
          letra = “”;
          letra = tbNomeComecaCom.Text;

          FrmRelEditoraNomeComeca frmRelEditNomeComeca = new FrmRelEditoraNomeComeca();

          frmRelEditNomeComeca.NomeEditoraComeca = tbNomeComecaCom.Text.Trim();

          frmRelEditNomeComeca.ShowDialog();
          frmRelEditNomeComeca.Focus();
          }
          else
          {
          tbNomeComecaCom.Focus();
          tbNomeComecaCom.Select(tbNomeComecaCom.Text.Length, 0);
          tbNomeComecaCom.ForeColor = Color.Red;
          MessageBox.Show(“Não Há Dados para Seleção !”, “Atenção”, MessageBoxButtons.OK, MessageBoxIcon.Warning);
          reader.Close();
          ConexaoAccess.Desconectar();
          }
          }
          catch (Exception ex)
          {
          MessageBox.Show(“Não foi Possível Verificar !” + ex.Message, “Atenção”, MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
          }

          • andrealveslima disse:

            Olá Jair!

            Que bacana que você conseguiu resolver.. E muito obrigado por ter compartilhado o código aqui.. Sucesso aí pra você!

            Abraço!
            André Lima

  • hola esta genial este articulo, el problema que tengo es que no puedo filtrar mi base de datos, tengo una base de 10000 registro con access 2013 y cada uno aparece en una pagina así es como lo tengo hasta hay esta bien en el visor, pero si exporto, manda todos ha exportar los 10000 registro y mes gustaría que solo haga la cantidad indicada de registros, ejemplo: 1001 a 2000 registro o en el viso filtrar la cantidad de registro a mostrar

    • andrealveslima disse:

      Olá Victor!

      Para especificar um range de páginas, você precisa trabalhar com ExportOptions.. Você cria uma instância de PdfRtfWordFormatOptions, especifica o page range e depois chama o método “Export” passando a instância de ExportOptions.. Algo como (não testei esse código, uma vez que não estou com um ambiente com Crystal Reports instalado no momento):

      var exportOpts = new ExportOptions();
      var pdfRtfWordOpts = new PdfRtfWordFormatOptions();
       
      pdfRtfWordOpts.FirstPageNumber = firstPage; // numero da primeira página
      pdfRtfWordOpts.LastPageNumber = lastPage; // numero da última página
      pdfRtfWordOpts.UsePageRange = true; 
      Report.ExportOptions.FormatOptions = pdfRtfWordOpts; 
      Report.ExportOptions.ExportFormatType = ExportFormatType.RichText;
      
      Report.Export(exportOpts);
      

      Abraço!
      André Lima

  • Marcelo Strassburger disse:

    André,

    Preciso implementar dois botões no visualizador do relatório
    1. Para gerar exportar o pdf idêntico ao relatório mostrado nesse visualizador;
    2. Imprimir na impressora padrão o relatório mostrado.

    Em minhas tentativa:
    Caso 1 – Exporta através do método ExportToDisk, porém o pdf é gerado sem carregar os dados (no visualizador os dados aparecem corretamente)
    Caso 2 – Imprime pelo método PrinttoPrinter, porém a impressão é gerada sem carregar os dados (fica idêntico ao relatório em pdf do caso 1).

    O que está faltando fazer para carregar os dados se eles aparecem no visualizador?

    • andrealveslima disse:

      Olá Marcelo!

      Como é que ficou o seu código? Aparentemente está faltando carregar os dados na instância do relatório que você está utilizando para chamar os métodos..

      Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *