André Alves de Lima

Talking about Software Development and more…

Trabalhando com colunas no ReportViewer (para imprimir etiquetas)

Em aplicativos que contém algum tipo de catálogo de endereços, é muito comum termos a necessidade de imprimir etiquetas (para envelopes) com os nomes e endereços das pessoas desse catálogo. Para solucionar esse problema, o recomendado é que utilizemos alguma ferramenta de geração de relatórios. Se a sua ferramenta de geração de relatórios é o ReportViewer, é muito fácil implementar um relatório que imprima as etiquetas utilizando o conceito de colunas no ReportViewer. Esse é o tema do artigo de hoje.

Nos sistemas que eu trabalhei até hoje, eu nunca precisei imprimir etiquetas. Mas, acredito que deva ter sido pela natureza dos sistemas que eu trabalhei (por exemplo, sistemas relacionados com cargos e salários e sistemas relacionados ao ramo florestal). Em sistemas que possuem catálogo de endereços, é comum a necessidade de imprimirmos etiquetas.

Eu me atentei para essa realidade quando um dos inscritos da minha newsletter me questionou sobre a ordenação que o ReportViewer utiliza quando trabalhamos com o conceito de colunas (que é justamente como conseguimos imprimir etiquetas). Vou explicar melhor a dúvida desse inscrito mais adiante. A princípio, vamos criar um simples relatório para imprimirmos algumas etiquetas com o ReportViewer.

Criando o DataSet

Primeiramente, vamos criar um novo projeto do tipo “Windows Forms Application“. Nesse projeto, adicione um novo DataSet, que servirá de fonte de dados para o nosso relatório, ou seja, é nesse DataSet que teremos as informações das etiquetas que serão impressas. Como de costume, o item do tipo DataSet está presente dentro da categoria “Data”. Dê o nome de “DataSetEtiqueta” para o DataSet que será criado:

Dentro do DataSetEtiqueta, crie uma nova DataTable com o nome “Etiqueta” e os campos IDEtiqueta, Nome, Endereco, CEP, Cidade e Estado. Todos os campos devem ser do tipo string, exceto o campo IDEtiqueta, que deve ser do tipo auto incremento:

Note que nessa DataTable temos todos os atributos necessários para a geração das etiquetas. Provavelmente esses dados não estarão disponíveis no seu banco de dados exatamente dessa forma, mas, ao trabalharmos com relatórios, é sempre uma boa prática construirmos exatamente o DataSet necessário para o relatório e preenchermos esse DataSet com os dados vindos de outras tabelas do banco de dados.

Criando o relatório

Agora que temos o DataSet com a tabela “Etiqueta“, vamos criar um novo relatório do ReportViewer para exibirmos as informações dessas etiquetas. Adicione um item do tipo “Report” (que se encontra dentro da categoria “Reporting“), dando o nome de “ReportEtiqueta” para esse novo relatório:

Assim que o relatório tiver sido criado, vá até a página de propriedades, encontre a propriedade chamada “Columns” e altere o valor dessa propriedade para “2“:

Note que podemos também definir o espaçamento entre uma coluna e outra (o valor padrão é 0,13 cm). Normalmente, quando trabalhamos com etiquetas, é comum a utilização de folhas que já possuem as etiquetas de forma que possamos simplesmente retirá-las da folha e colá-las aonde quer que seja. Para que as etiquetas sejam impressas no lugar certo, você terá que configurar as propriedades “Columns” e “ColumnSpacing” de acordo com a folha de etiquetas que você estiver utilizando. Para esse exemplo, vou utilizar 2 colunas com o espaçamento padrão de 0,13 centímetros.

Quando você altera a propriedade “Columns“, note que o relatório apresentará a quantidade de colunas que você acabou de definir. No caso do nosso exemplo, conseguiremos visualizar duas colunas na área do relatório:

Você pode configurar o tamanho horizontal das colunas utilizando o “slider” (linha vertical cinza entre uma coluna e outra). Para ter uma noção precisa do tamanho de cada coluna, recomendo que você ative a régua do relatório através do menu de contexto:

