How do i auto print from vb.net ?
- I have posted a simlar question in th vb.net forum. But have not received an answer.
In VB.Net 2005
Using an RS serverside report.
My report is created and deployed. It uses an 8.5" by 5" form.
Interactive size and page sizes are 8.5x5
Margins are set to 0.5
Body is set to 7.5x4"
In my vb.net 2005 project:
I have a vb form with a button and a report viewer control on it.
When i click the button, the report renders correctly.
With the report rendered, I click the print button and the print dialogue shows.
I select the printer i want and select the custom form that i have created from its properties.
I click on the print button and it prints. Yeah so far.
I want to automate the entire process.
I can automate the entire process up to the point when the report fires the "render complete" event.
Inside this event, i want to choose a printer, choose the papersize, and print it.
How do i do this?
I could be happy with just chooseing the printer and printing without a user. The destination printer is a dot matrix with carbon forms in it on a tractor. There is no other paper that will be in this printer. I already have figured out that i can create the form in the printer driver and set it as the default papersize.
Anyway
Thank you up front (as usual)
Jerry Cic
Answers
Hi Jerry,
It sounds like you want to print report automatically.
By default, the SQL Server Reporting Services uses the RSClientPrint control to print report. The RSClientPrint is an ActiveX control, it will prompt the end-users a dialog for custom settings by default. The RSClientPrint control renders the report into an EMF object and then uses the PrintDocument .NET object to print the report.
So, we can do the same way to print a report automatically in a custom application:
1. Create a custom .NET application.
2. In a custom web page (or Windows form), use the Report Viewer control to display the report.
3. Add a button to the same page (or form).
4. In the button click event, use the “Render” method of the Report Viewer control to render the report to an EMF file. Or using the Reporting Services web services to render the report into an EMF object.
5. And then use the PrintDocument .NET object to print the image file using a specified printer.
By the way, if you have installed SQL Server Reporting Services product sample, you will find a print sample at the following location by default. We can use the sample code in our custom application:
C:\Program Files\Microsoft SQL Server\100\Samples\Reporting Services\Extension Samples\PrinterDelivery Sample
For more information, please see:
ReportViewer Controls (Visual Studio): http://msdn.microsoft.com/en-us/library/ms251671(VS.80).aspx
PrintDocument Class: http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx
Please try the suggestion, if anything is unclear, please feel free to ask.
Thanks,
Jin Chen
Jin Chen - MSFT- Marked As Answer byJerryCic Tuesday, November 03, 2009 2:20 AM
All Replies
- In VB.Net 2005
Using an RS serverside report.
My report is created and deployed. It uses an 8.5" by 5" form.
Interactive size and page sizes are 8.5x5
Margins are set to 0.5
Body is set to 7.5x4"
In my vb.net 2005 project:
I have a vb form with a button and a report viewer control on it.
When i click the button, the report renders correctly.
With the report rendered, I click the print button and the print dialogue shows.
I select the printer i want and select the custom form that i have created from its properties.
I click on the print button and it prints. Yeah so far.
I want to automate the entire process.
I can automate the entire process up to the point when the report fires the "render complete" event.
Inside this event, i want to choose a printer, choose the papersize, and print it.
How do i do this?
I could be happy with just chooseing the printer and printing without a user. The destination printer is a dot matrix with carbon forms in it on a tractor. There is no other paper that will be in this printer. I already have figured out that i can create the form in the printer driver and set it as the default papersize.
Anyway
Thank you up front (as usual)
Jerry Cic- Merged byMartin Xie - MSFTMSFTWednesday, November 04, 2009 8:12 AMMerge it to keep them in the same topic.
- Any takers?
How hard can it be? the secret must be in the report viewer conrtrol.
I cant find it tho. Hi Jerry,
It sounds like you want to print report automatically.
By default, the SQL Server Reporting Services uses the RSClientPrint control to print report. The RSClientPrint is an ActiveX control, it will prompt the end-users a dialog for custom settings by default. The RSClientPrint control renders the report into an EMF object and then uses the PrintDocument .NET object to print the report.
So, we can do the same way to print a report automatically in a custom application:
1. Create a custom .NET application.
2. In a custom web page (or Windows form), use the Report Viewer control to display the report.
3. Add a button to the same page (or form).
4. In the button click event, use the “Render” method of the Report Viewer control to render the report to an EMF file. Or using the Reporting Services web services to render the report into an EMF object.
5. And then use the PrintDocument .NET object to print the image file using a specified printer.
By the way, if you have installed SQL Server Reporting Services product sample, you will find a print sample at the following location by default. We can use the sample code in our custom application:
C:\Program Files\Microsoft SQL Server\100\Samples\Reporting Services\Extension Samples\PrinterDelivery Sample
For more information, please see:
ReportViewer Controls (Visual Studio): http://msdn.microsoft.com/en-us/library/ms251671(VS.80).aspx
PrintDocument Class: http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx
Please try the suggestion, if anything is unclear, please feel free to ask.
Thanks,
Jin Chen
Jin Chen - MSFT- Marked As Answer byJerryCic Tuesday, November 03, 2009 2:20 AM
- in your code you need to add the PrintToPrinter command in your line. that is the command that allows you to print autmate.
Dim Printer As New Printer
If RadioButton1.Checked = True Then
Printer.PrintAction = Printing.PrintAction.PrintToPrinter
ElseIf RadioButton2.Checked = True Then
Printer.PrintAction = Printing.PrintAction.PrintToPreview
Else
Printer.PrintFileName = _ My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData _
& "Form1.eps"
Printer.PrintAction = Printing.PrintAction.PrintToFile
End If
Don't judge me, just Upgrade me. Thanks! The following table lists the PrintAction values that are valid for the PrintAction property. Enumeration name Description PrintToFile The print operation is directed to a file. PrintToPreview The print operation is directed to a print preview dialog box. PrintToPrinter
Don't judge me, just Upgrade me. Thanks!- Thank you for your response.
I'm not sure how to impliment this approach into my situation.
My situation is that i am using a report viewer control and a server side render.
Thanks
Jerry C - Hi
4. In the button click event, use the “Render” method of the Report Viewer control to render the report to an EMF file. Or using the Reporting Services web services to render the report into an EMF object.
I got it to work well as a local report.
I would like to have it work as a server report.
I am stuck on the syntax for the render method off the serverreport object
There are three overrides. Which one do i use?
Each override has parameters that i do not understand.
I need an example.
All the examples i found were for a local report.
Any help will be appreciated.
Jerry - Hi Jerry,
If using SQL Server Reporting Services web services, please see:
http://msdn.microsoft.com/en-us/library/reportexecution2005.reportexecutionservice.render.aspx
There has a sample in the article. That is used for server report.
Thanks,
Jin Chen
Jin Chen - MSFT - Hi
I am almost there.
Dim SR As ServerReport = RV.ServerReport 'RV is a ReportViewerControl SR.ReportServerUrl = New System.Uri(GetGlobal("ReportServerUrl"))
Works. But i have to use a ReportViewer control to instantiate the serverreport object.
i can say dim LR as new LocalReport
but cannot say dim SR as new ServerReport
If is say Dim SR as ServerReport
Then i cannot say SR.ReportserverURL="/sasa/asa" as the SR object is null.
How do i instantiate an instance of a serverreport object without using a reportViewerControl?
Thanks
Jerry C - Here is my solution
I created a class object called AutoPrinter.
It is instantiated by passing it a LocalReport or a ServerReport,
along with the document width, height, and margins.
Here is how it is called:
Dim AP As New AutoPrinter(SR, 8.5, 5, 0, 0, 0, 0, "Microsoft XPS Document Writer") AP.PrintReport() AP.Dispose()
Where SR is a ServerReport object or a LocalReport object.
Here is a typical ServerReport subroutine that calls the autoprint class.
The form has a ReportViewer control on it called RV.
Here is the Server Side report routine:
Sub Print_AllOut(ByVal OE As Integer) ' server side render RV.ProcessingMode = ProcessingMode.Remote Dim SR As ServerReport = RV.ServerReport 'RV is a ReportViewerControl SR.ReportServerUrl = New System.Uri(GetGlobal("ReportServerUrl")) SR.ReportPath = GetGlobal("OEAllOutPath") Dim ReportParameters(0) As ReportParameter ReportParameters(0) = New ReportParameter("OrderNumber", OE.ToString) SR.SetParameters(ReportParameters) Dim ds$ = SR.GetDataSources.Item(0).Name Dim dc(0) As Microsoft.Reporting.WinForms.DataSourceCredentials dc(0) = New Microsoft.Reporting.WinForms.DataSourceCredentials dc(0).Name = ds dc(0).Password = UserPassword() dc(0).UserId = UserID() SR.SetDataSourceCredentials(dc) Dim AP As New AutoPrinter(SR, 8.5, 5, 0, 0, 0, 0, "Microsoft XPS Document Writer") AP.PrintReport() AP.Dispose() RV.ServerReport.Refresh() Me.RV.RefreshReport() End Sub
Here is a typical Local report routine
Sub Print_AllOutL(ByVal OE As Integer) RV.ProcessingMode = ProcessingMode.Local RV.LocalReport.ReportPath = "OE_AllOuts.rdlc" RV.LocalReport.DataSources.Add(New ReportDataSource("Haffners", _ LoadSalesData())) Dim AP As New AutoPrinter(RV.LocalReport, 8.5, 5, 0, 0, 0, 0, "Microsoft XPS Document Writer") AP.PrintReport() AP.Dispose() RV.ShowParameterPrompts = False RV.ShowCredentialPrompts = False RV.LocalReport.Refresh() Me.RV.RefreshReport() End Sub
Both routines call the autoprint class the same way.
Here is the class AutoPrint:
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 AutoPrinter Implements IDisposable Private m_currentPageIndex As Integer = 0 Private m_streams As IList(Of Stream) = Nothing Private m_LocalReport As LocalReport = Nothing Private m_ServerReport As ServerReport = Nothing Private m_PrinterName As String = "" Private m_Width As Double = 0 Private m_Height As Double = 0 Private m_TopMargin As Double = 0 Private m_LeftMargin As Double = 0 Private m_RightMargin As Double = 0 Private m_BottomMargin As Double = 0 Public RequestResult As String = "" Dim MimeType As String = "" Dim Encoding As String = "" Dim Extension As String = "" Dim m_Streamids As String() = Nothing Dim m_Streamid As String = "" Public Sub New(ByVal LocalReport As LocalReport, _ ByVal Width As Double, _ ByVal Height As Double, _ ByVal TopMargin As Double, _ ByVal LeftMargin As Double, _ ByVal RightMargin As Double, _ ByVal BottomMargin As Double, _ ByVal PrinterName As String) m_LocalReport = LocalReport m_Height = Height m_Width = Width m_TopMargin = TopMargin m_LeftMargin = LeftMargin m_RightMargin = RightMargin m_BottomMargin = BottomMargin m_PrinterName = PrinterName RequestResult = "" End Sub Public Sub New(ByVal ServerReport As ServerReport, _ ByVal Width As Double, _ ByVal Height As Double, _ ByVal TopMargin As Double, _ ByVal LeftMargin As Double, _ ByVal RightMargin As Double, _ ByVal BottomMargin As Double, _ ByVal PrinterName As String) m_ServerReport = ServerReport m_Height = Height m_Width = Width m_TopMargin = TopMargin m_LeftMargin = LeftMargin m_RightMargin = RightMargin m_BottomMargin = BottomMargin m_PrinterName = PrinterName RequestResult = "" End Sub Public Sub PrintReport() Export_Report() m_currentPageIndex = 0 Print_Report() End Sub Private Sub Export_Report() Dim DeviceInfo As String = _ "<DeviceInfo>" + _ " <OutputFormat>EMF</OutputFormat>" + _ " <PageWidth>WWWW</PageWidth>" + _ " <PageHeight>HHHH</PageHeight>" + _ " <MarginTop>TTTT</MarginTop>" + _ " <MarginLeft>LLLL</MarginLeft>" + _ " <MarginRight>RRRR</MarginRight>" + _ " <MarginBottom>BBBB</MarginBottom>" + _ "</DeviceInfo>" DeviceInfo = DeviceInfo.Replace("WWWW", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("HHHH", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("TTTT", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("LLLL", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("RRRR", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("BBBB", m_Width.ToString("0.00in")) Dim warnings() As Warning = Nothing m_streams = New List(Of Stream)() If m_LocalReport IsNot Nothing Then m_LocalReport.Render("Image", DeviceInfo, AddressOf CreateStream, _ warnings) End If If m_ServerReport IsNot Nothing Then Dim myStream As New MemoryStream( _ m_ServerReport.Render("Image", DeviceInfo, MimeType, _ Encoding, Extension, m_Streamids, warnings)) m_streams.Add(myStream) Dim myImage As Byte() For Each m_Streamid In m_Streamids myImage = m_ServerReport.RenderStream("Image", m_Streamid, _ Nothing, Nothing, Nothing) myStream = New MemoryStream(myImage) m_streams.Add(myStream) Next End If Dim Stream As Stream For Each stream In m_streams stream.Position = 0 Next End Sub 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 New MemoryStream m_streams.Add(stream) Return stream End Function Private Sub Print_Report() If m_streams Is Nothing Or m_streams.Count = 0 Then Return End If Dim PrintDoc As New PrintDocument() 'The following line removes the printing page ?? of ?? messagebox PrintDoc.PrintController = New System.Drawing.Printing.StandardPrintController() PrintDoc.PrinterSettings.PrinterName = m_PrinterName If Not PrintDoc.PrinterSettings.IsValid Then Dim msg As String = String.Format( _ "Can't find printer ""{0}"".", m_PrinterName) Console.WriteLine(msg) Return End If AddHandler PrintDoc.PrintPage, AddressOf PrintPage PrintDoc.Print() End Sub 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) Debug.Print(m_currentPageIndex.ToString) m_currentPageIndex += 1 ev.HasMorePages = (m_currentPageIndex < m_streams.Count) End Sub Public Overloads Sub Dispose() Implements IDisposable.Dispose If Not (m_streams Is Nothing) Then Dim stream As Stream For Each stream In m_streams stream.Close() Next m_streams = Nothing End If End Sub End Class
This method will print to the printer indicated without running the print dialogue.
It will also surpress the "Printing page ?? of ??" message box.
The routine will display a message box if the printer passed to the routine is not a valid printer.
This has worked well for me and i hope it will help others as well.
Thanks
Jerry Cicierega - Thank you very much for this script, just what I needed.
Just a typo from cop/ paste
DeviceInfo = DeviceInfo.Replace("WWWW", m_Width.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("HHHH", <span style="font-size:x-small">m_Height</span>.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("TTTT", <span style="font-size:x-small">m_TopMargin</span>.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("LLLL", <span style="font-size:x-small">m_LeftMargin</span>.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("RRRR", <span style="font-size:x-small">m_rightMargin</span>.ToString("0.00in")) DeviceInfo = DeviceInfo.Replace("BBBB", <span style="font-size:x-small">m_BottomMargin</span>.ToString("0.00in"))
it's all very nice when it works


