Category : .Net | Author : Chtiwi Malek | First posted : 10/8/2013 | Updated : 10/9/2013
Tags : sql, reporting, reportviewer, microsoft, reports, data, visual studio, print, solution, hack, trick
Cross-Browser Printing with Asp.Net ReportViewer

Cross-Browser Printing with Asp.Net ReportViewer

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.
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.
Comments & Opinions :
suggestion to work inside MasterPage
first of all i want thank you
for you samble its realy useful

and it work fine
but  doesn't work with MasterPage
and i am new in jquery

So can you help me to modified it

Best Regards
R.Ibrahim
- by remon ibrahim on 12/12/2013
hi, I have a problem too.. and i just want to ask for help, my report data doesn't show once i click the report button. it display the printing dialog with preview but the data is null. I'm getting my data in sql database. I downloaded the file to explore it more but i can't find where the problem is. Thanks in advance.
- by anne on 1/10/2014
some injected js code starts by checking if NREUMQ.f exists, but the NREUMQ it self does not exsist. As I have little clue what this is about, I dont have mutch hope to solve this or having anybody being able to help me here, but... anyway... (PS: Had to reply here, as the new comment form only ask you to please type your comment, what you actually has done that.
- by Rjan Flappi on 1/14/2014
THANK YOU
THANK YOU VERY MUCH ,IT'S REALY EASY,SIMPLE CODE AND IT WORK VERY GOOD CROSS BROWSERS
- by lath on 8/14/2014
I'm  using CrystalDecisions crystal report viewer. How i can print on any browser. this code is not working.
- by Mk on 11/26/2016
THANK YOU
THANK YOU VERY MUCH ,IT'S REALY EASY,SIMPLE CODE AND IT WORK VERY GOOD CROSS BROWSERS
- by lath on 8/14/2014
THANK YOU
THANK YOU VERY MUCH ,IT'S REALY EASY,SIMPLE CODE AND IT WORK VERY GOOD CROSS BROWSERS
- by lath on 8/14/2014
Some help
Good work ! But I have a little problem. All the colors of the report disappear when printing , i don't know why can you help me please?
- by Mc Evens on 9/14/2014
Good Work
Best Thanks for your great effort
- by taha on 9/16/2014
Problem
if i have multi page report that function will print first page only kindly send me the solution 
- by taha on 9/16/2014
issue + wsom work arround
for all those who are having issue of null dta... please correct your "Report viever" client id, which you pass to the function.... look the client id into the firebug...... + please provide a solution for making all the pages to be printed
- by syed ali on 10/3/2014
Help
Thanks for your great efforts .
if i have multi page report that function will print first page only kindly send me the solution .....
- by Doaa on 11/10/2014
Thank you for the solution + Issue
Thank you for the great solution.
Initial i was not getting the data on the report, i have change the below line of code.
var docCnt = styles + $($.find("div[id$='_oReportDiv']")).parent().html();

my problem is while printing i am not getting the borders in the report.
can you please help 
- by vinit on 11/24/2014
me too, not getting the borders
- by Ibere on 1/26/2015
Cross-Browser Printing with Asp.Net ReportViewer
if i have multi page report that function will print first page only ,if any solution exiest for direct printing multiple page without exporting to pdf or excel
- by sandeep on 12/23/2014
Null on PrintView
I am facing problem when I click on print it shows null always
- by Mohammad Bilal on 1/2/2015
multi page print
Thank you for the solution, it works great for single page report. But i am getting problem while multi page report. Can you please explain how to print multi-page report in one go.
- by Uday on 1/14/2015
A Big Thanks
It never occured to me that we can use the plain html to print.. thanks
- by Rajesh on 1/21/2015
It's Awesome.....
This code is too good.....
- by Amitabha DebBarman on 2/12/2015
help
if my page for print is content from master page 
I use your code.
show my " null " 
plz hlep me 
- by mk on 3/16/2015
Unable to print background image
This is simply awesome but I have one problem.
We have been trying to pring embedded background image without having to export it to PDF first.

When I click Print report, it displays the image nicely but when I print, it prints text on the image without the actual image.
 
Anyway to work around this?
- by Johnny on 5/7/2015
Unable to print background image
This is simply awesome but I have one problem.
We have been trying to pring embedded background image without having to export it to PDF first.

When I click Print report, it displays the image nicely but when I print, it prints text on the image without the actual image.
 
Anyway to work around this?
- by Johnny on 5/7/2015
Iframe instead of open window
Thanks a lot for you useful post.
I used iframe to prevent from opening a new windows. I think this way is user friendly.
 
var strFrameName = ("printer-" + (new Date()).getTime());
var jFrame = $("<iframe name='" + strFrameName + "'>");
jFrame
.css("width""1px")
.css("height""1px")
.css("left""-2000px")
.css("position""absolute")
.appendTo($("body:first"));
var objFrame = window.frames[strFrameName];
var objDoc = objFrame.document;
var jStyleDiv = $("<div>").append($("style").clone());
var styles = '<style type="text/css">' + jStyleDiv.html() + "</style>";
var docType = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
var docCnt = styles + $("#VisibleReportContentctl00_cphMain_rvReportMain_ctl09").html();
var docHead = '<head><title>...</title><style>body{margin:5;padding:0;}</style></head>';
objDoc.open();
objDoc.write(docType + '<html>' + docHead + '<body onload="window.print();">' + docCnt + '</body></html>');
objDoc.close();

and I used js code to adding print icon in report viewer control instead of a new print button:

function addPrintButton(ctl) {
    var innerTbody = '<tbody><tr><td><input type="image" style="border-width: 0px; padding: 2px; height: 16px; width: 16px;" alt="Print" src="/App/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.0.40219.1&Name=Microsoft.Reporting.WebForms.Icons.Print.gif" title="Print"></td></tr></tbody>';
    var innerTable = '<table title="Print" onclick="javascript:PrintFunc(\'' + ctl + '\'); return false;" id="do_print" style="cursor: default;">' + innerTbody + '</table>'
    var outerDiv = '<div style="display: inline-block; font-size: 8pt; height: 30px;" class=" "><table cellspacing="0" cellpadding="0" style="display: inline;"><tbody><tr><td height="28px">' + innerTable + '</td></tr></tbody></table></div>';
    $("#ctl00_cphMain_rvReportMain_ctl05 > div").append(outerDiv);
}
ctl: is the id of report viewer's id.

Thanks again.
- by Alex on 7/26/2015
Print
It's NOT work with multi pages also NO Styles printed and with me NOT work with firefox....
- by Hazem on 7/26/2015
New to this
your funcetion need to be inserted to 8.aspx page and I need to know what block I need to  insert my code is as follow:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReportForm.aspx.cs" Inherits="WebApplication3.ReportForm" %>

<%@ Register assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" namespace="Microsoft.Reporting.WebForms" tagprefix="rsweb" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:Button ID="Button1" runat="server" BackColor="Yellow" Height="55px" OnClick="Button1_Click" Text="Button" Width="102px" />
        <br />
        <rsweb:ReportViewer ID="rv1" runat="server" Font-Names="Verdana" Font-Size="8pt" ProcessingMode="Remote" WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt" Width="1145px">
            <ServerReport ReportPath="Customers" />
        </rsweb:ReportViewer>
    
    </div>
    </form>
</body>
</html>
- by Vijay Patel on 8/13/2015
Figure it out
No I am getting error  Code:
   public partial class ReportForm : System.Web.UI.Page and that is part of all trouble

I have  inserted click event code as follow but not matching  my function can you help:
   protected void Button1_Click(object sender, EventArgs e)
        {

            //$('#printReport').click(function ()) {
            //   printReport('rv1');
            //}};
        }
 
- by Vijay Patel on 8/13/2015
error at $ sign
I am getting  list of error   mentioned below  when rewrite clik evvent codes:

Error    1    Unexpected character '$'    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    50    13    Web Base SSRS2
Error    2    Too many characters in character literal    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    50    15    Web Base SSRS2
Error    3    Too many characters in character literal    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    51    18    Web Base SSRS2
Error    4    Invalid expression term ''    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    50    13    Web Base SSRS2
Error    5    ) expected    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    50    50    Web Base SSRS2
Error    6    Invalid expression term ')'    C:\Users\DevAdmin\Documents\Visual Studio 2013\Projects\ReportWeb Site1\Web Base SSRS2\Web Base SSRS2\ReportPage.aspx.cs    52    2    Web Base SSRS2


