The code below is a class file done in vb.net. The original idea came from reading this forum and some blogs.
To use the code below, you can create a windows application or service.
then create a class file and drop this code in it.
Remeber to reference the 2005 report execution service and also in the program settings include the path to your server.
IE: ReportExecutionService = http://localhost/ReportServer/ReportExecution2005.asmx or whatever your server URL is at.
Setup the public properties for printername (sharenames work fine), Number of copies and Report name.
That is all there is to it. This code is REALLY expandable to add more options.
Please remember to let me kow if you like this.
Imports
SystemImports
System.DrawingImports
System.Drawing.ImagingImports
System.Drawing.PrintingImports
System.IOImports
System.Web.Services.ProtocolsImports
PrintReport.ReportExecutionImports
System.Runtime.InteropServices ' For Marshal.CopyNamespace
PrintReport Friend Class app Private m_sPrinterName As String Private m_sReportName As String Private m_sNumCopies As Integer<STAThread()> _
Public Sub Main(ByVal args As String()) Dim pe As PrintMain = New PrintMain() pe.PrintReport(m_sPrinterName, m_sReportName, m_sNumCopies) End Sub Public Property pPrinterName() Get Return m_sPrinterName End Get Set(ByVal value)m_sPrinterName = value
End Set End Property Public Property pReportName() Get Return m_sReportName End Get Set(ByVal value)m_sReportName = value
End Set End Property Public Property pNumCopies() Get Return m_sNumCopies End Get Set(ByVal value)m_sNumCopies = value
End Set End Property End Class Friend Class PrintMain Private rs As New ReportExecutionService() Private m_renderedReport As Byte()() Private m_delegate As Graphics.EnumerateMetafileProc = Nothing Private m_currentPageStream As MemoryStream Private m_metafile As Metafile = Nothing Private m_numberOfPages As Integer Private m_currentPrintingPage As Integer Private m_lastPrintingPage As Integer Public Sub New() ' Create proxy object and authenticaters.Credentials = System.Net.CredentialCache.DefaultCredentials
rs.Url =
My.Settings.ReportExecutionService '"http://localhost/ReportServer/ReportExecution2005.asmx" End Sub Public Function RenderReport(ByVal reportPath As String) As Byte()() ' Private variables for rendering Dim deviceInfo As String Dim format As String = "IMAGE" Dim firstPage As Byte() = Nothing Dim encoding As String = "" Dim mimeType As String = "" Dim warnings As Warning() = Nothing Dim reportHistoryParameters As ParameterValue() = Nothing Dim streamIDs As String() = Nothing Dim pages As Byte()() = Nothing Dim historyID As String = Nothing Dim showHideToggle As String = Nothing Dim execInfo As New ExecutionInfo Dim execHeader As New ExecutionHeader() Dim SessionId As String Dim extension As String = ""rs.ExecutionHeaderValue = execHeader
execInfo = rs.LoadReport(reportPath, historyID)
'rs.SetExecutionParameters(parameters, "en-us")SessionId = rs.ExecutionHeaderValue.ExecutionID
' Build device info based on the start pagedeviceInfo =
String.Format("<DeviceInfo><OutputFormat>{0}</OutputFormat></DeviceInfo>", "emf") 'Exectute the report and get page count. Try ' Renders the first page of the report and returns streamIDs for ' subsequent pagesfirstPage = rs.Render(format, deviceInfo, extension, encoding, mimeType, warnings, streamIDs)
' The total number of pages of the report is 1 + the streamIDsm_numberOfPages = streamIDs.Length + 1
pages =
New Byte(m_numberOfPages - 1)() {} ' The first page was already renderedpages(0) = firstPage
Dim pageIndex As Integer = 1 Do While pageIndex < m_numberOfPages ' Build device info based on start pagedeviceInfo =
String.Format("<DeviceInfo><OutputFormat>{0}</OutputFormat><StartPage>{1}</StartPage></DeviceInfo>", "emf", pageIndex + 1)pages(pageIndex) = rs.Render(format, deviceInfo, extension, encoding, mimeType, warnings, streamIDs)
pageIndex += 1
Loop Catch ex As SoapException 'Console.WriteLine(ex.Detail.InnerXml) Catch ex As Exception 'Console.WriteLine(ex.Message) Finally 'Console.WriteLine("Number of pages: {0}", pages.Length) End Try Return pages End Function Public Function PrintReport(ByVal printerName As String, ByVal ReportName As String, Optional ByVal NumCopies As Integer = 0) As Boolean Me.RenderedReport = Me.RenderReport(ReportName) Try ' Wait for the report to completely render. If m_numberOfPages < 1 Then Return False End If Dim printerSettings As PrinterSettings = New PrinterSettings()printerSettings.MaximumPage = m_numberOfPages
printerSettings.MinimumPage = 1
printerSettings.PrintRange = PrintRange.SomePages
printerSettings.FromPage = 1
printerSettings.ToPage = m_numberOfPages
printerSettings.Copies = NumCopies
printerSettings.PrinterName = printerName
Dim pd As PrintDocument = New PrintDocument()m_currentPrintingPage = 1
m_lastPrintingPage = m_numberOfPages
pd.PrinterSettings = printerSettings
' Print report 'Console.WriteLine("Printing report...") AddHandler pd.PrintPage, AddressOf pd_PrintPagepd.Print()
Catch ex As Exception 'Console.WriteLine(ex.Message) Finally ' Clean up goes here. End Try Return True End Function Private Sub pd_PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)ev.HasMorePages =
False If m_currentPrintingPage <= m_lastPrintingPage AndAlso MoveToPage(m_currentPrintingPage) Then ' Draw the pageReportDrawPage(ev.Graphics)
' If the next page is less than or equal to the last page, ' print another page. If m_currentPrintingPage <= m_lastPrintingPage Thenm_currentPrintingPage += 1
ev.HasMorePages =
True End If End If End Sub ' Method to draw the current emf memory stream Private Sub ReportDrawPage(ByVal g As Graphics) If Nothing Is m_currentPageStream OrElse 0 = m_currentPageStream.Length OrElse Nothing Is m_metafile Then Return End If SyncLock Me ' Set the metafile delegate. Dim width As Integer = m_metafile.Width Dim height As Integer = m_metafile.Heightm_delegate =
New Graphics.EnumerateMetafileProc(AddressOf MetafileCallback) ' Draw in the rectangle Dim destPoint As Point = New Point(0, 0)g.EnumerateMetafile(m_metafile, destPoint, m_delegate)
' Clean upm_delegate =
Nothing End SyncLock End Sub Private Function MoveToPage(ByVal page As Int32) As Boolean ' Check to make sure that the current page exists in ' the array list If Nothing Is Me.RenderedReport(m_currentPrintingPage - 1) Then Return False End If ' Set current page stream equal to the rendered pagem_currentPageStream =
New MemoryStream(Me.RenderedReport(m_currentPrintingPage - 1)) ' Set its postion to start.m_currentPageStream.Position = 0
' Initialize the metafile If Not Nothing Is m_metafile Thenm_metafile.Dispose()
m_metafile =
Nothing End If ' Load the metafile image for this pagem_metafile =
New Metafile(CType(m_currentPageStream, Stream)) Return True End Function Private Function MetafileCallback(ByVal recordType As EmfPlusRecordType, ByVal flags As Integer, ByVal dataSize As Integer, ByVal data As IntPtr, ByVal callbackData As PlayRecordCallback) As Boolean Dim dataArray As Byte() = Nothing ' Dance around unmanaged code. If data <> IntPtr.Zero Then ' Copy the unmanaged record to a managed byte buffer ' that can be used by PlayRecord.dataArray =
New Byte(dataSize - 1) {}Marshal.Copy(data, dataArray, 0, dataSize)
End If ' play the record.m_metafile.PlayRecord(recordType, flags, dataSize, dataArray)
Return True End Function Public Property RenderedReport() As Byte()() Get Return m_renderedReport End Get Set(ByVal value As Byte()())m_renderedReport = value
End Set End PropertyEnd Class
end
namespace