Article Overview
- Background
- Prerequisites
- How to print rdlc report directly to printer in MVC
- Complete example
- Output
- Summary
Background
There was a situation where I had to render an rdlc report into a MVC application and directly open it to the print dialog box.
Hence, I have created an rdlc report in MVC and rendered that report as bytes using ReportViewer and saved it to pdf file. I have used PdfReader and added JavaScript to pdf file through PdfStamper for the mozilla browser issue. After that, I opened a print dialog using JavaScript.
Here, I have kept all the implementation details along with a complete example.
Prerequisites
- You should have a basic knowledge of RDLC report implementation as well as MVC applications.
- Reference of "Microsoft.ReportViewer.WebForms" and "iTextSharp"
How to print rdlc report directly to printer in MVC
There are mainly four key steps to implement this:
- Create rdlc report in MVC
- Use ReportViewer and render as bytes
- Create pdf file using PdfReader and add JavaScript to pdf file through PdfStamper
- Open Print dialog using JavaScript
Now, let us see in detail.
Create rdlc report
Our first task is to add and create a report file into the project.
First, create a MVC project.
Second, add new RDLC report by “Add New Item” => “Visual C#” => “Report” selection.
Third, design report. To make it easy to understand I have created one simple static report without any database connection just for simplicity.
User ReportViewer and render as bytes
Now, our second task is to use (consume) report into the C# (code).
First, add “Microsoft.ReportViewer.WebForms” reference into the project.
Second, add “Microsoft.ReportViewer.WebForms” namespace.
- using Microsoft.Reporting.WebForms;
Third, write code and set report path.
- reportViewer.LocalReport.ReportPath = Server.MapPath(@"~\Report1.rdlc");
Create pdf file using PdfReader and add JavaScript to pdf file through PdfStamper
Now, we have to render (convert) the report into bytes and save it as a pdf file along with some JavaScript settings like the following:
First, render report into bytes.
- Warning[] warnings;
- string[] streamids;
- string mimeType, encoding, filenameExtension;
-
- byte[] bytes = reportViewer.LocalReport.Render("Pdf", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
Second, add iTextShart using NuGet to save pdf file and add some properties to that pdf file as described below.
-
- string FileName = "Test_" + DateTime.Now.Ticks.ToString() + ".pdf";
- string FilePath = HttpContext.Server.MapPath(@"~\TempFiles\") + FileName;
-
-
- PdfReader reader = new PdfReader(bytes);
- FileStream output = new FileStream(FilePath, FileMode.Create);
-
- string Agent = HttpContext.Request.Headers["User-Agent"].ToString();
-
-
- PdfStamper pdfStamper = new PdfStamper(reader, output, '0', true);
-
- if (Agent.Contains("Firefox"))
- pdfStamper.JavaScript = "var res = app.loaded('var pp = this.getPrintParams();pp.interactive = pp.constants.interactionLevel.full;this.print(pp);');";
- else
- pdfStamper.JavaScript = "var res = app.setTimeOut('var pp = this.getPrintParams();pp.interactive = pp.constants.interactionLevel.full;this.print(pp);', 200);";
-
- pdfStamper.FormFlattening = false;
- pdfStamper.Close();
- reader.Close();
Here, PdfStamper is being used to add JavaScript so that print popup will open especially for FireFox web browser.
Third, return created pdf file’s path.
-
- string FilePathReturn = @"TempFiles/" + FileName;
- return Content(FilePathReturn);
Note, that here I am creating a pdf file and storing it into the “TempFiles” folder location.
Open Print dialog
Now, our last task is to open a file into the print dialog.
First, place a placeholder for pdf to show.
- <div id="divPDF">
- <div id="printerDiv"><iframe id="frmPDF"></iframe></div>
- </div>
Second, assign pdf and call print option from JavaScript.
- $('#frmPDF').attr('src', '@Url.Content("~/")' + result);
- setTimeout(function () {
- frame = document.getElementById("frmPDF");
- framedoc = frame.contentWindow;
- framedoc.focus();
- framedoc.print();
- }, 1000);
That’s it.
For your reference, I have kept the complete example in a single folder and uploaded that with this article and it contains the below files:
- Index.cshtml (View)
- HomeController.cs (Controller)
- Report1.rdlc (Report)
- TempFiles (Folder to store created pdf file)
Complete code is like the following:
View (Index.cshtml)
- <style>
- #printerDiv iframe { position: absolute; top: -1000px; }
- </style>
- <div class="jumbotron">
- <button onclick="funExportToPDF()">Export to PDF</button>
- </div>
-
- <div id="divPDF">
- <div id="printerDiv"><iframe id="frmPDF"></iframe></div>
- </div>
-
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
-
- <script type="text/javascript">
-
- function funExportToPDF() {
-
- $.ajax({
- url: '@Url.Action("ExportToPDF", "Home")',
- type: 'GET',
- contentType: 'application/json; charset=utf-8',
- success: function (result) {
-
- $('#frmPDF').attr('src', '@Url.Content("~/")' + result);
-
- setTimeout(function () {
- frame = document.getElementById("frmPDF");
- frameframedoc = frame.contentWindow;
- framedoc.focus();
- framedoc.print();
- }, 1000);
- },
- error: function (xhr, status, err) {
- alert(err);
- }
- });
-
- return false;
- }
-
- </script>
Controller (HomeController.cs)
- public ActionResult ExportToPDF()
- {
-
- ReportViewer reportViewer = new ReportViewer();
-
- reportViewer.ProcessingMode = ProcessingMode.Local;
- reportViewer.LocalReport.ReportPath = Server.MapPath(@"~\Report1.rdlc");
-
-
- Warning[] warnings;
- string[] streamids;
- string mimeType, encoding, filenameExtension;
-
- byte[] bytes = reportViewer.LocalReport.Render("Pdf", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
-
-
- string FileName = "Test_" + DateTime.Now.Ticks.ToString() + ".pdf";
- string FilePath = HttpContext.Server.MapPath(@"~\TempFiles\") + FileName;
-
-
- PdfReader reader = new PdfReader(bytes);
- FileStream output = new FileStream(FilePath, FileMode.Create);
-
- string Agent = HttpContext.Request.Headers["User-Agent"].ToString();
-
-
- PdfStamper pdfStamper = new PdfStamper(reader, output, '0', true);
-
- if (Agent.Contains("Firefox"))
- pdfStamper.JavaScript = "var res = app.loaded('var pp = this.getPrintParams();pp.interactive = pp.constants.interactionLevel.full;this.print(pp);');";
- else
- pdfStamper.JavaScript = "var res = app.setTimeOut('var pp = this.getPrintParams();pp.interactive = pp.constants.interactionLevel.full;this.print(pp);', 200);";
-
- pdfStamper.FormFlattening = false;
- pdfStamper.Close();
- reader.Close();
-
-
- string FilePathReturn = @"TempFiles/" + FileName;
- return Content(FilePathReturn);
- }
The output will be like following in Chrome browser after clicking on "Export to PDF" button:
Now, I believe you will be able to print rdlc reports directly to the printer in MVC.