none
Auto report printing class only printing 1 page

    Question

  • I have a class written by another developer to automatically print reporting services reports without the print dialog box. However it will only print one page even if the report has multiple.

    I assume it has something to do with the io Streams because it never goes into the loop For Each stream in streamIDs in the Render Function.

    Here is the code. 

    Imports System.IO
    Imports System.Data
    Imports System.Text
    Imports System.Drawing.Imaging
    Imports System.Drawing.Printing
    Imports System.Collections.Generic
    Imports Microsoft.Reporting.WinForms
    
    Public Class PrintReport
        Implements IDisposable
    
        Private _Printer As String
        Dim Report As ReportViewer
        Private _bLandscape As Boolean = False
        Private _topMargin As Decimal = 0.1
        Private _bottomMargin As Decimal = 0.1
        Private _leftMargin As Decimal = 0.1
        Private _rightMargin As Decimal = 0.1
        Private m_currentPageIndex As Integer
        Private m_streams As Generic.List(Of IO.MemoryStream)
        Private _Rendered As Byte()
    #Region "Properties"
        Public Property LandScape() As Boolean
            Get
                Return _bLandscape
            End Get
            Set(ByVal value As Boolean)
                _bLandscape = value
            End Set
        End Property
    
        Public Property Printer() As String
            Get
                Return _Printer
            End Get
            Set(ByVal value As String)
                _Printer = value
            End Set
        End Property
        Public Property TopMargin() As Decimal
            Get
                Return _topMargin
            End Get
            Set(ByVal value As Decimal)
                _topMargin = value
            End Set
        End Property
        Public Property BottomMargin() As Decimal
            Get
                Return _bottomMargin
            End Get
            Set(ByVal value As Decimal)
                _bottomMargin = value
            End Set
        End Property
        Public Property LeftMargin() As Decimal
            Get
                Return _leftMargin
            End Get
            Set(ByVal value As Decimal)
                _leftMargin = value
            End Set
        End Property
        Public Property RightMargin() As Decimal
            Get
                Return _rightMargin
            End Get
            Set(ByVal value As Decimal)
                _rightMargin = value
            End Set
        End Property
    #End Region
    
        Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
            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
        ''' <summary>
        ''' This function will print the report calling the printpage function
        ''' </summary>
        ''' <param name="tray">Tray number to print to</param>
        ''' <param name="copies">Number of copies to print</param>
        ''' <returns>True the page printed, false the page did not print</returns>
        ''' <remarks></remarks>
        Public Function Print(ByVal tray As String, ByVal copies As String) As Boolean
            Try
    
    
                If m_streams Is Nothing Or m_streams.Count = 0 Then
                    Return False
                End If
                Dim printDoc As New PrintDocument
                printDoc.PrinterSettings.PrinterName = _Printer
                AddHandler printDoc.PrintPage, AddressOf PrintPage
                printDoc.DefaultPageSettings.Landscape = _bLandscape
                printDoc.PrinterSettings.Copies = copies
    
                For Each ps As PaperSource In printDoc.PrinterSettings.PaperSources
                    If ps.SourceName = tray Then
                        printDoc.DefaultPageSettings.PaperSource = ps
                        If tray = "Tray 4" Then
                            printDoc.DefaultPageSettings.PrinterSettings.Duplex = Duplex.Horizontal
                        Else
                            printDoc.DefaultPageSettings.PrinterSettings.Duplex = Duplex.Simplex
                        End If
                    End If
                Next
                printDoc.Print()
            Catch ex As Exception
                MessageBox.Show("Error in function Print. Error: " & ex.message.tostring, "Print Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return False
            End Try
        End Function
        ''' <summary>
        ''' This function will render the report from reporting services according to page parameters properties.  You must render the report
        ''' before you can print it.
        ''' </summary>
        ''' <param name="Report">This is the server report object that will be rendered</param>
        ''' <returns>True, the report rendered.  False, the report did not render</returns>
        ''' <remarks></remarks>
        Public Function Render(ByVal Report As ServerReport) As Boolean
            Try
                Dim warnings As Warning()
                Dim streamIDs As String()
                Dim mimeType As String = ""
                Dim encoding As String = ""
                Dim extension As String = ""
                Dim deviceInfo As String = ""
                Dim format As String = "Image"
                Select Case _bLandscape
                    Case False
                        deviceInfo = _
                        "<DeviceInfo>" + _
                        " <OutputFormat>EMF</OutputFormat>" + _
                        " <PageWidth>8.5in</PageWidth>" + _
                        " <PageHeight>11in</PageHeight>" + _
                        " <MarginTop>" & _topMargin & "in</MarginTop>" + _
                        " <MarginLeft>" & _leftMargin & "in</MarginLeft>" + _
                        " <MarginRight>" & _rightMargin & "in</MarginRight>" + _
                        " <MarginBottom>" & BottomMargin & "in</MarginBottom>" + _
                        "</DeviceInfo>"
                    Case True
                        deviceInfo = _
                        "<DeviceInfo>" + _
                        " <OutputFormat>EMF</OutputFormat>" + _
                        " <PageWidth>11in</PageWidth>" + _
                        " <PageHeight>8.5in</PageHeight>" + _
                        " <MarginTop>" & _topMargin & "in</MarginTop>" + _
                        " <MarginLeft>" & _leftMargin & "in</MarginLeft>" + _
                        " <MarginRight>" & _rightMargin & "in</MarginRight>" + _
                        " <MarginBottom>" & BottomMargin & "in</MarginBottom>" + _
                        "</DeviceInfo>"
                End Select
                Dim streamID As String
                Dim myParameters(0) As ReportParameter
                m_streams = New Generic.List(Of IO.MemoryStream)
                _Rendered = Report.Render(format, deviceInfo, mimeType, encoding, extension, streamIDs, warnings)
                Dim stream As New MemoryStream
                stream.Write(_Rendered, 0, CInt(_Rendered.Length))
                m_streams.Add(stream)
                MessageBox.Show(m_currentPageIndex)
                For Each streamID In streamIDs
                    _Rendered = Report.RenderStream(format, streamID, deviceInfo, mimeType, encoding)
                    stream = New MemoryStream
                    stream.Write(_Rendered, 0, CInt(_Rendered.Length))
                    m_streams.Add(stream)
                Next
                For Each stream In m_streams
                    stream.Position = 0
                Next
                'm_currentPageIndex = 0
                Return True
            Catch ex As Exception
                MessageBox.Show("Error rending report in Render fuction. Error: " & ex.message.tostring, "Render Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return False
            End Try
    
        End Function
    
        Private disposedValue As Boolean = False        ' To detect redundant calls
        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not (m_streams Is Nothing) Then
                For Each Stream As Stream In m_streams
                    Stream.Close()
                Next
                m_streams = Nothing
            End If
            Me.disposedValue = True
        End Sub
    
    #Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    #End Region
        Public Sub New()
            Report = New ReportViewer
        End Sub
    End Class
    
    

    Wednesday, March 15, 2017 8:55 PM

All replies

  • Hi

    Might be an idea to ask the 'another developer'. After all, he/she would know the answer.


    Regards Les, Livingston, Scotland

    Wednesday, March 15, 2017 10:39 PM
  • I assume it has something to do with the io Streams because it never goes into the loop For Each stream in streamIDs in the Render Function.

    Are you sure that Report.Render is returning more than one StreamID?   Insert a breakpoint after the call to Report.Render and look at the count of streams.  You need to confirm that the StreamIDs collection is being passed by reference and is being updated correctly.  

    Wednesday, March 15, 2017 11:03 PM