none
How to create a winform application that uses report builder and print directly to printer without viewing the report RRS feed

  • Question

  • In VS 2008, we created a winform with a report viewer on it. We run the report and the report displays in the control on the winform. You can click print on the toolbar and the print preview dialog box comes up. Select printer and print, the report prints to the printer.

    What we want to do is have the report render from the rdlc we created and the dataset we set up but not show up in the report viewer on the winform, not have to set printer dialog box properties and just have it print to the default printer on this client machine when the user click a print button on the winform.

    We looked at 5 similar questions but they were not using the report rendered at runtime.

    Got any samples anywhere or suggestions?

    Thanks

    Bruce

    Wednesday, May 28, 2014 6:49 PM

Answers

  • Bruce,

    Yes, you can do it.

    You need to use a Winform, but you don't display it. You need to use a Winform because the report rendering methods will only work from a Windows form. So you use the same code that you use in the form, but instead of the form.showdialog method, you use :

    Dim myFileNameAs String = "MyFileName"
    
    Dim bytes As Byte() = form.reportViewer.LocalReport.Render("Pdf")
    Using stream As IO.FileStream = New IO.FileStream(myFileName, IO.FileMode.Create)
         stream.Write(bytes, 0, bytes.Length)
    End Using
    

    • Marked as answer by Bmayfield Thursday, June 5, 2014 3:11 PM
    Tuesday, June 3, 2014 9:04 PM
  • Bruce,

    You are probably using a different version of the .net Framework, and your Render method requires additional parameters. You can find out which parameters are missing by typing only the method name ("Render") with the first parenthesis only. This will ask IntelliSense to display all overloads with their respective parameters.

    Another way of doing this is to select the method name ("Render") and hit F1.

    When you find out which parameters are missing, fill them and you should be OK.

    Also, this code only generates a report in a file. To actually print the file, you need to add code like this :

     Dim p As New System.Diagnostics.Process
                p.StartInfo.FileName = file.FullName
                p.StartInfo.Verb = "print"
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
                p.Start()
    

    • Marked as answer by Bmayfield Thursday, June 5, 2014 3:12 PM
    Wednesday, June 4, 2014 2:39 PM

