André Alves de Lima

Talking about Software Development and more…

Trabalhando com código de barras no Report Viewer

Um dos assuntos mais requisitados com relação ao Report Viewer é a questão da utilização de código de barras nos relatórios. Como é que podemos exibir código de barras no Report Viewer?

Pois bem, no vídeo de hoje eu vou mostrar para você as duas opções que nós temos para exibirmos código de barras nos nossos relatórios do Report Viewer. A primeira opção será através de uma fonte de código de barras. Já a segunda opção será a geração da imagem do código de barras e envio dessa imagem pronta para o relatório. Assiste aí e depois me conta o que você achou:

Opção 1: Utilizando fonte de código de barras

Uma opção que podemos empregar para exibirmos código de barras nas nossas aplicações (tanto nos relatórios como nas telas) é a utilização de fontes de código de barras. Muitos tipos de códigos de barras (se você ainda não sabe, existem inúmeros tipos diferentes) possuem fontes que podem ser instaladas e convertem automaticamente texto em código de barras. Por exemplo, se pesquisarmos por “free barcode 128 font” no Google (128 é um tipo de código de barras, talvez o mais conhecido), encontraremos muitas opções que podemos utilizar:

Para testar essa sistemática, eu baixei a fonte “Code 128” do site dafont.com. Uma vez instalada, nós podemos simplesmente formatar um TextBox do relatório escolhendo essa fonte:

Veja só o resultado:

Dependendo do tipo de código de barras, você encontrará facilmente fontes gratuitas na internet. Caso você não encontre, aí você terá que partir para a segunda opção.

Opção 2: Enviando imagem do código de barras para o relatório

A segunda opção que temos para exibirmos código de barras no Report Viewer é a geração de uma imagem com o código de barras no lado da aplicação e o envio dessa imagem pronta para o relatório. Isso quer dizer que nós teremos que criar uma nova coluna do tipo “byte[]” na DataTable que está alimentando o relatório (ou uma nova propriedade, caso você esteja alimentando o relatório através de classes e não através de DataTables). Vamos dar o nome de “ImagemCB” (imagem do código de barras) para essa nova coluna:

Feito isso, temos que dar um “refresh” nos campos do DataSet do relatório para que a nova coluna apareça:

Agora nós podemos adicionar uma nova coluna na nossa tabela do relatório e, dentro dessa coluna, nós colocaremos um controle do tipo “Image“:

Nas propriedades da imagem, nós temos que configurar que o conteúdo dela virá do banco de dados (opção “Database“) e a coluna correspondente é a “ImagemCB” (que é justamente a nova coluna que criamos anteriormente):

Vamos também configurar o tamanho da imagem para que ela seja automaticamente redimensionada para caber na célula da tabela, além de adicionarmos um “padding” para que o código de barras não saia grudado nas bordas da célula:

Agora que nós já preparamos o nosso relatório para que a imagem do código de barras seja exibida, como é que nós fazemos para gerarmos a imagem para cada produto? Simples, nós utilizaremos uma biblioteca que já implementa essa funcionalidade!

A biblioteca open source mais conhecida que eu encontrei para geração de códigos de barras no .NET é a BarcodeLib. O código fonte dessa biblioteca está disponível no GitHub e você encontra os releases dela no NuGet também. Além do “Code 128“, ela suporta também outros formatos conhecidos de código de barras.

Para utilizá-la no nosso projeto, vamos adicionar uma referência através do NuGet:

A chamada para gerarmos uma imagem do código de barras com a biblioteca BarcodeLib é muito simples. Nós só temos que chamar o método “Encode” passando o tipo de código de barras e o conteúdo dele. Porém, como o relatório está esperando um array de bytes com a imagem, nós temos que converter o retorno da biblioteca (que será uma instância de “Image“). Para isso, eu utilizei o método “ImageToByteArray” que eu encontrei nesta thread do StackOverflow. Veja como é que fica o código completo:

// C#
private void Form1_Load(object sender, EventArgs e)
{
	using (var bc = new BarcodeLib.Barcode())
	{
		this.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 1", "12345", ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, "12345")));
		this.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 2", "23456", ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, "23456")));
		this.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 3", "34567", ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, "34567")));
		this.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 4", "45678", ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, "45678")));
		this.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 5", "56789", ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, "56789")));
	}

	this.reportViewer1.RefreshReport();
}

