0
votes

I am creating a simple invoice management system for my friend. the users can create invoices and print when required. I am currently stuck at printing the invoice part. it's a B2B business model and needs to print 100s of invoices at once. I created the report using MS RDLC. linked it to a report viewer. below is the UI of my application

Application UI

What I am trying to do I want to automate the inbuild print function of the report viewer (red arrow) but without the choose printer dialogue box upon pressing the Print Button (Yellow Arrow).

There are lots of code sample everywhere. I already read the walkthrough from MS, but can't understand it fully.

What I have tried Tried to Print the reportviewer using PrintDocument() but rendered a blank page. Can't understand how to assign the reportviewer to PrintDocument object.

    Dim printDoc As New PrintDocument()
    Dim ps As New PrinterSettings()
    printDoc.PrinterSettings.PrinterName = ps.PrinterName 'Default Printer Name
    printDoc.Print() 'How to assign the Reportviewer1 to printdoc?

============UPDATE============

I have tried the below class found when searching web.

Custom Class

then I call it like this.

 Dim autoprintme As AutoPrintCls = New AutoPrintCls(ReportViewer1.LocalReport)
 autoprintme.Print()

its working and printing through my default printer, but page setup get messed up. can anyone please point me to the write direction?

My Page Setup

Hight:14.8cm  Width:21cm 

============UPDATE 2============

I have already figure this out, due to wrong margin value page setup got messed up.

I have change this in the class

"<DeviceInfo><OutputFormat>emf</OutputFormat>
<StartPage>0</StartPage>
<EndPage>0</EndPage>
<MarginTop>{0}</MarginTop>
<MarginLeft>{1}</MarginLeft>
<MarginRight>{2}</MarginRight>
<MarginBottom>{3}</MarginBottom>
<PageHeight>{4}</PageHeight>
<PageWidth>{5}</PageWidth>
</DeviceInfo>", "0in","0in","0in","0in", ToInches(585),
ToInches(827)) 

but all is hard coded, how to pass Height, Width and Margin value from button click event to the class?

1
I have updated my question with a semi working solutionLEON
What do you mean page setup get "messed up"?viking_grll
I have updated my question, please see Update 2LEON
you need to set the margins based on the page settings which you can get from LocalReport.GetDefaultPageSettings(). Check the "export()" method in my example.viking_grll
I understand what you trying to do, but I want know how can I pass my own variable like this.. Dim hight As Double = 585 Dim width As Double = 827 Dim autoprintme As AutoPrintCls = New AutoPrintCls(ReportViewer1.LocalReport, hight. width)LEON

1 Answers

0
votes

Add this class to your project:

Imports System.Drawing.Imaging
Imports System.Drawing.Printing
Imports System.Globalization
Imports System.IO
Imports System.Text
Imports Microsoft.Reporting.WinForms

Public Class ReportPrinter
    Public Sub Print(report As LocalReport)
        ' print
        export(report)
        printReport(report)
    End Sub

    Private _currentPageIndex As Integer
    Private _streams As IList(Of Stream)

    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 stream As Stream = New MemoryStream()
        _streams.Add(stream)
        Return stream
    End Function

    Private Sub export(ByVal report As LocalReport)
        Dim settings As ReportPageSettings = report.GetDefaultPageSettings()
        Dim pageInfo As String
        If Not settings.IsLandscape Then
            pageInfo = _
                String.Format("<PageWidth>{0}</PageWidth>" & _
                              "<PageHeight>{1}</PageHeight>", _
                              toInches(settings.PaperSize.Width), _
                              toInches(settings.PaperSize.Height))
        Else
            pageInfo = _
                String.Format("<PageHeight>{0}</PageHeight>" & _
                              "<PageWidth>{1}</PageWidth>", _
                              toInches(settings.PaperSize.Width), _
                              toInches(settings.PaperSize.Height))
        End If
        Dim deviceInfo As String = _
            String.Format("<DeviceInfo>" & _
                            "<OutputFormat>EMF</OutputFormat>" & _
                            "{0}" & _
                            "<MarginTop>{1}</MarginTop>" & _
                            "<MarginLeft>{2}</MarginLeft>" & _
                            "<MarginRight>{3}</MarginRight>" & _
                            "<MarginBottom>{4}</MarginBottom>" & _
                            "</DeviceInfo>", _
                            pageInfo, _
                            toInches(settings.Margins.Top), _
                            toInches(settings.Margins.Left), _
                            toInches(settings.Margins.Right), _
                            toInches(settings.Margins.Bottom))
        Dim warnings As Warning() = Nothing
        _streams = New List(Of Stream)()
        report.Render("Image", deviceInfo, AddressOf createStream, warnings)
        For Each stream As Stream In _streams
            stream.Position = 0
        Next
    End Sub

    Private Function toInches(hundrethsOfInch As Integer) As String
        Dim inches As Double = hundrethsOfInch / 100.0
        Return inches.ToString(CultureInfo.InvariantCulture) + "in"
    End Function

    Private Sub printPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
        Dim pageImage As Metafile = New Metafile(_streams(_currentPageIndex))

        ' Adjust rectangular area with printer margins.
        Dim adjustedRect As System.Drawing.Rectangle = _
            New System.Drawing.Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX), _
                                         ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY), _
                                         ev.PageBounds.Width, _
                                         ev.PageBounds.Height)

        ' Draw a white background for the report
        ev.Graphics.FillRectangle(System.Drawing.Brushes.White, adjustedRect)

        ' Draw the report content
        ev.Graphics.DrawImage(pageImage, adjustedRect)

        ' Prepare for the next page. Make sure we haven't hit the end.
        _currentPageIndex += 1
        ev.HasMorePages = (_currentPageIndex < _streams.Count)
    End Sub

    Private Sub printReport(report As LocalReport)
        If _streams Is Nothing OrElse _streams.Count = 0 Then
            Throw New Exception("No stream to print.")
        End If

        Dim printDoc As New PrintDocument()
        printDoc.DocumentName = report.DisplayName
        printDoc.DefaultPageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape
        printDoc.PrintController = New StandardPrintController()
        If Not printDoc.PrinterSettings.IsValid Then
            Throw New Exception("Cannot find the default printer.")
        Else
            AddHandler printDoc.PrintPage, AddressOf printPage
            _currentPageIndex = 0
            printDoc.Print()
        End If
    End Sub
End Class

Then use it like this:

Dim printer As ReportPrinter = New ReportPrinter()
printer.Print(reportViewer1.LocalReport)