.NET - Gerando o código de Barras 128C (NFe)


O código de barras 128 é um código de barras alfanumérico de alta densidade. Os símbolos podem ser tão longos quanto necessários para armazenar os dados codificados. Ele foi projetado para codificar todos os 128 caracteres ASCII e pode ser usado em uma grande variedade de aplicações.

O código de barras 128 C é uma simbologia linear numérica utilizado em Nota Fiscal Eletrônica (NFe) / DANFE. Esta simbologia inclui um dígito verificador, e o código de barras também pode ser verificado caractere por caractere por meio de paridades.

Obs: A Nota Fiscal Eletrônica (NFe) é o modelo nacional de documento fiscal eletrônico que substituirá gradativamente a emissão do documento fiscal em papel, com validade jurídica garantida pela assinatura digital do remetente.

Eu não pretendo entrar em detalhes técnicos sobre o assunto, para isso deixo as referências, meu objetivo é mostrar como gerar o código de barras usando uma library já pronta e assim poupar o seu trabalho.

O nosso colega Brad Barnhill desenvolveu uma livraria de código que você pode usar para gerar o código de barras 128C , dentre outros.

Não há segredo , o artigo original pode ser visto aqui : Barcode Image Generation Library.

No link do artigo você também pode baixar a livraria e um código fonte que mostrar como gerar diversos tipos de código de barras. (Recomendo que você baixe os arquivos do site indicado mas se estiver com problemas você pode pegar a livraria aqui : Barcode_bin2.zip - 29.47 KB )

Eu vou mostrar neste artigo como usar a livraria para gerar o código de barras 128C usado na NFe.

A utilização da livraria não tem segredo veja a seguir os comandos usados para as tarefas básicas:

1- Gerar um código de barras padrão 128c para um valor informado;

Dim Barcode As New BarcodeLib.Barcode('1023948487474', BarcodeLib.TYPE.CODE128C)

2- Exibir a imagem do código de barras gerado em um controle PictureBox com largura 300 e altura 150;

PictureBox2.Image = Barcode.Encode(BarcodeLib.TYPE.CODE128C, 1023948487474', 300, 150)

3- Salvar a imagem gerada como codBar128C.jpg na pasta c:\dados

Barcode.SaveImage("C:\dados\codBar128C.jpg", BarcodeLib.SaveTypes.JPG)

Nota: Você pode obter a imagem gerada e armazenar em uma fonte de dados como um DataSet . Supondo que você tenha um DataSet com um campo chamado ImagemCodBar do tipo byte , para obter a imagem gerada e salvar no DataSet faça assim:

'ler imagem gerada
Dim fs As New FileStream("C:\dados\codBar128C.jpg", FileMode.Open)
Dim br As New BinaryReader(fs)
'salvar imagem no dataset
rowds.Imagem = br.ReadBytes(br.BaseStream.Length)
 

Gerando o código de barras 128C No VB .NET

Após baixar o arquivo da livraria para gerar o código de barras descompacte a DLL em uma pasta na sua máquina local.

Abra o seu Visual Basic 2008 Express e crie um projeto do tipo Windows Forms Application com o nome gerandoCodBar128c;

A seguir a partir do menu Project -> Add Reference , vamos incluir uma referência a livraria no nosso projeto;

Na janela Add Reference selecione Browse e localize a pasta onde você descompactou a dll da livraria , selecione-a e clique em OK;

A seguir no formulário padrão form1.vb inclua os controles : TextBox, GroupBox , Button e PictureBox conforme o leiaute da figura abaixo:

Baseado no código fonte de demonstração eu estou mostrando no exemplo como gerar a imagem do código de barras, salvar a imagem e salvar o XML para a imagem gerada usando a linguagem VB .NET.

No início do formulário declare o código que cria uma instância da classe Barcode();

Dim b As New BarcodeLib.Barcode()

No evento Load do formulário defina o código abaixo:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


Dim
temp As New Bitmap(1, 1)

temp.SetPixel(0, 0, Me.BackColor)

codBarImagem.Image = DirectCast(temp, Image)


End
Sub

No evento Click do botão Gerar temos o código que gera a imagem para o código de barras e também a sua codificação;

  Private Sub btnGerarCodBar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGerarCodBar.Click
        Dim W As Integer = Convert.ToInt32(Me.txtLargura.Text.Trim())
        Dim H As Integer = Convert.ToInt32(Me.txtComprimento.Text.Trim())
        Dim tipo As BarcodeLib.TYPE = BarcodeLib.TYPE.UNSPECIFIED
       tipo = BarcodeLib.TYPE.CODE128C

        Try
            If tipo <> BarcodeLib.TYPE.UNSPECIFIED Then
                '===== gera a imagem para o codigo de barras =====
                codBarImagem.Image = b.Encode(tipo, Me.txtValorCodBar.Text.Trim(), Color.Black, Color.White, W, H)
                '===================================
                'mostra o código gerado 
                txtCodigoCodBar.Text = b.EncodedValue
            End If
            codBarImagem.Width = codBarImagem.Image.Width
            codBarImagem.Height = codBarImagem.Image.Height
            'reposiciona a imagem 
            'codBarImagem.Location = New Point((Me.GroupBox2.Location.X + Me.GroupBox2.Width / 2) - codBarImagem.Width / 2, _
 (Me.GroupBox2.Location.Y + Me.GroupBox2.Height / 2) - codBarImagem.Height / 2)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

 