public static byte[] ImageToByteArray(System.Drawing.Image image)
{
	using(var ms = new MemoryStream())
	{
		image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
		return ms.ToArray();
	}
}
    ' VB.NET
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Using Bc = New BarcodeLib.Barcode()
            Me.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 1", "12345", ImageToByteArray(Bc.Encode(BarcodeLib.TYPE.CODE128, "12345")))
            Me.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 2", "23456", ImageToByteArray(Bc.Encode(BarcodeLib.TYPE.CODE128, "23456")))
            Me.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 3", "34567", ImageToByteArray(Bc.Encode(BarcodeLib.TYPE.CODE128, "34567")))
            Me.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 4", "45678", ImageToByteArray(Bc.Encode(BarcodeLib.TYPE.CODE128, "45678")))
            Me.DataSetRelatorio.DataTableProduto.AddDataTableProdutoRow("Produto 5", "56789", ImageToByteArray(Bc.Encode(BarcodeLib.TYPE.CODE128, "56789")))
        End Using

        Me.ReportViewer1.RefreshReport()
    End Sub

    Public Shared Function ImageToByteArray(Image As System.Drawing.Image) As Byte()
        Using Ms = New MemoryStream()
            Image.Save(Ms, Imaging.ImageFormat.Png)
            Return Ms.ToArray()
        End Using
    End Function

Execute a aplicação e confira o resultado:

Mas pera aí, por que os códigos não são iguais?

Uma coisa que você pode estar se perguntando é: se os códigos são iguais, porque o resultado é diferente com a fonte? Veja só, se dermos um zoom no relatório nós conseguiremos observar melhor a diferença:

Isso acontece porque o “Code 128” não é somente uma conversão direta de texto em código de barras. Como você pode conferir na Wikipedia, tem toda uma lógica que nós teríamos que seguir na hora de construirmos a string que deverá ser exibida com a fonte (como, por exemplo, caracteres de inicialização e finalização, além do “caractere verificador“). Se você quiser saber mais a respeito da geração da string para o “Code 128“, dê uma olhada nestes links:

Code 128/GS1-128 Barcode FAQ & Tutorial

Code 128 Check Character Calculation Examples

E se você quiser testar a geração de códigos de barras, existem inúmeros sites que fazem isso gratuitamente, como estes aqui:

Online Barcode Generator

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Concluindo

No artigo de hoje você conferiu duas maneiras de exibirmos código de barras no Report Viewer. A primeira delas foi através de uma fonte. Já a segunda opção foi a geração da imagem do código de barras no lado da aplicação e envio da mesma para o relatório através do DataSet.

E você, já precisou trabalhar com código de barras na sua aplicação? Como é que você resolveu essa demanda? Trabalhou com uma fonte ou alguma biblioteca para geração dos códigos? Estou curioso para saber mais sobre as suas experiências na caixa de comentários logo abaixo!

Até a próxima!

André Lima

Photo by Pixabay used under Creative Commons
https://pixabay.com/en/startup-start-up-notebooks-creative-593327/

Image by Pixabay used under Creative Commons
https://pixabay.com/en/tax-forms-income-business-468440/

Song Rocket Power Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 3.0 License
http://creativecommons.org/licenses/by/3.0/

Newsletter do André Lima

* indicates required



Powered by MailChimp

