求生成条形码的解决方案

onlinepay 2008-10-13 01:07:43
各位大虾,
我们目前的解决方案是用 .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积分,全部给帮助我的人们.

谢谢...
...全文
1974 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
seahi 2012-01-17
  • 打赏
  • 举报
回复
mark
hchjjun 2009-11-20
  • 打赏
  • 举报
回复
mark
43720938 2008-11-01
  • 打赏
  • 举报
回复
mark
onlinepay 2008-10-31
  • 打赏
  • 举报
回复
我自己搞定了,楼上很多朋友说了一些一知半解的答案,却没有真正能解决这个问题,我还是使用了 excel 中的 vba 代码实现了。
那个 barcode 控件很搞笑,要在重新给新值时用 vba 代码改变一下 barcode控件的大小就可以使用新值生效了。如下面的代码:

Private Sub Worksheet_Change(ByVal Target As Range)
BarCodeCtrl1.Value = "]C110" & Cells(5, 5) & ":21" & Cells(12, 19) & ":30" & Cells(12, 18)
BarCodeCtrl1.Height = 41
BarCodeCtrl1.Width = 520
BarCodeCtrl1.Refresh
'改变height 或width值,打印结果才正确
BarCodeCtrl1.Value = "]C110" & Cells(5, 5) & ":21" & Cells(12, 19) & ":30" & Cells(12, 18)
BarCodeCtrl1.Height = 41.25
BarCodeCtrl1.Width = 523.6
BarCodeCtrl1.Refresh
'Sheet2.PrintOut
End Sub


希望能帮助有同样问题的人。
lizhengnan 2008-10-16
  • 打赏
  • 举报
回复
UP
onlinepay 2008-10-15
  • 打赏
  • 举报
回复
水晶报表目前我一直没有接触过。个人觉得用字体最好。但是就是没有找到这方面的免费的条形码字体
onlinepay 2008-10-15
  • 打赏
  • 举报
回复
怎么绑定呢?可否详细说明一下呢?谢谢您。
onlinepay 2008-10-15
  • 打赏
  • 举报
回复
请问使用 Code128 字体怎么做呢?
CODE128码是可以解决的,要用算法算出首尾加进的特殊字符
这个算法在 Excel VBA 中怎么实现呢?
vbman2003 2008-10-14
  • 打赏
  • 举报
回复
MARK
fuyonggao 2008-10-14
  • 打赏
  • 举报
回复
打印的条形码标签的内容始终不变,始终显示最开始的数据,也就是说如果你想打印修改后的条形码数据,就得将Excel 关闭,重新打开Excel 后才可以打印新的数据,所以这个一直没有得到解决
让设定的控件值生效即可,很简单的.
yanlongwuhui 2008-10-14
  • 打赏
  • 举报
回复
MARK
my98800 2008-10-14
  • 打赏
  • 举报
回复
使用条形吗字库呀
jsooy 2008-10-14
  • 打赏
  • 举报
回复
不管用不用得上,先收藏起来。谢谢了
floadcloud 2008-10-14
  • 打赏
  • 举报
回复
mark
ncqingchuan1976 2008-10-14
  • 打赏
  • 举报
回复
这是EAN8码的实现

Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Namespace 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 Class
End Namespace
ncqingchuan1976 2008-10-14
  • 打赏
  • 举报
回复
这是EAN13码的具体实现

Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Namespace 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 Class
End Namespace
ncqingchuan1976 2008-10-14
  • 打赏
  • 举报
回复
如果知道128码的编码规则那就自己写条码组件。
这是基类代码

Imports System.Drawing
Imports System.Windows.Forms
Imports System.Text.RegularExpressions
Imports System.Drawing.Imaging

Public 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 Sub

End Class
holon 2008-10-13
  • 打赏
  • 举报
回复
不错,支持一下
-------------
cn域名免费送 www.arraylist.cn
程序人生-IT人士的酒吧式交流平台
-------------
holon 2008-10-13
  • 打赏
  • 举报
回复
不错,支持一下
-------------
cn域名免费送 www.arraylist.cn
程序人生-IT人士的酒吧式交流平台
-------------
JeffChung 2008-10-13
  • 打赏
  • 举报
回复
没做过,我一直觉得用水晶报表之类的做比较简单^

帮顶
加载更多回复(11)

16,716

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