Apesar de conseguirmos visualizar as duas colunas que configuramos anteriormente, só é possível adicionarmos controles na primeira coluna da esquerda. O ReportViewer fará automaticamente a quebra dos dados de uma coluna para a outra, seguindo primeiro na vertical (um registro abaixo do outro) e, quando a página tiver terminado, o ReportViewer começará a utilizar a segunda coluna, e assim por diante.

Uma vez configurado o layout inicial do relatório, adicione um controle do tipo “List” dentro da primeira coluna do relatório e configure o DataSet desse controle conforme a imagem a seguir:

Finalmente, arraste os campos do DataSet para dentro do controle “List” conforme podemos observar na imagem abaixo:

Para o campo relacionado às colunas “Cidade” e “Estado“, podemos criar um TextBox com uma expressão customizada (já que queremos mostrar “Cidade / Estado”). Veja como fica a fórmula para esse caso:

=Fields!Cidade.Value & " / " & Fields!Estado.Value

Além de configurar corretamente o tamanho das colunas e seu espaçamento, é importante que você configure também o tamanho da página e suas margens. Para isso, vá até o menu “Report” e escolha a opção “Report Properties“. Na janela “Report Properties“, configure o tamanho da página e margens (eu configurei um tamanho qualquer de forma que quatro etiquetas fossem exibidas por página):

Exibindo o relatório

Uma vez criado o relatório, temos que exibi-lo. Vá até o “Form1” criado automaticamente pelo Visual Studio e, de preferência, altere o seu nome para algo que faça mais sentido (como “FormEtiqueta“). Feito isso, adicione um controle do ReportViewer no formulário e configure-o para que ele ocupe a tela toda (“Dock in parent container” na “smart tag” do controle). Por fim, na “smart tag” do controle do ReportViewer, abra a caixa de opções “Choose Report” e escolha o relatório que criamos anteriormente (ReportEtiqueta):

Após ter selecionado o relatório, vá até o code-behind do formulário, encontre o método “Load” e adicione algumas linhas na tabela “Etiqueta” (obviamente, em situações reais, esses dados deveriam ser carregados de um banco de dados):

        private void FormEtiqueta_Load(object sender, EventArgs e)
        {
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("André Alves de Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Larissa Aldine Müller Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Sophie Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Fulano de Tal", "Praça da Matriz", "13480-000", "Limeira", "SP");

            this.reportViewer.RefreshReport();
        }

Execute a aplicação e veja o resultado:

Notou como ficou esquisito e as colunas nem foram utilizadas? Na realidade elas foram. O que acontece é que, por padrão, o ReportViewer exibe o preview em um modo que não é o de impressão (e que, na realidade, ninguém entende como funciona). Para ver o resultado final, você precisa alterar para o modo de impressão, clicando no botão “Print Layout“:

Aí sim o resultado fará muito mais sentido:

Caso você queira fazer com que o modo de impressão seja exibido por padrão, basta utilizar o método “SetDisplayMode” passando o “PrintLayout” antes da chamada de “RefreshReport” no método “Load” do formulário (dica extraída deste tópico nos fóruns da MSDN):

        private void FormEtiqueta_Load(object sender, EventArgs e)
        {
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("André Alves de Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Larissa Aldine Müller Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Sophie Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW");
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Fulano de Tal", "Praça da Matriz", "13480-000", "Limeira", "SP");

            this.reportViewer.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.PrintLayout);
            this.reportViewer.RefreshReport();
        }

Alterando a ordem das etiquetas

Lembra que, no começo do artigo, eu disse que um inscrito tinha me questionado sobre a confecção de etiquetas no ReportViewer? Pois bem, uma dúvida que ele tinha era como alterar a ordem de impressão das etiquetas. Como você pode perceber, a ordem que o ReportViewer estabelece é que as etiquetas serão impressas primeiramente na horizontal e, quando a primeira coluna estiver totalmente preenchida, ele começará a utilizar a segunda coluna, e assim por diante.