20 thoughts on “Trabalhando com código de barras no Report Viewer

  • Claudio disse:

    Excelente,parabéns

  • deuzivaldo disse:

    Bom dia professor muito bom parabéns
    Há um tempo eu comprei um curso completo do professor Mario Andrade que ensinava a criar carteirinhas com foto e código de barra no visual studio 2006
    gostaria de fazer no vb.net 2011 e o que eu estou usando agora,tem mita diferencia de um para o outro,e se você tem algo por onde eu posa começar

    • andrealveslima disse:

      Olá Deuzivaldo!

      Não sei se teria muita diferença entre as versões do curso e da versão que você está utilizando agora.. Minha sugestão seria tentar implementar o conteúdo do curso e, caso surja alguma dificuldade, entre em contato que eu tento ajudar.. Ou tente se basear nesse meu artigo sobre código de barras no Report Viewer para implementar a mesma funcionalidade..

      Abraço!
      André Lima

  • Antonio disse:

    Parabéns André! òtimo artigo e vídeo.

    Se possível você poderia me dizer como implementa o código desse artigo usando o Foreach como voc~e disse no vídeo no lugar da alimentação manual do relatório? Já pesquisei e não consegui essa implementação. Grato desde já pela colaboração.

    • andrealveslima disse:

      Olá Antonio, obrigado pelo comentário!

      Não tem muito segredo.. Primeiro você precisa carregar os dados do banco em uma DataTable, inclusive o número do código de barras de cada registro.. Depois, você faz um foreach nas linhas dessa DataTable, preenchendo a imagem do código de barras em cada linha.. Exemplo:

      var dataTable = CarregarDadosDoBanco(); // Aqui você tem que carregar os dados do banco e retornar eles em uma DataTable...
      dataTable.Columns.Add("ImagemCB", typeof(byte[]));
      using (var bc = new BarcodeLib.Barcode())
      {
      	foreach (DataRow linha in dataTable.Rows)
      	{
      		linha["CodigoCB"] = ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, linha["ValorDoCodigoDeBarras"]));
      	}
      }
      

      Abraço!
      André Lima

  • Danilo Vasconcelos disse:

    Sei que não tem relação com a postagem acima, mas to precisando de ajuda. Eu fiz os procedimentos do video em que vc ensina ativar o report viewer ontem e parecia ter dado td certo, mas decidi começar mexer no report viewer hj, só que agr não consigo achar mais nada no visual studio relacionado a report viewer, não aparece na toolbox e nem na hora de adicionar um novo item. Já tentei desinstalar e instalar novamente mas não resolveu nada, poderia me ajudar?
    Vlw, agradeço desde ja!

    • andrealveslima disse:

      Olá Danilo!

      Já respondi lá no seu comentário do Youtube.. Você adicionou o Report Viewer nesse seu projeto pelo NuGet? Adicionou novamente ele na ToolBox? Não tem muito segredo.. Seguindo o tutorial é pra funcionar..

      Ah, vamos continuar a discussão ou aqui ou no Youtube (e não nos dois lugares), para evitar duplicação de conteúdo, OK?

      Abraço!
      André Lima

  • Adeilton Pessini disse:

    Olá boa tarde,
    Estou precisando pegar uma valor existente em um banco de dados converte-lo para código de barras e mostrar no Report, poderia me ajudar?
    Estou usando VB.NET

    • andrealveslima disse:

      Olá Adeilton!

      Mas foi justamente isso que eu mostrei no vídeo (tirando a parte de pegar o valor do banco de dados).. Em qual parte você está com dificuldade exatamente?

      Abraço!
      André Lima

  • Adeilton Pessini disse:

    Então você fez a inserção manual de valores no dataset, queria saber como eu pego um valor da referente ao meu banco de dados e converto ele, por exemplo a coluna codigo da minha tabela no banco de dados!

    • andrealveslima disse:

      Olá Adeilton!

      Não tem segredo.. É só você pegar os dados do banco (com um “ExecuteReader” do ADO.NET, por exemplo) e adicionar esses registros em uma DataTable em memória.. Nessa DataTable, você adiciona uma outra coluna que guardará a imagem do código de barras.. Aí é só aplicar a sistemática que eu demonstrei no artigo para gerar os códigos de barras..

      Em qual parte exatamente você está tendo dificuldade? Você já consegue pelo menos pegar as informações originais do banco de dados e armazenar em uma DataTable em memória? Ou você está com dificuldade nessa parte também?

      Abraço!
      André Lima

  • Manoel disse:

    Obrigado! Parabéns pela ótima aula.

  • Kayo Melo disse:

    Olá André, tudo bem? Só queria deixar um comentário pois pode ser que alguém passe pelo mesmo… No meu caso, as informações era um pouco maiores (A1131121800001001 – 17 caracteres) e o método acima funciona mas na hora de o leitor de código de barras ler, não conseguia identificar o código. Pra isto, tive que acrescentar mais 4 informações (2 importantes): Cor das colunas, cor do fundo, altura e largura. O mínimo no comprimento é 150, no caso do 190 como coloquei ficou muito bom a leitura.

    No RDLC o retângulo ou imagem que irá exibir o código usei a dimensão: 10,68cm; 1,35cm

    …ImageToByteArray(bc.Encode(BarcodeLib.TYPE.CODE128, “NumeroAConverter.Text”, Color.Black, Color.White, 190, 40));

    Forte abraço.

    • andrealveslima disse:

      Olá Kayo!

      Muito obrigado pela dica! Valeu por vir aqui nos comentários e contar como você conseguiu resolver.. Com certeza vai ajudar outras pessoas que passarem pelo mesmo problema..

      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 *