Printing BarCodes from within MSCRM and the power of .Net
Yesterday, I had a query from a customer willing to send events registration emails with embedded barcodes, so that the event attendees can self check-in at the event.
The whole solution finding ended opening my mind about .Net possibilities in a quite positive way, while it started rather poorly.
As we already had a custom code sending the registration emails with a confirmation PDF, I thought that was just a matter of changing the SSRS report generating the PDF so that we could use barcodes and barcodes being just fonts is should be pretty straighforward.
I downloaded a free Code39 font, installed it on the dev ssrs server,tried using it in SSRS and directly started having issues, as it was an open type font and .Net (and thus SSRS) only supports True Type fonts.
So, I got a TTF Code39 font, installed it and, hoorah, it was fine in preview. I then tried the PDF extract and all I got was garbage...
Now, I had my share of PDF rendering issues in SSRS, usually due to incompatibilities between the HTML and PDF languages, but that was the first time I saw it with fonts so I started browsing the web for similar problems and it seems SSRS 2005 (the version that the customer uses) doesn't handle very well extra fonts in PDF, and so I started playing with the idea of pushing an upgrade to SSRS2008 (not an SQL upgrade, just the SSRS part), when I spotted articles with related issues in SSRS 2008R2...
I was looking into how to generate barcodes with code when I found this marvellous article by Cody Konior which solves the problem once and for all.
The key part of the article is this piece of SSRS vb.net code whith create a bitmap image from a specific font generated string
Public Shared Function GenerateImage(ByVal fontName As String, ByVal stringText As String) As Byte()
Dim oGraphics As System.Drawing.Graphics
Dim barcodeSize As System.Drawing.SizeF
Dim ms As System.IO.MemoryStream
Using font As New System.Drawing.Font(New System.Drawing.FontFamily(fontName), 36)
Using tmpBitmap As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
oGraphics = System.Drawing.Graphics.FromImage(tmpBitmap)
oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel
barcodeSize = oGraphics.MeasureString(stringText, font)
oGraphics.Dispose()
End Using
Using newBitmap As New System.Drawing.Bitmap(barcodeSize.Width, barcodeSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
oGraphics = System.Drawing.Graphics.FromImage(newBitmap)
oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel
Using oSolidBrushWhite As New System.Drawing.SolidBrush(System.Drawing.Color.White)
Using oSolidBrushBlack As New System.Drawing.SolidBrush(System.Drawing.Color.Black)
oGraphics.FillRectangle(oSolidBrushWhite, New System.Drawing.Rectangle(0, 0, barcodeSize.Width, barcodeSize.Height))
oGraphics.DrawString(stringText, font, oSolidBrushBlack, 0, 0)
End Using
End Using
ms = New System.IO.MemoryStream()
newBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
End Using
End Using
Return ms.ToArray()
End Function
So by using the System.Drawing library, this seemingly complex task was reduced in a dozen lines of vb.net code.
Furthermore as the library is part of .net, the deployment of this SSRS "extension" to other environnments (ie: dev, staging, test, production) is just a matter of installing the RDL file as usual; no fancy registration, installation of whatever is needed.
Until now, I did never realized how having SSRS using the .Net stack was effectively allowing such easy extensions of daunting tasks; it opened my mind to a full range of new possibilities.
It's a bit like you always knew it was there but you have to see it to understand the full implications.
And the cherry on the cake ? This whole code was intended for SSRS 2008 but worked without a hitch in SSRS 2005 ;)
Comments
RSS feed for comments to this post.