Porém, o inscrito queria que as etiquetas fossem geradas seguindo a ordem horizontal, de forma que os registros fossem exibidos da seguinte maneira:

Após pesquisar um pouco, acabei concluindo que não é possível escolhermos nativamente no ReportViewer a ordenação desejada por esse inscrito. Mas, de qualquer forma, é possível implementarmos essa ordenação de forma manual. Para isso, temos que adicionar uma nova coluna à tabela Etiqueta, chamada “Ordenacao“, utilizando o tipo “Int32“:

Feito isso, preenchemos os valores dessa coluna com valores de forma que o mecanismo do ReportViewer seja enganado e exiba as etiquetas utilizando a nova ordenação:

            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("André Alves de Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW", 1);
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Larissa Aldine Müller Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW", 3);
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Sophie Lima", "Somewhere in Bad Waldsee", "88339", "Bad Waldsee", "BW", 2);
            DataSetEtiqueta.Etiqueta.AddEtiquetaRow("Fulano de Tal", "Praça da Matriz", "13480-000", "Limeira", "SP", 4);

Agora só falta configurarmos a ordenação da lista no relatório de forma que ela obedeça essa nova coluna. Para isso, vá até o relatório e, dentro da janela “Report Data“, clique com o botão direito no DataSetRelatorio e escolha a opção “Refresh“:

Com isso, o relatório reconhecerá essa nova coluna. Por fim, clique com o botão direito no canto superior esquerdo do controle “List” e escolha a opção “Tablix Properties” no menu de contexto:

Na janela “Tablix Properties“, vá até a categoria “Sorting” e adicione a coluna “Ordenacao” na lista:

Pronto! Dessa forma o relatório obedecerá a nova ordenação que estabelecemos manualmente.

A lógica para numeração da coluna “Ordenacao” dependerá da quantidade de colunas e da quantidade de etiquetas por coluna, mas, acho que deu para entender a ideia, não é mesmo?

Concluindo

A criação de relatórios para impressão de etiquetas com o ReportViewer não é complicada. Uma vez que sabemos onde as propriedades se encontram e como funciona a lógica que o ReportViewer utiliza para exibir os registros, tudo fica mais simples.

Nesse artigo você aprendeu como criar um relatório simples para a impressão de etiquetas utilizando a funcionalidade de colunas no ReportViewer. Além disso, respondi a dúvida de um inscrito sobre como criar uma ordenação customizada pra as etiquetas. Caso você queira conferir um outro artigo sobre a geração de etiquetas no ReportViewer, confira o artigo que eu utilizei como referência.

Finalmente, caso você queira ficar por dentro das novidades do meu site, além de receber dicas que eu só compartilho por e-mail, inscreva-se na minha newsletter utilizando este link ou o formulário logo abaixo.

Até a próxima!

André Lima

Photo by mpclemens used under Creative Commons
https://www.flickr.com/photos/mpclemens/5670381076/

Newsletter do André Lima

* indicates required



Powered by MailChimp

