如何使用Microsoft Report Builder为RDL报表添加Bar code 39条形码
RDL报表中为物料编号添加Code 39条形码实现方案
Code 39(又称Code 3 of 9)自带起止符规则、无需强制校验位,是Report Builder里实现成本最低的条码类型,两种常用实现方案按需选择即可。
方案1:字体实现(配置最简单,适合可操作服务器字体的场景)
- 提前在制作报表的本机、部署报表的服务器系统中安装Free 3 of 9免费Code39字体,否则预览/打印时条码会渲染为普通字符。
- Code39规范要求条码内容首尾必须加
*作为起始、终止识别符,缺了这个扫码枪无法识别内容。 - 在报表设计区拖入普通文本框,绑定物料编号字段,将文本框字体设置为已安装的Free 3 of 9,字号调整为22pt-28pt(过小识别率低,过宽占用版面),文本框的表达式填写如下:
="*" & UCase(Fields!物料编号.Value) & "*"
注意:Code39默认仅支持大写英文字母、数字和规定的特殊符号,表达式里加
UCase()是为了把物料编号里的小写字母自动转大写,避免识别失败。
方案2:自定义代码生成条码图(无需安装字体,适合无服务器操作权限的场景)
如果没法在报表服务器装字体,可以直接在报表内嵌Code39编码逻辑,直接生成条码图片渲染:
- 打开报表属性面板,切换到「代码」标签页,将以下VB自定义代码粘贴到代码编辑区:
Public Function GenerateCode39(ByVal inputText As String) As Byte() Dim code39Map As New System.Collections.Generic.Dictionary(Of Char, String)() ' Code39标准字符编码映射 code39Map.Add("0"c, "000110100") code39Map.Add("1"c, "100100001") code39Map.Add("2"c, "001100001") code39Map.Add("3"c, "101100000") code39Map.Add("4"c, "000110001") code39Map.Add("5"c, "100110000") code39Map.Add("6"c, "001110000") code39Map.Add("7"c, "000100101") code39Map.Add("8"c, "100100100") code39Map.Add("9"c, "100000101") code39Map.Add("A"c, "001001001") code39Map.Add("B"c, "101001000") code39Map.Add("C"c, "001101000") code39Map.Add("D"c, "000011001") code39Map.Add("E"c, "100011000") code39Map.Add("F"c, "001011000") code39Map.Add("G"c, "000001101") code39Map.Add("H"c, "100001100") code39Map.Add("I"c, "001001100") code39Map.Add("J"c, "000011100") code39Map.Add("K"c, "100000011") code39Map.Add("L"c, "001000011") code39Map.Add("M"c, "101000010") code39Map.Add("N"c, "000010011") code39Map.Add("O"c, "100010010") code39Map.Add("P"c, "001010010") code39Map.Add("Q"c, "000000111") code39Map.Add("R"c, "100000110") code39Map.Add("S"c, "001000110") code39Map.Add("T"c, "000010110") code39Map.Add("U"c, "110000001") code39Map.Add("V"c, "011000001") code39Map.Add("W"c, "111000000") code39Map.Add("X"c, "010010001") code39Map.Add("Y"c, "110010000") code39Map.Add("Z"c, "011010000") code39Map.Add("-"c, "010000101") code39Map.Add("."c, "110000100") code39Map.Add(" "c, "011000100") code39Map.Add("$"c, "010101000") code39Map.Add("/"c, "010100010") code39Map.Add("+"c, "010001010") code39Map.Add("%"c, "000101010") code39Map.Add("*"c, "010010100") ' 起止符专用编码 ' 预处理内容:转大写、补首尾起止符 Dim processedText As String = "*" & inputText.ToUpper() & "*" Dim encodedBits As New System.Text.StringBuilder() For Each c As Char In processedText If code39Map.ContainsKey(c) Then encodedBits.Append(code39Map(c) & "0") End If Next Dim bitsStr As String = encodedBits.ToString().TrimEnd("0"c) ' 绘制条码位图 Dim narrowBarWidth As Integer = 2 ' 窄条像素宽度,可按打印精度调整 Dim barHeight As Integer = 60 ' 条码高度 Dim bmp As New System.Drawing.Bitmap(bitsStr.Length * narrowBarWidth, barHeight) Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp) g.Clear(System.Drawing.Color.White) For i As Integer = 0 To bitsStr.Length - 1 If bitsStr(i) = "1"c Then g.FillRectangle(System.Drawing.Brushes.Black, i * narrowBarWidth, 0, narrowBarWidth, barHeight) End If Next g.Dispose() ' 转成字节流供报表图像控件加载 Dim ms As New System.IO.MemoryStream() bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png) Return ms.ToArray() End Function
- 回到报表设计区,拖入一个「图像」控件,将图像源设置为「数据库」,图像值的表达式填写如下:
=Code.GenerateCode39(Fields!物料编号.Value)
配置踩坑提醒
- 普通Code39不需要额外计算校验位,网上很多教程加校验位的逻辑是给扩展版Code39用的,普通场景加了反而会导致扫码识别失败。
- 条码区域下方建议额外加一个普通文本框绑定原始物料编号,遇到条码污损、打印模糊的情况可以手动录入编号。
- 打印时不要开启「适合页面」「缩小以适应边距」类的缩放选项,会拉歪条码宽高比,直接降低识别率,条码宽高比保持在1:4到1:6之间识别效果最好。
内容的提问来源于stack exchange,提问作者EAA
相关产品推荐
相关产品推荐

