EDN Admin
Well-known member
I have a print function in my code that will render an SSRS report and print it out on the printer. This way we can create one SSRS report and use it both on the web and on the winform. I have been asked to now do a printpreview of the report so the user can view the report and print if they want. I have created an rsPrint class which I have attached. I need the PrintReview Method to show a printpreview dialog with the report. All I get now is a black image. Any help is appreciated.
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
Public Function PrintReview() As Boolean
If m_streams Is Nothing Or m_streams.Count = 0 Then
Return False
End If
Dim ppdlg As New PrintPreviewDialog
Dim printDoc As New PrintDocument
printDoc.PrinterSettings.PrinterName = _Printer
AddHandler printDoc.PrintPage, AddressOf PrintPage
printDoc.DefaultPageSettings.Landscape = False
printDoc.PrinterSettings.Copies = 1
printDoc.DefaultPageSettings.PrinterSettings.Duplex = Duplex.Horizontal
ppdlg.Document = printDoc
ppdlg.ShowDialog()
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)
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
View the full article
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
Public Function PrintReview() As Boolean
If m_streams Is Nothing Or m_streams.Count = 0 Then
Return False
End If
Dim ppdlg As New PrintPreviewDialog
Dim printDoc As New PrintDocument
printDoc.PrinterSettings.PrinterName = _Printer
AddHandler printDoc.PrintPage, AddressOf PrintPage
printDoc.DefaultPageSettings.Landscape = False
printDoc.PrinterSettings.Copies = 1
printDoc.DefaultPageSettings.PrinterSettings.Duplex = Duplex.Horizontal
ppdlg.Document = printDoc
ppdlg.ShowDialog()
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)
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
View the full article