Observe que eu estou definindo as cores da imagem de forma fixa: texto = Black e fundo = White;

Para salvar a imagem gerada inclua o código abaixo no evento CLick do botão Salvar Imagem;

 Private Sub btnSalvarImgCodBar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvarImgCodBar.Click

        Dim sfd As New SaveFileDialog()
        sfd.Filter = "BMP (*.bmp)|*.bmp|GIF (*.gif)|*.gif|JPG (*.jpg)|*.jpg|PNG (*.png)|*.png|TIFF (*.tif)|*.tif"
        sfd.FilterIndex = 2
        sfd.AddExtension = True

        If sfd.ShowDialog() = DialogResult.OK Then
            Dim salvartipo As BarcodeLib.SaveTypes = BarcodeLib.SaveTypes.UNSPECIFIED
            Select Case sfd.FilterIndex
                Case 1
                    ' BMP 
                    salvartipo = BarcodeLib.SaveTypes.BMP
                    Exit Select
                Case 2
                    ' GIF 
                    salvartipo = BarcodeLib.SaveTypes.GIF
                    Exit Select
                Case 3
                    ' JPG 
                    salvartipo = BarcodeLib.SaveTypes.JPG
                    Exit Select
                Case 4
                    ' PNG 
                    salvartipo = BarcodeLib.SaveTypes.PNG
                    Exit Select
                Case 5
                    ' TIFF 
                    salvartipo = BarcodeLib.SaveTypes.TIFF
                    Exit Select
                Case Else
                    Exit Select
            End Select
            'switch
            b.SaveImage(sfd.FileName, salvartipo)
        End If
    End Sub

Finalmente, se você desejar salvar o arquivo XML correspondente a imagem gerada use o código abaixo no evento Click do botão Salvar XML;

Private Sub btnSalvarXmlCodBar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvarXmlCodBar.Click
        btnGerarCodBar_Click(sender, e)
        Using sfd As New SaveFileDialog()
            sfd.Filter = "XML Files|*.xml"
            If sfd.ShowDialog() = DialogResult.OK Then
                Using sw As New System.IO.StreamWriter(sfd.FileName)
                    sw.Write(b.XML)
                End Using
            End If
        End Using
    End Sub

O projeto em execução pode ser visto na figura a seguir onde temos a imagem do código de barras e seu código:

O código do arquivo XML salvo para a imagem correspondente é :

<BarcodeXML xmlns="http://tempuri.org/BarcodeXML.xsd">
- <xs:schema id="BarcodeXML" targetNamespace="http://tempuri.org/BarcodeXML.xsd" xmlns:mstns="http://tempuri.org/BarcodeXML.xsd" xmlns="http://tempuri.org/BarcodeXML.xsd" _
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
- <xs:element name="BarcodeXML" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="Barcode">
- <xs:complexType>
- <xs:sequence>
  <xs:element name="Type" type="xs:string" minOccurs="0" /> 
  <xs:element name="RawData" type="xs:string" minOccurs="0" /> 
  <xs:element name="EncodedValue" type="xs:string" minOccurs="0" /> 
  <xs:element name="EncodingTime" type="xs:double" minOccurs="0" /> 
  <xs:element name="IncludeLabel" type="xs:boolean" minOccurs="0" /> 
  <xs:element name="Forecolor" type="xs:string" minOccurs="0" /> 
  <xs:element name="Backcolor" type="xs:string" minOccurs="0" /> 
  <xs:element name="CountryAssigningManufacturingCode" type="xs:string" minOccurs="0" /> 
  <xs:element name="ImageWidth" type="xs:int" minOccurs="0" /> 
  <xs:element name="ImageHeight" type="xs:int" minOccurs="0" /> 
- <xs:element name="Image" minOccurs="0">
- <xs:simpleType>
- <xs:restriction base="xs:string">
  <xs:maxLength value="10000000" /> 
  </xs:restriction>
  </xs:simpleType>
  </xs:element>
  </xs:sequence>
  </xs:complexType>
  </xs:element>
  </xs:choice>
  </xs:complexType>
  </xs:element>
  </xs:schema>
- <Barcode>
  <Type>CODE128C</Type> 
  <RawData>038000356216</RawData> 
  <EncodedValue>11010011100100100110001010011110011011001100100010001101111000101010011101100101000111101100011101011</EncodedValue> 
  <EncodingTime>15.625</EncodingTime> 
  <IncludeLabel>false</IncludeLabel> 
  <Forecolor>Black</Forecolor> 
  <Backcolor>White</Backcolor> 
  <CountryAssigningManufacturingCode>N/A</CountryAssigningManufacturingCode> 
  <ImageWidth>300</ImageWidth> 
  <ImageHeight>150</ImageHeight> 
  <Image>/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLD.... </Barcode>
  </BarcodeXML>

A library permite gerar outros tipos de código de barras e, se eu eu você (eu não sou...), iria checar as informações geradas para ter certeza de que esta tudo dentro do padrão usado no território nacional.

Nota: A rotina para gerar o código de barras 128C para NF-e tem um bug quando é usado 44 dígitos. Entrei em contato com o autor da library que constatou o problema e prometeu disponibilizar em breve uma versão corrigindo o erro.

Obs: O autor corrigiu o problema e a nova versão já foi disponibilizada no link:

De qualquer forma fica aqui esta contribuição. (O projeto completo esta no Super DVD .NET e Super CD .NET)

Eu sei é apenas VB .NET, mas eu gosto...

Referências:


José Carlos Macoratti