28 thoughts on “Trabalhando com colunas no ReportViewer (para imprimir etiquetas)

  • Thiago Ramos disse:

    Boa tarde André,
    muito legal esse post, ajuda a esclarecer bastante. Estou com uma dificuldade e não sei se poderia me ajudar.
    Como faço para utilizar uma imagem nesse report? Essa imagem é criada a todo momento que rodo a aplicação, sempre com o mesmo nome e o mesmo diretório. Coloquei o componente image para receber de forma externa, por parâmetro, onde nele eu passo o caminho da imagem, mas a imagem fica com um “x” como se não existisse.

    • andrealveslima disse:

      Olá Thiago, muito obrigado pelo comentário!

      Eu já escrevi sobre o carregamento de imagens através de um caminho em disco no Report Viewer, não sei se você já viu:

      http://www.andrealveslima.com.br/blog/index.php/2014/10/28/exibindo-imagem-a-partir-de-um-caminho-em-disco-no-report-viewer/

      Será que você não esqueceu de alterar a propriedade EnableExternalImages para true? O default é false.. Antes da chamada de RefreshReport no seu Form, inclua essa alteração e veja se funciona:

      this.reportViewer1.LocalReport.EnableExternalImages = true;

      Abraço!
      André Lima

      • Thiago Ramos disse:

        Boa noite,

        obrigado pela resposta.

        Já havia colocado para aceitar imagem externa sim, mas não deu certo, não consegui resolver usando o reportviewer, o jeito que encontrei foi desenhar a etiqueta usando drawimage e printdocument.
        Resolvi o problema, mas ficou a curiosidade do erro. De qualquer forma obrigado pela resposta.

        • andrealveslima disse:

          Olá Thiago,

          Que coisa estranha hein.. Infelizmente, sem maiores detalhes, eu não tenho ideia do que possa ser.. Mas, pelo menos você conseguiu resolver o problema de uma outra forma..

          Abraço!
          André Lima

          • Robson Arruda disse:

            Estava tentando fazer um relatório que usasse a quebra na mesma página e acabei encontrando aqui! Muito obrigado, resolveu meu problema!

            E sobre a dúvida do colega acima, estava com um probleminha assim…
            solução:
            adiciona no (fx) da imagem o código: =”File://” & Fields…

            Meu problema foi resolvido assim.
            Boa sorte!

          • andrealveslima disse:

            Olá Robson, obrigado pelo comentário!

            Fico feliz que você tenha conseguido solucionar o seu problema! E muito obrigado por ter complementado a resposta da questao acima..

            Abraco!
            Andre Lima

      • Rômulo Vicente dos Reis disse:

        Ola Andre Lima, tudo bem, bom dia.
        Tenho uma duvida e gostaria de compartilhar aqui pra ver se vc ou alguem me ajuda.
        Tenho um Relatori em ReportViewer VB onde traz todos os dados dos alunos cadastrados que tenho, minha duvida no form teria como colocar um check botão que ao precionar ocutaria determinada coluna no relatorio para que eu possa imprimir o relatorio com os dados que eu quiser no momento??? Se vc puder me ajudar agradeço.

        • andrealveslima disse:

          Olá Rômulo!

          Você pode criar parâmetros no seu relatório que farão o controle se a coluna estará visível ou não.. Aí você manda os valores para esse parâmetro da sua aplicação para o relatório.. Para esconder ou exibir colunas a partir do valor de um parâmetro, você só precisa configurar uma expressão para a opção “Column visibility” da coluna do Tablix, conforme explicado nesta thread do StackOverflow:

          Hide columns dynamically in rdlc report

          Abraço!
          André Lima

  • Ricardo Luiz disse:

    Olá Thiago, estou tentando desenvolver a impressão de etiquetas utilizando o ReportViewer mas ASP.NET. Não existe a propriedade SetDisplayMode para WebForm. Com isso todo o impresso só aparece na primeira coluna. Existe algo equivalente para utilizar o modo PrintLayout para WebForm ?

    • andrealveslima disse:

      Olá Ricardo, obrigado pelo comentário!

      Realmente não existe o método SetDisplayMode no web forms.. Nesse caso, a impressão é feita diretamente pelo browser.. Quando você escolhe imprimir pelo browser, o relatório vem com as colunas ou não? O certo é ele vir com as colunas..

      Talvez para web forms faça mais sentido não mostrar o preview, mas sim, gerar o relatório em formato PDF e exibir no browser.. Dessa forma, o layout do PDF gerado já será o layout de impressão (teoricamente, com as colunas e as etiquetas no seu devido lugar)..

      Aqui tem um exemplo de geração de PDF via Report Viewer no ASP.NET:

      Create a PDF using the .Net ReportViewer control

      Abraço!
      André Lima

      • Alisson Cabral disse:

        Meu projeto é em ASP.NET MVC e o meu pdf faz uma lista e não as colunas.
        Segui todos os passos mencionados e até comprei o e-book, mas não consegui gerar em colunas.

        • andrealveslima disse:

          Olá Alisson!

          Você já tentou imprimir o relatório? O que acontece é que, como eu mencionei no artigo, a engine do Report Viewer só exibe o layout de colunas no modo de impressão.. No Windows Forms você pode alternar entre o modo de visualização e o modo de impressão.. Porém, no Web Forms você não tem um modo de impressão (somente o de visualização).. Provavelmente ao imprimir o relatório você verá que o Report Viewer irá considerar o layout de colunas que você configurou no seu rdlc..

          Se você realmente tiver que exibir o relatório já em modo de impressão, eu recomendo que você gere o PDF do relatório e exiba esse PDF para o usuário, ao invés de utilizar o controle exibidor do Report Viewer.. Dessa forma, no PDF gerado, as colunas serão consideradas e o resultado será conforme o que você está esperando..

          Caso você não saiba como gerar o PDF do relatório, nesta thread do StackOverflow tem um exemplo:

          Creating a PDF from a RDLC Report in the Background

          Se você ainda tiver ficado com alguma dúvida relacionada a esse assunto, é só responder aqui ou entrar em contato por e-mail explicando o ponto em que você está tendo dificuldade..

          Abraço!
          André Lima

          • Alisson Cabral disse:

            Te enviei um e-mail explicando os passos realizados juntamente com um vídeo demonstrando o que foi feito.
            Agradeço.

          • andrealveslima disse:

            Olá Alisson!

            Eu respondi o seu e-mail.. Veja lá se você conseguiu entender.. Qualquer coisa entre em contato novamente!

            Abraço!
            André Lima

  • Thiago disse:

    Muito bom o artigo André, mas estou com uma dúvida.

    Fiz como descrito só que etiquetas estão sendo preenchidas na vertical e quando completa passa para a outra coluna.

    Há alguma forma de elas serem preenchidas na horizontal (colunas) e depois de completas saltarem para a linha de baixo?

    • andrealveslima disse:

      Olá Thiago, obrigado pelo comentário!

      Você chegou a dar uma olhada no artigo na seção “Alterando a ordem das etiquetas”? Eu falo exatamente sobre esse problema.. Eu acredito que a alternativa apresentada vai te ajudar a resolver esse seu problema da ordem das etiquetas.. Dá uma olhada lá e me avisa depois se funcionou..

      Abraço!
      André Lima

      • Thiago disse:

        Funcionou sim, muito obrigado.

        Mas surgiu outra dúvida, que seria o seguinte:

        Tenho dois relatórios distintos, e gostaria de uni-los para exibir no report viewer, é possível?

        • andrealveslima disse:

          Olá Thiago!

          Que bom que funcionou.. Para exibir dois relatórios, você poderia criar um outro relatório “mestre” para servir de placeholder dos dois relatórios “filhos”.. No relatório mestre você só teria dois sub-reports, um apontando para o relatório 1 e outro apontando para o relatório 2.. Sacou?

          Se você não entendeu, manda no meu e-mail (contato arroba andrealveslima ponto com ponto br) um projetinho a parte com os seus dois relatórios que eu tento te explicar de outra forma..

          Abraço!
          André Lima

  • Nz_Silva disse:

    Olá Sr. Lima!

    Parabéns por este “Artigo irrepreensível”, simples e claro. Ajudou-me bastante…

    Abraços!

  • Vitor Rorigues disse:

    Ola André. Segue seu exemplo para criar etiquetas e fiz um modelo de 3 Colunas para impressora argox. Quando visualizo mostra normal, porém ao imprimir a mesma só imprime na vertical e não na horizontal. Saberia o que poderia ser? Desde já muito obrigado

    • andrealveslima disse:

      Olá Vitor!

      Estranho hein.. Você ainda está com esse problema? Será que não está com alguma coisa errada no tamanho da página? O relatório é exibido corretamente tanto em modo layout quanto em modo impressão? Você já tentou exportar para PDF para ver o resultado?

      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 *