SQLServerCentral Article

Using an RDL File Locally in .NET to Print Reports

,

Problem

Often in our applications there is a need to print out some data.  It seems in this day and age the need to print should completely go away, but sadly, the requirement keeps coming up.  This happened recently on an application I was working on.  This article describes the solution I decided to use.

Solution

When you need to print data on paper, one of the things to be concerned about is that it will print correctly on any printer that it might print on.  Putting printed reports into PDF format is a good solution to this issue.   With the PDF format, what you see is almost always what will print out.  In this case, I decided to go with a Reporting services report (RDL format).   This format allows you to easily export to PDF for printing.  The only caveat is I am not calling a Reporting Services Server.  I am creating the PDF directly in the .NET application.  This is done by using a Reporting Services .net dll in your .NET Winforms project that allows you to attach data and render the local report as a PDF.

The Process

First you need to create a Reporting Services report.  If you are not familiar with this, there are plenty of great articles on it.  I have attached an example project with a sample RDL report (RDLExample.rdl).

Next, create a new .NET Windows Forms app, although this code also works in WPF and should work in Universal as well.

Next add the Reporting Services nuget package.  You do this by right clicking references and then select manage nuget packages.

Click on Browse and type: Microsoft.reportingservices in the search.

Select the Microsoft.ReportingServices.ReportViewerControl.WebForms and then click install.

Now I know it seems strange to add a WebForm control to a Windows Form app.  The reason for this is we aren’t actually using any of the WebForms UI and the render method is simpler than the WinForm render method.

Next there are several references that were added we only need the WebForms dll that was added.  I suggest removing the others since they aren’t used and just add to the size of what you have to deploy.

The .NET Code

The code is simple, and I have included comments inside.

//The .net code is pretty simple.  First load the RDL file.
Microsoft.Reporting.WebForms.LocalReport report = new Microsoft.Reporting.WebForms.LocalReport();
//Point the saved RDL report NOTE: if your rdl file isn't here point to where your file is located
report.ReportPath = @"c:\temp\RDLExample.rdl";
//Next set the datasource with the data you want to print.
System.Data.DataTable tbl = scheduleData.Tables[0];
//create the dataset that we will attach to the report
Microsoft.Reporting.WebForms.ReportDataSource rds = new Microsoft.Reporting.WebForms.ReportDataSource();
//Set the datasource so the report has data
rds.Name = "dsSchedule"; //This refers to the dataset name in the RDL file
rds.Value = tbl;
report.DataSources.Add(rds);
//You may need to set some default values for report parameters if they exist.
//Set dummy values for report parameters so the report doesn't blow up
                    //NOTE even if hidden parameters you need to have a prompt in the report file so that they can be set here
                    report.SetParameters(new List<Microsoft.Reporting.WebForms.ReportParameter> {
                        new Microsoft.Reporting.WebForms.ReportParameter("PlantName","YourPlant"),
                        new Microsoft.Reporting.WebForms.ReportParameter("ServerName", "Server"),
                        new Microsoft.Reporting.WebForms.ReportParameter("DatabaseName", "DB"),
                        new Microsoft.Reporting.WebForms.ReportParameter("ConnectionString", "ConnStr")
                    });
//Next render the report as a PDF.
//Create the PDF of the report
Byte[] mybytes = report.Render("PDF");
//Finally write out the PDF file and display it.
if (mybytes != null && mybytes.Length > 0)
{
  //You may need to pick a different folder to write to if c:\temp doesn't exist
  using (FileStream fs = File.Create(@"c:\temp\test.pdf"))
  {
    fs.Write(mybytes, 0, mybytes.Length);
  }
//Now we open the pdf file we just created
System.Diagnostics.Process.Start(@"c:\temp\test.pdf");
}

Example

In my example app, after you have run the script files to create the database objects and sample data click the get data button.

Then you can click the Print Local button to see the RDL PDF file.

The example does have a Write RDL File to DB button that will take the local RDL file and put it in the database table.  Then the Print from RDL DB will use the RDL file stored in the database.

You can store RDL files in Varbinary(max) column in a table.  The reason I mention this is that the Reporting services server stores the RDL files when you save them in the ReportServer database in the dbo.catalog table.  So, you can get the RDL files from that table if you so choose.

In my actual application, I wrote a process to copy the RDL file from the central Reporting services server out to the remote plants to a local database there.  Then we didn’t have to worry about remote plants needing access to the catalog table and the report still works if the WAN goes down.

Conclusion

This article showed how to use a reporting services RDL file and render it directly from a .NET winform application.  This allows you to print from an application without having to be tied to a reporting services instance.  I hope you enjoyed this article and find it helpful with your printing needs.

Resources

Rate

5 (7)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (7)

You rated this post out of 5. Change rating