line 50            $('# printReport').click(function () {
line 51     printReport('rv1');
Line 52 });


Please help
- by Vijay Patel on 8/17/2015
Doubts to clarified
THANK YOU VERY MUCH ,IT'S REALY EASY,SIMPLE CODE AND IT WORK VERY GOOD CROSS BROWSERS.

How should i specify default no of copies in your javascript function?
 
- by AnandL on 12/9/2015
Not Wroking
It is not working with Masterpage.. How can we change our datasource??
- by Gopal Sharma on 12/14/2015
Barcode Nor showing
Thanks.. Good Code and works well, but barcode is not showing on report, please tell me about Bar code in this code..
- by Aqeel on 3/11/2016
During Print the System date on top left of page
hi Malek Chtiwi it is working fine but during Print the System date is displaying on top left of page which I want to hide therefore how I do it?
with regards
- by Faisal Niaz Khan on 3/14/2016
Working Well
i search For Solution Dayes ago and i find your solution it worked For me  
Many Thanks
- by Mostafa Fayez on 4/19/2016
Useable peace of code
Many thanks!
 
- by JudgeDredd on 6/24/2016
Superb solution
Many Thanks. It is working very fine with less efforts.
- by Tushar on 7/29/2016
Nice work
Many many thanks for this piece of code but unfortunately it doesn't print multiple pages...
Please provide a code that will print all pages without exporting into pdf or excel
thanks again
- by Saleem on 8/10/2016
Thanks for your great efforts.
It works great for single page report. But i've multi page report so can you please explain how to print multi-page report in one go (means print all pages of the report without exporting into pdf).
- by Munir Ahmad on 9/2/2016
Leave a Comment:
Name :
Email : * will not be shown
Title :
Comment :