求生成条形码的解决方案
各位大虾,
我们目前的解决方案是用 .Net winform 开发的一个小程序,输入数据,然后操作 Excel ,将数据填充到 Excel 中去,然后直接通过程序打印 Excel。其中的条形码使用的是 Code 39 字体生成的,即 Sakura CD39 字体。条形码的内容也很简单,由数字"1234567890"和连字符"-"组成,所以用 Code 39 一直没有问题。
现在,我们有国外的业务,需要产生一种新的条形码: ]C11040000149:21003:30200
这个条形码里面有中括号 "]" 和 冒号":" 还有字母 "C"
我们尝试了以前的方法,都不能实现。
1.最初想使用Code 39 ,但是它不能解析中括号 “]”,即不能对中括号进行编码
2.到网上下载Code 128 ,code 128 好像可以解析上面的字符串,但是一直没有找到免费的。
3.使用Excel 中的控件Microsoft Barcode Control 9.0。因为我们是通过Excel 打印条形码标签的,所以想通过这个来实现。最初是真的可以了,通过设置,他可以解析上面的字符串,但是同时产生了一个新的问题:打印的条形码标签的内容始终不变,始终显示最开始的数据,也就是说如果你想打印修改后的条形码数据,就得将Excel 关闭,重新打开Excel 后才可以打印新的数据,所以这个一直没有得到解决。
4.想使用水晶报表,但是没有使用过,也不知道能不能产生条形码。
上面是我遇到的问题,不知道有哪位大虾能为我指点迷津。非常感谢回贴的任何一个网友。
如果文字无法解释的话,请打电话给我,或者留下您的电话,我打电话过来。我的电话是 0512-62585188-337 (胡子亮)
我的邮件是: zlhu@qq.com 我会在线等的,今天一天都会挂在CSDN上面。我第一次发问题,只有100积分,全部给帮助我的人们.
谢谢...
[解决办法]
Imports System.DrawingImports System.Windows.FormsImports System.Text.RegularExpressionsImports System.Drawing.ImagingPublic MustInherit Class Barcode Inherits Control Private m_BarCode As String '输入值 Private m_LineWidth As Integer '基准线宽度 '临时中间变量 Private m_DisPlayFont As Boolean '是否显示条码数字 Private m_Image As Image Public Overridable Property LineWidth() As Integer Get Return m_LineWidth End Get Set(ByVal value As Integer) If value > 0 AndAlso value <= 6 Then m_LineWidth = value End If End Set End Property Protected Function Check(ByVal Inptut As String) As Boolean '判断输入值是否符合规范 Return Regex.IsMatch(m_BarCode, Inptut) '只能输入12或者13位数字 End Function Public Overridable Property Value() As String Set(ByVal value As String) m_BarCode = value Me.Invalidate() '设置值完毕后触发绘画事件 End Set Get Return m_BarCode End Get End Property Public Overridable ReadOnly Property BarCode() As String '返回条码数字 Get Return String.Empty End Get End Property Public Property DisPlayFont() As Boolean Get Return m_DisPlayFont End Get Set(ByVal value As Boolean) m_DisPlayFont = value Me.Invalidate() End Set End Property Public ReadOnly Property Image() As Image Get SavePic() Return m_Image m_Image.Dispose() End Get End Property Public Sub New() m_LineWidth = 1 m_DisPlayFont = True Me.Height = 85 End Sub Protected Overridable Sub DrawPic(ByVal Graphic As Graphics) End Sub Protected Overridable Sub DrawText(ByVal Graphic As Graphics) End Sub Private Sub SavePic() '生成图象以供打印 m_Image = New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb) Dim Graphic As Graphics = Graphics.FromImage(m_Image) Graphic.Clear(Color.White) DrawPic(Graphic) DrawText(Graphic) End SubEnd Class
[解决办法]
这是EAN13码的具体实现
Imports System.DrawingImports System.TextImports System.Windows.FormsNamespace EAN Public NotInheritable Class EAN13 Inherits Barcode Private CharA As String() = New String(9) {"0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011"} '间隔线左侧编码集合A Private CharB As String() = New String(9) {"0100111", "0110011", "0011011", "0100001", "0011101", "0111001", "0000101", "0010001", "0001001", "0010111"} '间隔线左侧编码集合B Private Guid As String() = New String(9) {"AAAAAA", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA", "ABABAB", "ABABBA", "ABBABA"} '引导数编码规则 Private Rencode As String() = New String(9) {"1110010", "1100110", "1101100", "1000010", "1011100", "1001110", "1010000", "1000100", "1001000", "1110100"} '间隔线右侧编码集合 Private Const Cstar As String = "101" '条形码左护线 Private Const Cmid As String = "01010" '条形码间隔线 Private Const Cend As String = "101" '条形码右护线 Public Sub New() '初始化值 MyBase.New() MyBase.Value = "123456789012" Me.Width = 129 End Sub Public Overrides ReadOnly Property BarCode() As String Get Return CheckDigit() End Get End Property Private Function Calcdigit() As String Dim Sum As Integer, i As Integer For i = MyBase.Value.Length - 1 To 0 Step -1 If i Mod 2 <> 0 Then Sum += CInt(MyBase.Value.Substring(i, 1)) * 3 Else Sum += CInt(MyBase.Value.Substring(i, 1)) End If Next Return Strings.Right((10 - Sum Mod 10), 1) End Function Public Overrides Property LineWidth() As Integer '设置基准线宽度 Get Return MyBase.LineWidth End Get Set(ByVal value As Integer) MyBase.LineWidth = value Me.Width = 95 * MyBase.LineWidth + 34 Me.Invalidate() End Set End Property Private Function CheckDigit() As String If Check("^\d{12,13}$") = True Then Select Case MyBase.Value.Length '如果输入12位的话则计算校验位,13位的话则不计算,如果不匹配则为空字符 Case 12 Return MyBase.Value & Calcdigit() Case 13 Return MyBase.Value Case Else Return String.Empty End Select Else Return String.Empty End If End Function Private Function Convert() As String '通过编码规则将条码数字转换成图形码 Dim BinaryCode As New StringBuilder(95), LMethod As Integer, i As Integer Dim tempstr = CheckDigit() CheckDigit() If tempstr <> String.Empty Then LMethod = CInt(tempstr.Substring(0, 1)) BinaryCode.Append(Cstar) For i = 1 To 6 If Guid(LMethod).Substring(i - 1, 1) = "A" Then BinaryCode.Append(CharA(CInt(tempstr.Substring(i, 1)))) Else BinaryCode.Append(CharB(CInt(tempstr.Substring(i, 1)))) End If Next BinaryCode.Append(Cmid) For i = 7 To 12 BinaryCode.Append(Rencode(CInt(tempstr.Substring(i, 1)))) Next BinaryCode.Append(Cend) Return BinaryCode.ToString Else Return String.Empty End If End Function Protected Overrides Sub DrawPic(ByVal Graphic As Graphics) '根据转换后的图象编码进行绘制 Dim BlackPen As New Pen(Color.Black, Me.LineWidth) Dim i As Integer, Height As Single Dim ConvertStr As String = Convert() If ConvertStr <> String.Empty Then '画条码的线条 For i = 0 To ConvertStr.Length - 1 Height = 0 If i < 3 OrElse i > 91 OrElse (i > 45 AndAlso i < 50) Then Height = 10 End If If ConvertStr.Substring(i, 1) = "1" Then Graphic.DrawLine(BlackPen, CSng(17 + Me.LineWidth * i), 10, CSng(17 + Me.LineWidth * i), (Me.Height - 20 + Height)) End If Next End If BlackPen.Dispose() '释放资源 End Sub Protected Overrides Sub DrawText(ByVal Graphic As Graphics) Dim TempStr As String = CheckDigit() If TempStr <> String.Empty Then If Me.DisPlayFont = True Then '画条码字 Dim FontSize As Integer = 8 + LineWidth * 2 '根据条码宽度不同设置字体大小不同 Dim BarCodeFont As New Font("Arival", FontSize, FontStyle.Regular, GraphicsUnit.Pixel) Dim FontWidth As Integer = TextRenderer.MeasureText(TempStr.Substring(0, 1), BarCodeFont).Width Dim Y As Single = Me.Height - BarCodeFont.Height - (25 - BarCodeFont.Height) / 2 '绘制数字的开始位置 Dim X As Single = 19 + 3 * Me.LineWidth + (7 * Me.LineWidth - FontWidth) / 2 Graphic.DrawString(TempStr.Substring(0, 1), BarCodeFont, Brushes.Black, 20 - FontWidth, Y) '画第一个数字 For i = 1 To 6 '画左边的数字 Graphic.DrawString(TempStr.Substring(i, 1), BarCodeFont, Brushes.Black, X + (7 * Me.LineWidth) * (i - 1), Y) '由于1个数字有7位数字编码,所以一个条码数字的宽度应该在7条基准线宽度以内 Next X += 47 * Me.LineWidth '画右边的数字 For i = 7 To 12 Graphic.DrawString(TempStr.Substring(i, 1), BarCodeFont, Brushes.Black, X + (7 * Me.LineWidth) * (i - 7), Y) Next End If End If End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) '绘图事件的处理程序 Dim Myrect As New Rectangle(0, 0, Me.Width, Me.Height) '指定背景区域并绘成白色 e.Graphics.FillRectangle(Brushes.White, Myrect) DrawPic(e.Graphics) '调用条码的绘制方法 DrawText(e.Graphics) e.Graphics.Dispose() End Sub Private Sub EAN13_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize MyBase.LineWidth = (Me.Width - 34) / 95 End Sub End ClassEnd Namespace
[解决办法]
这是EAN8码的实现
Imports System.DrawingImports System.TextImports System.Windows.FormsNamespace EAN Public NotInheritable Class EAN8 Inherits Barcode Private CharA As String() = New String(9) {"0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011"} '间隔线左侧编码集合A Private Rencode As String() = New String(9) {"1110010", "1100110", "1101100", "1000010", "1011100", "1001110", "1010000", "1000100", "1001000", "1110100"} '间隔线右侧编码集合 Private Const Cstar As String = "101" '条形码左护线 Private Const Cmid As String = "01010" '条形码间隔线 Private Const Cend As String = "101" '条形码右护线 Public Sub New() MyBase.New() MyBase.Value = "1234567" Me.Width = 87 End Sub Public Overrides ReadOnly Property BarCode() As String Get Return CheckDigit() End Get End Property Public Overrides Property LineWidth() As Integer '设置基准线宽度 Get Return MyBase.LineWidth End Get Set(ByVal value As Integer) MyBase.LineWidth = value Me.Width = 67 * value + 20 Me.Invalidate() End Set End Property Private Function Calcdigit() As String Dim Sum As Integer, i As Integer For i = MyBase.Value.Length - 1 To 0 Step -1 If i Mod 2 = 0 Then Sum += CInt(MyBase.Value.Substring(i, 1)) * 3 Else Sum += CInt(MyBase.Value.Substring(i, 1)) End If Next Return Strings.Right((10 - Sum Mod 10), 1) End Function Private Function CheckDigit() As String If Check("^\d{7,8}$") = True Then Select Case MyBase.Value.Length '如果输入12位的话则计算校验位,13位的话则不计算,如果不匹配则为空字符 Case 7 Return MyBase.Value & Calcdigit() Case 8 Return MyBase.Value Case Else Return String.Empty End Select Else Return String.Empty End If End Function Private Function Convert() As String '通过编码规则将条码数字转换成图形码 Dim BinaryCode As New StringBuilder Dim TempStr As String = CheckDigit() If TempStr <> String.Empty Then BinaryCode.Append(Cstar) For i = 0 To 3 BinaryCode.Append(CharA(CInt(TempStr.Substring(i, 1)))) Next BinaryCode.Append(Cmid) For i = 4 To 7 BinaryCode.Append(Rencode(CInt(TempStr.Substring(i, 1)))) Next BinaryCode.Append(Cend) Return BinaryCode.ToString Else Return String.Empty End If End Function Protected Overrides Sub DrawPic(ByVal Graphic As Graphics) '根据转换后的图象编码进行绘制 Dim BlackPen As New Pen(Color.Black, Me.LineWidth) Dim WhitePen As New Pen(Color.White, Me.LineWidth) Dim i As Integer, Height As Single Dim ConvertStr As String = Convert() If ConvertStr <> String.Empty Then '画条码的线条 For i = 0 To ConvertStr.Length - 1 Height = 0 If i < 3 OrElse i > 63 OrElse (i > 30 AndAlso i < 36) Then Height = 10 End If If ConvertStr.Substring(i, 1) = "1" Then Graphic.DrawLine(BlackPen, CSng(10 + Me.LineWidth * i), 10, CSng(10 + Me.LineWidth * i), (Me.Height - 20 + Height)) End If Next End If BlackPen.Dispose() '释放资源 WhitePen.Dispose() End Sub Protected Overrides Sub DrawText(ByVal Graphic As Graphics) Dim TempStr As String = CheckDigit() If TempStr <> String.Empty Then If MyBase.DisPlayFont = True Then '画条码字 Dim FontSize As Integer = 8 + LineWidth * 2 '根据条码宽度不同设置字体大小不同 Dim BarCodeFont As New Font("Arival", FontSize, FontStyle.Regular, GraphicsUnit.Pixel) Dim FontWidth As Integer = TextRenderer.MeasureText(TempStr.Substring(0, 1), BarCodeFont).Width Dim Y As Single = Me.Height - BarCodeFont.Height - (25 - BarCodeFont.Height) / 2 '绘制数字的开始位置 Dim X As Single = 12 + 3 * Me.LineWidth + (7 * Me.LineWidth - FontWidth) / 2 For i = 0 To 3 '画左边的数字 Graphic.DrawString(TempStr.Substring(i, 1), BarCodeFont, Brushes.Black, X + (7 * Me.LineWidth) * (i), Y) '由于1个数字有7位数字编码,所以一个条码数字的宽度应该在7条基准线宽度以内 Next X += 33 * Me.LineWidth '画右边的数字 For i = 4 To 7 Graphic.DrawString(TempStr.Substring(i, 1), BarCodeFont, Brushes.Black, X + (7 * Me.LineWidth) * (i - 4), Y) Next End If End If End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) '绘图事件的处理程序 Dim Myrect As New Rectangle(0, 0, Me.Width, Me.Height) '指定背景区域并绘成白色 e.Graphics.FillRectangle(Brushes.White, Myrect) DrawPic(e.Graphics) '调用条码的绘制方法 DrawText(e.Graphics) e.Graphics.Dispose() End Sub Private Sub EAN8_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize MyBase.LineWidth = (Me.Width - 20) / 67 End Sub End ClassEnd Namespace