Ask a questionAsk a question
 

AnswerHow do i auto print from vb.net ?

  • Thursday, October 29, 2009 4:08 AMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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

  • Friday, October 30, 2009 8:05 AMJin ChenMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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

  • Wednesday, October 28, 2009 9:59 PMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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.
    •  
  • Friday, October 30, 2009 3:34 AMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Any takers?

    How hard can it be? the secret must be in the report viewer conrtrol.

    I cant find it tho.

  • Friday, October 30, 2009 8:05 AMJin ChenMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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
    •  
  • Sunday, November 01, 2009 7:37 PMMalange Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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!
  • Sunday, November 01, 2009 7:38 PMMalange Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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!
  • Tuesday, November 03, 2009 3:45 AMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Sunday, November 08, 2009 1:39 AMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Monday, November 09, 2009 1:39 AMJin ChenMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Saturday, November 14, 2009 9:48 PMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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

  • Sunday, November 15, 2009 3:30 AMJerryCic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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
  • Tuesday, November 17, 2009 4:02 PMPhilippe Devaux_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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