Twitter Image

Printing BarCodes from within MSCRM and the power of .Net

Written by Stéphane Dorrekens
Thursday, 08 September 2011 07:40

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 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)
            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 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 ;)


#1 Nicolas 2011-09-16 13:14
That's a nice one. I wonder for which customer that was... :)