在SQL Server Reporting Services (SSRS) 报告中嵌入条形码是一个常见的需求,尤其是在需要打印包含条形码的文档时。虽然可以使用条形码字体,但它们在SSRS报告服务器上发布的报告中可能无法正常工作,而且条形码字体可能相当昂贵。幸运的是,Brad Barnhill 发表了一篇优秀的文章,提供了一个条形码图像生成库(Barcodelib),使得生成高质量的条形码变得简单。
最初,尝试使用免费的条形码字体,但如引言中所述,当发布报告时失败了。接下来,尝试编写自定义代码生成位图,使用条形码字体,并通过Graphics.DrawString将其写入位图并返回为字节数组。这在一定程度上有效,但当将报告导出为PDF时,图像质量急剧下降,因为首先它是TrueType字体,所以条形码渲染、转换和打印有时是可扫描的,但不幸的是,条形码扫描器有时会因为图像不够好而无法读取。因此,使用代码和免费字体是不够的。在浏览了许多论坛和想法之后,找到了Brad的文章,并决定尝试使用它,因为它直接渲染条形码,而不是将字体转换为图像。
使用Brad Barnhill提供的barcodelib生成的条形码质量非常好,即使在打印后也是如此,并且高度可配置,可以旋转,带或不带标签,各种条形码格式等。
首先,需要从Brad Barnhill的文章中下载barcodelib。然后,将barcodelib.dll复制到"任何地方"。具体来说(以SSRS2008和VS 2008示例为例):
C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin\
C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies
C:\Program Files (x86)\Microsoft Visual Studio 9\Common7\IDE\PrivateAssemblies
然后在报告->属性中添加对System.Drawing的引用,从.NET选项卡,以及对报告服务器bin文件夹中barcodelib.dll的另一个引用,使用浏览选项卡。然后,添加类名"Barcodelib.Barcode"和实例名"bar"。
现在,它应该看起来像这样:
Public Function Convert(Text As String) As Byte()
Dim b As System.Drawing.Bitmap
Dim bar As New BarcodeLib.Barcode
bar.Alignment = BarcodeLib.AlignmentPositions.LEFT
bar.IncludeLabel = False
bar.RotateFlipType = Drawing.RotateFlipType.RotateNoneFlipNone
b = bar.Encode(BarcodeLib.TYPE.CODE39Extended, Text, 400, 30)
Dim bitmapData As Byte() = Nothing
Using ms As New System.IO.MemoryStream()
b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)
bitmapData = ms.ToArray()
End Using
Return bitmapData
End Function
是否认出了之前提到的实例"bar"在这里被使用?可以根据自己的喜好替换设置(例如,增强功能以接受参数),旋转,条形码格式类型等。在引言中提到的早期文章中查看barcodelib的功能!非常感谢Brad!
调整大小(在这个示例中是400x30)可能符合期望。通过试错,玩得开心。SSRS图像属性(稍后会看到)需要一个字节数组。所以他们将得到一个,快速将位图写入内存流并获取字节数组。其他方法,例如使用Marshal.Copy可能有效,但会在正在处理的SSRS嵌入式代码场景中引入更多的麻烦。
现在一切都准备好了,来到了有趣的部分。向报告中添加一个图像来包含条形码。转到图像属性:将图像源设置为"数据库",MIME类型"Image/bmp",并将字段表达式设置为以下内容:
=Code.First(Fields!myfield.Value)
报告的预览将生成一个整洁的条形码,部署/发布的报告版本也将在报告服务器上生成条形码:)太简单了,不是吗?
有一些事情需要注意。确保图像大小足够大,或者允许自动增长,或者设置为按比例适应。如果条形码被扭曲或裁剪,它可能无法为条形码扫描器渲染可读,如果一半丢失了。Code39Extended似乎需要一个星号来开始和结束条形码。这意味着文本需要以*开始并以*结束。然后读取的条形码内容将是*星号之间的任何内容。这可能也适用于其他一些条形码格式。
确保以高分辨率打印报告,以便条形码按预期出现,而不是全部洗掉,使用彩色打印,因为原始条形码图像是24位位图,灰度可能会洗掉。在激光打印机上,使用彩色,单面和光栅打印作为选项。
如果将报告部署到另一台远程机器,请确保将barcodelib部署到该机器的报告服务器的bin目录。
使用VS2012时可能会出现问题,请参见。
这个网站上有很多其他非常有趣的文章关于条形码的主题,看看!