Printing an rdlc report in a specific printer from an Asp.Net MVC application

Sourcecode(github)

Introduction

Today I am sharing a small method which we have adopted for automatically printing an rdlc file in my Asp.Net MVC3 application upon a button client click.

During the development of an Asp.Net MVC application we had some bottlenecks in the printing of rdlc reports from the views. We were using the client definition (rdlc) of Reporting Service for report creation. But the things were stuck on one scenario where our client required to print the reports automatically by specifying a particular printer name which is presented. Upon clicking a button the reports need to be printed in a particular printer which was configured in the admin section.

After some analysis and googling we came to know that it is not a quick win. Finally we decided to achieve it with acrobat reader and java script in the pdf. (You must have an acrobat reader plugin installed in your browser)
As per our requirement, there is a printer setting where we are setting a particular printer for a particular report by providing the IP address of the system. According to these settings a particular report must print through a printer which is provided in the settings table upon clicking some button in the client.

Code

First we have to design the report using rdlc. The next step is converting the rdlc to pdf from the action method in the controller. Also we need to inject a JavaScript for automatically printing the report in acrobat viewer. For that with the help of  iTextSharp we have converted the rdlc file into pdf at the same time we injected some JavaScript for automatic printing to the pdf.


You need to include the following namespaces which is in iTextSharp DLL
using iTextSharp.text.pdf;

The action method is as follows

public void RecieptPrint(long inv_ReceiptID)
{
      LocalReport localReport = new LocalReport();
      localReport.ReportPath = @"Reprt1.rdlc";
      DataTable dt = DataSelect();

            The following code is for dynamically setting the data source to rdlc. I already wrote about this here .

     ReportDataSource reportDataSource = new ReportDataSource();
     reportDataSource.Value = dt;
     reportDataSource.Name = "DataSet1";
     localReport.SetParameters(param);
     localReport.DataSources.Add(reportDataSource);
     string reportType = "PDF";
     string mimeType;                  
     string encoding;
     string fileNameExtension = "pdf";
/* The DeviceInfo settings should be changed based on the reportType, here I have provided the size of the pdf based on my paper requirement. */

string deviceInfo =@”<DeviceInfo>
                    <OutputFormat>PDF</OutputFormat>
                    <PageWidth>9.2in</PageWidth>
                    <PageHeight>12in</PageHeight>
                    <MarginTop>0.25in</MarginTop>
                    <MarginLeft>0.45in</MarginLeft>
                    <MarginRight>0.45in</MarginRight>
                    <MarginBottom>0.25in</MarginBottom>
                    </DeviceInfo>”;
Warning[] warnings;
string[] streams;
byte[] renderedBytes;

Now we are going to converting the rdlc to byte array using the above device info for pdf .

renderedBytes= localReport.Render(reportType,deviceInfo,out mimeType, out   encoding, out   fileNameExtension,out streams,out warnings);

Here comes the important part of the solution. We are adding this byte array to our pdf file. Also we are injecting a JavaScript code which will execute upon loading the pf in thr reader and trigger the printing.

 var doc = new Document();
 var reader = new PdfReader(renderedBytes);
 using (FileStream fs = new FileStream(Server.MapPath(“~/Summary”+  Convert.ToString(Session[“CurrentUserName“]) + “.pdf“),     FileMode.Create))
 {
     PdfStamper stamper = new PdfStamper(reader, fs);
     string Printer = "Printer_01"
     // This is the script for automatically printing the pdf in     acrobat viewer.
     stamper.JavaScript = “var pp = getPrintParams();
     pp.interactive = pp.constants.interactionLevel.automatic;    
     pp.printerName = ” + Printer + “;print(pp);\r”;
    stamper.Close();
 }
 reader.Close();
}

In view using an iframe or on a new window we can render this pdf and it will be printed automatically by executing the injected JavaScript.

Points of Interest

If we saved that pdf instead of printing while opening it will be printed automaticlay

Dynamically setting the Report Data source for rdlc in Report viewer

While using client report definition (rdlc) for reporting in a .net application we need to create a dataset for its datatsource. It may cause a problem of diiferent connections for each report are there in a single application . For avoiding  this we can dynamically set datasource for report during run time.

  1. To begin with we need to add a new rdlc file into the project.
Add a new rdlc file

2. Then add a Dataset for designing the report

Add a dataset

3. To populate the dataset add a table adapter with corresponding stored procedure or a query to fetch the data.

Dataset

4. After creating the data adapter we can access this in our report definition (rdlc)

5. Once the data set s added, design the report(rdlc) based on your using this dataset . After designing remove this dataset from the project.

6. We need to add  MicrosoftReportViwer into our form/aspx page .

7. Then we can dynamically assign the data source from the data access or business logic in the code as detailed below.

 BLL.Class obj= new BLL.Class();
 // Getting the data 
 DataTable dtTest = obj.SelectData();

 this.reportViewer1.RefreshReport();
 reportViewer1.Reset();
 reportViewer1.ProcessingMode = ProcessingMode.Local;
 LocalReport rep = reportViewer1.LocalReport;
 rep.Refresh();
 ReportDataSource rds = new ReportDataSource(dtTest);
 rep.ReportEmbeddedResource ="Report1.rdlc";
 rds.Name = "DataSet1_Data";
 this.reportViewer1.DataSource.Add(rds);
 reportViewer1.RefreshReport();

reportViewer1 : Name of the MicrosoftReportViwer control

We can also pass report parameters to rdlc as follows

//Report parameter
ReportParameter rp = new ReportParameter("content","HELLO");//(Param name,value)
this.reportViewer1.LocalReport.SetParameters(new ReportParameter[] { rp });