Bujar Ademi

Bujar Ademi

Windows Programmer

Print Report RDLC without preview in Visual Basic 2005
Bujar Ademi

I have asked many time to print rdlc report from Visual Basic 2005 direct to the printer without preview of report. On my project for law firm I needed to print claims without preview. To do so, I created report in Visual Basic 2005 and then class which will take care of printing without preview. This was needed because we are doing mass printing of claims. I won’t go in details about creating report in Visual Basic 2005, what I want to explain in these article is how to send direct to the printer existing report.

For this purpose I will try to explain some of the functions that will do the job. Main idea is to export the report to printable document and then with the help of PrintDocument class to send to the printer.

Private m_currentPageIndex As Integer
Private m_streams As IList(Of Stream)

Private Sub Export(ByVal report As LocalReport)
Dim deviceInfo As String = _
"<DeviceInfo>" + _
" <OutputFormat>EMF</OutputFormat>" + _
" <PageWidth>8.27in</PageWidth>" + _
" <PageHeight>11.69in</PageHeight>" + _
" <MarginTop>0.2in</MarginTop>" + _
" <MarginLeft>0.2in</MarginLeft>" + _
" <MarginRight>0.2in</MarginRight>" + _
" <MarginBottom>0.5in</MarginBottom>" + _
"</DeviceInfo>"
Dim warnings() As Warning = Nothing
m_streams = New List(Of Stream)()
report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)

Dim stream As Stream

For Each stream In m_streams
stream.Position = 0
Next
End Sub

 

For information, LocalReport class has the method to Render itself on an diferrent type of document like, pdf or for our purpose an Image of type EMF. The above method called Export, take as parameter a report and render it as image so later we can use to print that image. The next function is callback of method Render and it looks like this:

Private Function CreateStream(ByVal name As String, ByVal fileNameExtension As String, ByVal encoding As Encoding, ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
Dim rnd As Random
rnd = New Random
Dim stream As Stream = New FileStream("Some temporary file where to save", FileMode.Create)
m_streams.Add(stream)
Return stream
End Function

After we prepare our report for printing then it’s time to print. Printing we will do with the help of PrintDocument class that is part of .NET framework.

Public Sub Print()
'First we export the report and set current page to 0
Export(Report)
m_currentPageIndex = 0

If m_streams Is Nothing Or m_streams.Count = 0 Then
Return
End If
'We declare our PrintDocument, and then we can set printer name or other stuff for our print document class
Dim printDoc As New PrintDocument()
'Register event for Page printing
AddHandler printDoc.PrintPage, AddressOf PrintPage

Dim ps As PaperSize = New PaperSize("A4", 830, 1170)

printDoc.DefaultPageSettings.PaperSize = ps
With printDoc.DefaultPageSettings.Margins
.Top = 1
.Bottom = 0.2
.Left = 0.2
.Right = 0.2
End With
printDoc.DocumentName = "Name of printed document"
'This is just to be sure that the printer has A4 format
For i As Integer = 0 To printDoc.DefaultPageSettings.PrinterSettings.PaperSizes.Count - 1
If printDoc.DefaultPageSettings.PrinterSettings.PaperSizes(i).Kind = PaperKind.A4 Then
printDoc.DefaultPageSettings.PaperSize = printDoc.DefaultPageSettings.PrinterSettings.PaperSizes(i)
End If

Next
If Not printDoc.PrinterSettings.IsValid Then
Dim msg As String = "Can't find printer"
Return
End If
printDoc.Print()

End Sub

This is the method that do all the job. But before we finish we need an additional method. Method that will go threw pages and print them.

Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
ev.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
Dim pageImage As New Metafile(m_streams(m_currentPageIndex))
ev.Graphics.DrawImage(pageImage, ev.PageBounds)

m_currentPageIndex += 1
ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
End Sub

I believe that now you have clear view how to print your reports direct to printer, I will not put all code in one place, that will be your turn to put all code in one place and do your homework :)