I am trying to embed a barcode in my RDL report which is developed by Microsoft SQL Server Report Builder 3.0.
I found couple of suggested solutions in the internet, one of them is to add a DLL
reference and add some code, but it didn't work and it always fails to load the DLL
, I found another solution by using an API as source of an image, but that would not be a feasible solution for me since I do not always have internet connection in my server.
Is there a way to use Code 128
font in my report? Or any other solution that does not require internet connection?
After a lot of research, I managed to embed barcode in my report and have it running using Code 128
font.
However, the font by itself is not enough since you need to prepare the text first in order for the barcode to be scannable, following solution does not require installing the font on the clients machines, you only need to install it on the server:
First you need to install Code 128
font if you did not already! You can download it from here.
Open your report or create a new one.
We need to add System.Drawing
DLL
file as reference:
This can be done by going to the Report Properties (Right Click outside the body -> Report Properties), click on References tab, click on Add button in Add or remove assemblies section, click on the Open button ...
Browse for C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll
file, and click Open.
You should have something like this:
Go to Code tab in the Report Properties, copy and past the following code and click Ok:
Function StringToBarcode(value As String) As String
Dim charPos, minCharPos As Integer
Dim currentChar, checksum As Integer
Dim isTableB As Boolean = True, isValid As Boolean = True
Dim returnValue As String = String.Empty
If (value Is Nothing OrElse value.Length = 0) Then
Return String.Empty
End If
'Check for valid characters
For charCount As Integer = 0 To value.Length - 1
currentChar = Asc(value.Substring(charCount, 1))
If (Not (currentChar >= 32 AndAlso currentChar <= 126)) Then
isValid = False
Exit For
End If
Next
If Not (isValid) Then Return returnValue
charPos = 0
While (charPos < value.Length)
If (isTableB) Then
'See if interesting to switch to table C
'yes for 4 digits at start or end, else if 6 digits
If (charPos = 0 OrElse charPos + 4 = value.Length) Then
minCharPos = 4
Else
minCharPos = 6
End If
minCharPos = IsNumber(value, charPos, minCharPos)
If (minCharPos < 0) Then
'Choice table C
If (charPos = 0) Then
'Starting with table C
'char.ConvertFromUtf32(205)
returnValue = Chr(205).ToString()
Else
'Switch to table C
returnValue = returnValue + Chr(199).ToString()
End If
isTableB = False
Else
If (charPos = 0) Then
'Starting with table B
returnValue = Chr(204).ToString()
'char.ConvertFromUtf32(204);
End If
End If
End If
If (Not isTableB) Then
'We are on table C, try to process 2 digits
minCharPos = 2
minCharPos = IsNumber(value, charPos, minCharPos)
If (minCharPos < 0) Then
'OK for 2 digits, process it
currentChar = Integer.Parse(value.Substring(charPos, 2))
If (currentChar < 95) Then
currentChar = currentChar + 32
Else
currentChar = currentChar + 100
End If
returnValue = returnValue + Chr(currentChar).ToString()
charPos += 2
Else
'We haven't 2 digits, switch to table B
returnValue = returnValue + Chr(200).ToString()
isTableB = True
End If
End If
If (isTableB) Then
'Process 1 digit with table B
returnValue = returnValue + value.Substring(charPos, 1)
charPos += 1
End If
End While
'Calculation of the checksum
checksum = 0
Dim loo As Integer
For loo = 0 To returnValue.Length - 1
currentChar = Asc(returnValue.Substring(loo, 1))
If (currentChar < 127) Then
currentChar = currentChar - 32
Else
currentChar = currentChar - 100
End If
If (loo = 0) Then
checksum = currentChar
Else
checksum = (checksum + (loo * currentChar)) Mod 103
End If
Next
'Calculation of the checksum ASCII code
If (checksum < 95) Then
checksum = checksum + 32
Else
checksum = checksum + 100
End If
' Add the checksum and the STOP
returnValue = returnValue + _
Chr(checksum).ToString() + _
Chr(206).ToString()
Return returnValue
End Function
Function IsNumber(InputValue As String, CharPos As Integer, MinCharPos As Integer) As Integer
MinCharPos -= 1
If (CharPos + MinCharPos < InputValue.Length) Then
While (MinCharPos >= 0)
If (Asc(InputValue.Substring(CharPos + MinCharPos, 1)) < 48 _
OrElse Asc(InputValue.Substring(CharPos + MinCharPos, 1)) > 57) Then
Exit While
End If
MinCharPos -= 1
End While
End If
Return MinCharPos
End Function
Public Function Code128(ByVal stringText As String) As Byte()
Dim result As Byte() = Nothing
Try
result = GenerateImage("Code 128", StringToBarcode(stringText))
Catch ex As Exception
End Try
Return result
End Function
Public 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), 30)
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
Insert an image in your report, and select Database as the image source, and use image/png
as MIMI type:
Click on fx button in Use this field button, and use this function =Code.Code128(Fields!your_field_name.Value)
, press Ok and Ok.