All replies

  • Bruce,

    Yes, you can do it.

    You need to use a Winform, but you don't display it. You need to use a Winform because the report rendering methods will only work from a Windows form. So you use the same code that you use in the form, but instead of the form.showdialog method, you use :

    Dim myFileNameAs String = "MyFileName"
    
    Dim bytes As Byte() = form.reportViewer.LocalReport.Render("Pdf")
    Using stream As IO.FileStream = New IO.FileStream(myFileName, IO.FileMode.Create)
         stream.Write(bytes, 0, bytes.Length)
    End Using
    

    • Marked as answer by Bmayfield Thursday, June 5, 2014 3:11 PM
    Tuesday, June 3, 2014 9:04 PM
  • We tried to code this:

    ' old working code in line below, this brings up preview and you have to use print dialog and click print
    'Me.ReportViewer1.RefreshReport()   '// replace working code with the suggested code below

    Dim myFileName As String = "c:\temp\myPdf.pdf"
    Dim bytes As Byte() = Me.ReportViewer1.LocalReport.Render("pdf")
    Using stream As IO.FileStream = New IO.FileStream(myFileName, IO.FileMode.Create)
    stream.Write(bytes, 0, bytes.Length)
    End Using

    Visual Studio gives "Overload resolution failed because no accessible render accepts this number of arguments." error was on "Me.ReportViewer1.LocalReport.Render("pdf")"

    Crystal Reports comes with VS 2008 but not with 2013. We plan to go to VS 2013. It is installed now and we are trying to self train ourselves on VS 2013. But for the very near future we are still on 2008 until we get some infrastructure changes implemented for .NET 4.5 for client environment. Here is something very close to what we need that we are looking to do with Report Builder that Crystal does in a test winform program in 2008:

            Dim DataSet1 As DataSet
            Dim adoOleDbConnection As OleDbConnection
            Dim adoOleDbDataAdapter As OleDbDataAdapter

            Dim connectionString As String = ""
            connectionString = "Provider=OraOLEDB.Oracle;"
            connectionString += "Data Source=DEV;"
            connectionString += "User ID=APPSPIPE;Password=xxxx731P"
            adoOleDbConnection = New OleDbConnection(connectionString)
            Dim sqlString As String = ""
            sqlString = "SELECT * FROM edi_filing_source_lov"
            adoOleDbDataAdapter = New OleDbDataAdapter(sqlString, adoOleDbConnection)
            DataSet1 = New DataSet()
            adoOleDbDataAdapter.Fill(DataSet1, "edi_filing_source_lov")
            crReportDocument.Database.Tables(0).SetDataSource(DataSet1)
            crReportDocument.PrintOptions.PrinterName = "HP_LaserJet_4350_PCL_5e_Info_Tech"
            crReportDocument.Refresh()
            crReportDocument.PrintToPrinter(1, False, 1, 1)

    Our very first preference is that we use Oracle ODP.NET but we have had difficulty getting Crystal to see the Oracle datasource or dataset, but as a test we used Oracle OLE DB which works in Crystal. Otherwise we would use Oracle Data Access connection, dataAdapter and command components instead in the above example code. We are looking for the ability to run a silent (unattended background or batch execution) to generate hundreds of multi-page form letters to print to a Xerox Docutech 6180 printer located in another building.

    We hope Microsoft's Report Builder can do this. Looking for a working example.

    Thanks for responding.

    Bruce


    • Edited by Bmayfield Wednesday, June 4, 2014 2:26 PM
    Wednesday, June 4, 2014 2:24 PM
  • Bruce,

    You are probably using a different version of the .net Framework, and your Render method requires additional parameters. You can find out which parameters are missing by typing only the method name ("Render") with the first parenthesis only. This will ask IntelliSense to display all overloads with their respective parameters.

    Another way of doing this is to select the method name ("Render") and hit F1.

    When you find out which parameters are missing, fill them and you should be OK.

    Also, this code only generates a report in a file. To actually print the file, you need to add code like this :

     Dim p As New System.Diagnostics.Process
                p.StartInfo.FileName = file.FullName
                p.StartInfo.Verb = "print"
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
                p.Start()
    

    • Marked as answer by Bmayfield Thursday, June 5, 2014 3:12 PM
    Wednesday, June 4, 2014 2:39 PM
  • Getting closer.

    Here is code now:

            Dim myFileName As String = "c:\temp\myPdf.pdf"
            Dim deviceInfo As String = "<DeviceInfo>" & _
            "<OutputFormat>PDF</OutputFormat>" & _
            "<PageWidth>11in</PageWidth>" & _
            "<PageHeight>8.5in</PageHeight>" & _
            "<MarginTop>0.25in</MarginTop>" & _
            "<MarginLeft>0.25in</MarginLeft>" & _
            "<MarginRight>0.25in</MarginRight>" & _
            "<MarginBottom>0.25in</MarginBottom>" & _
            "</DeviceInfo>"
            Dim warnings As Warning() = Nothing
            Dim streamids As String() = Nothing
            Dim mimeType As String = Nothing
            Dim encoding As String = Nothing
            Dim extension As String = Nothing

           Dim bytes As Byte() = Me.ReportViewer1.LocalReport.Render("PDF", deviceInfo, mimeType, _
                  encoding, extension, streamids, warnings)

            Dim fs As New FileStream(myFileName, FileMode.Create)
            fs.Write(bytes, 0, bytes.Length)
            fs.Close()
            fs = Nothing

            Dim p As New System.Diagnostics.Process
            p.StartInfo.FileName = myFileName
            p.StartInfo.Verb = "printto"
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            p.StartInfo.Arguments = "\\10.xx.xx.x\HP_LaserJet_4350_PCL_5e_CC"
            p.Start()

    A concern we have is the use of the byte array. If we generate 1500 letters at two pages double sided we could be looking at a 20 mb data stream that would be created in memory. We do not want to run out of memory, will the byte array handle generated report data that size? If so what would be a reasonable limitation?

    Thanks.

    Bruce

    Wednesday, June 4, 2014 5:14 PM
  • Bruce, The file generation process and the printing process should be different. You may want to print 1500 copies of the same report, so that would mean running the report generation code once and running the print code 1500 times. So you need to create two different procedures : CreateReportFile and PrintReport that will be run in loops, according to your needs. The byte array is used only once per report. When the report file is generated, you dont need the byte array anymore. That's another benefit of using separate procedures : the variables created in the procedure are local and will be dismissed when the procedure is finished. To create a procedure, enclose the corresponding code with : Sub nameOfProcedure ......... procedure code End Sub To call this procedure, simply use its name : nameOfProcedure
    Wednesday, June 4, 2014 6:22 PM
  • In our case the the report viewer points to a data source where the data adapter will get filled from a select statement that will potentially return 1500 rows from a table:

    odaFriDups.Fill(FriDups1)

    When we run the "Me.ReportViewer1.RefreshReport()" all the rows get displayed at once. So far, the table we our testing with in this post only returns 75 rows.

    Thanks.

    Bruce


    • Edited by Bmayfield Wednesday, June 4, 2014 9:13 PM
    Wednesday, June 4, 2014 9:00 PM