Microsoft Reporting Tools (SSRS) is a powerful reporting component freely available for .net developpers using Visual Studio, unfortunatly printing has always been an issue: The .net reportviewer only works on Internet Browser because the print button is an Active-X control, so for users using other browsers like Google Chrome, Firefox, Opera... the print button is hidden and they will have to download the rapport as a pdf, word doc.. and print it from there.
Also exporting a report to HTML format programmatically is not available for LocalReport, it's only available on the SQL Server Reporting Services (SSRS).
So I had to come up with a solution that :
- Enable printing for LocalReports in webforms.
- Works on all other browsers (Chrome, Firefox, Opera...).
- Allow multiple pages printing at once (since Reportviewer only shows the first page)
- Doesn't mess up with the PDF, DOC, Excel, Image export formats and layout.
- Doesn't require the client to install any plugin or software.
The Solution :
This little javascript code I wrote will have to be added to the report page and when called, it will read from the reportviewer the generated report html and the required css style, then will inject that into a new popup and launch printing.
// Print function (require the reportviewer client ID)
function printReport(report_ID) {
var rv1 = $('#' + report_ID);
var iDoc = rv1.parents('html');
// Reading the report styles
var styles = iDoc.find("head style[id$='ReportControl_styles']").html();
if ((styles == undefined) || (styles == '')) {
iDoc.find('head script').each(function () {
var cnt = $(this).html();
var p1 = cnt.indexOf('ReportStyles":"');
if (p1 > 0) {
p1 += 15;
var p2 = cnt.indexOf('"', p1);
styles = cnt.substr(p1, p2 - p1);
}
});
}
if (styles == '') { alert("Cannot generate styles, Displaying without styles.."); }
styles = '<style type="text/css">' + styles + "</style>";
// Reading the report html
var table = rv1.find("div[id$='_oReportDiv']");
if (table == undefined) {
alert("Report source not found.");
return;
}
// Generating a copy of the report in a new window
var docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">';
var docCnt = styles + table.parent().html();
var docHead = '<head><title>Printing ...</title><style>body{margin:5;padding:0;}</style></head>';
var winAttr = "location=yes, statusbar=no, directories=no, menubar=no, titlebar=no, toolbar=no, dependent=no, width=720, height=600, resizable=yes, screenX=200, screenY=200, personalbar=no, scrollbars=yes";;
var newWin = window.open("", "_blank", winAttr);
writeDoc = newWin.document;
writeDoc.open();
writeDoc.write(docType + '<html>' + docHead + '<body onload="window.print();">' + docCnt + '</body></html>');
writeDoc.close();
// The print event will fire as soon as the window loads
newWin.focus();
// uncomment to autoclose the preview window when printing is confirmed or canceled.
// newWin.close();
};
then simply bind the previous print function to a print button :
// Linking the print function to the print button
$('#printreport').click(function () {
printReport('rv1');
});
Now, this will only print the first page, because the following pages (if there is any) have not been generated by the reportviewer.
The workaround I came up with for that is to use the Rectangle element in your report designer, and place all the report content into the rectangle. Then check the property "Keep contents together on a single page, if possible". This will show all the data in one page in the reportviewer, and the cool thing is that the PDF, DOC, EXCEL exported files will still have their multipage preview and printing.
This solution has been tested on Visual Studio 2012 with Microsoft report viewer 2012 (v11), and should work with other versions as well.
You can download the sample website below to test this, and please feel free to comment if you have any question or improvement.
Chtiwi Malek on Google+About the author :
Malek Chtiwi is the man behind Codicode.com
34 years old full stack developer.
Loves technology; but also likes design, photography and composing music.