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