Article Overview
- Background
- Prerequisites
- How to print rdlc report directly to the printer in MVC
- Complete example
- Output
- Summary
Background
There was a situation where I had to render an RDLC report into an MVC application and directly open it to the print dialog box.
Hence, I have created an rdlc report in MVC rendered that report as bytes using ReportViewer, and saved it to a pdf file. I have used PdfReader and added JavaScript to the 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 the RDLC report directly to the 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 for the project.
First, create an MVC project.
Second, add a 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 the (consume) report in the C# (code).
First, add the “Microsoft.ReportViewer.WebForms” reference to the project.
Second, add the “Microsoft.ReportViewer.WebForms” namespace.
using Microsoft.Reporting.WebForms;
Third, write code and set the 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 the 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 the pdf file and add some properties to that pdf file as described below.
// File
string FileName = "Test_" + DateTime.Now.Ticks.ToString() + ".pdf";
string FilePath = HttpContext.Server.MapPath(@"~\TempFiles\") + FileName;
// Create and set PdfReader
PdfReader reader = new PdfReader(bytes);
FileStream output = new FileStream(FilePath, FileMode.Create);
string Agent = HttpContext.Request.Headers["User-Agent"].ToString();
// Create and set PdfStamper
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 a print popup will open especially for the Firefox web browser.
Third, return the created pdf file’s path.
// Return file 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.
Complete example
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)
The 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()
{
// Report
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.LocalReport.ReportPath = Server.MapPath(@"~\Report1.rdlc");
// Byte
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);
// File
string FileName = "Test_" + DateTime.Now.Ticks.ToString() + ".pdf";
string FilePath = HttpContext.Server.MapPath(@"~\TempFiles\") + FileName;
// create and set PdfReader
PdfReader reader = new PdfReader(bytes);
FileStream output = new FileStream(FilePath, FileMode.Create);
string Agent = HttpContext.Request.Headers["User-Agent"].ToString();
// create and set PdfStamper
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();
// return file path
string FilePathReturn = @"TempFiles/" + FileName;
return Content(FilePathReturn);
}
Output
The output will be like the following in Chrome browser after clicking on the "Export to PDF" button.
Summary
Now, I believe you will be able to print rdlc reports directly to the printer in MVC.