SSRS print button in Chrome and Firefox

2020-02-06 09:37发布

问题:

I have reports in SSRS 2005. I am using remote reports. In IE, the print button shows, but in Firefox and Chrome, the print button does not show.

My reports are shown in jquery UI dialogs, so I cannot just do a window.print. My reports render just fine within the modals.

I need to be able to issue a print command to the reportviewer the same way it is done from within the control, but only in firefox and chrome.

I dug into the markup for the report viewer, and found this code. I tried to manually inject it into the reportviewer with no success.

<table id="reportViewer_ctl01_ctl07_ctl00_ctl00" onclick="document.getElementById(&#39;reportViewer&#39;).ClientController.LoadPrintControl();return false;" onmouseover="this.Controller.OnHover();" onmouseout="this.Controller.OnNormal();" title="Print" style="display:none;">
                                <script type="text/javascript">
                                    document.getElementById('reportViewer_ctl01_ctl07_ctl00_ctl00').Controller = new ReportViewerHoverButton("reportViewer_ctl01_ctl07_ctl00_ctl00", false, "", "", "", "#ECE9D8", "#DDEEF7", "#99BBE2", "1px #ECE9D8 Solid", "1px #336699 Solid", "1px #336699 Solid");
                                </script><tr>
                                    <td><input type="image" name="reportViewer$ctl01$ctl07$ctl00$ctl00$ctl00" title="Print" src="/Reserved.ReportViewerWebControl.axd?OpType=Resource&amp;Version=9.0.30729.4402&amp;Name=Microsoft.Reporting.WebForms.Icons.Print.gif" alt="Print" style="height:16px;width:16px;padding:2px;" /></td>
                                </tr>
                            </table>

Any ideas?

回答1:

Unfortunately the print button is not supported in browsers other than IE.

I think you realise this and did a workaround, we have yet to come up with a decent solution as well. Although most of our users prefer printing from Excel directly, so we allow them to export the file which they then do the printing.

This SO question would be a good link:

SQL Reporting Services - Print Button not shown in Mozilla



回答2:

Here's what I did to create a pseudo print button which emulates the print function of Report Viewer in Internet Explorer to other browsers.

Please take note that the solution below requires JQuery. No ActiveX installation is necessary.

Here are the steps.

Step 1. Add the print button in your page where the report viewer is situated.

<input id="PrintButton" title="Print" style="width: 16px; height: 16px;" type="image" alt="Print" runat="server" src="~/Reserved.ReportViewerWebControl.axd?OpType=Resource&amp;Version=11.0.3442.2&amp;Name=Microsoft.Reporting.WebForms.Icons.Print.gif" />

Be sure to change the Version number to your RS version. If you're having trouble with the html code, you can open the page with internet explorer and inspect the print element and copy it.

Step 2. Add a div where your PDF will be rendered.

<div class="pdf">
    </div>

Step 3. Add the script.

$(document).ready(function () {
// Check if the current browser is IE (MSIE is not used since IE 11)
        var isIE = /MSIE/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent);

function printReport() {

            var reportViewerName = 'ReportViewer'; //Name attribute of report viewer control.
            var src_url = $find(reportViewerName)._getInternalViewer().ExportUrlBase + 'PDF';

            var contentDisposition = 'AlwaysInline'; //Content Disposition instructs the server to either return the PDF being requested as an attachment or a viewable report.
            var src_new = src_url.replace(/(ContentDisposition=).*?(&)/, '$1' + contentDisposition + '$2');

            var iframe = $('<iframe>', {
                src: src_new,
                id: 'pdfDocument',
                frameborder: 0,
                scrolling: 'no'
            }).hide().load(function () {
                var PDF = document.getElementById('pdfDocument');
                PDF.focus();
                try {
                    PDF.contentWindow.print();
                }
                catch (ex) {
                    //If all else fails, we want to inform the user that it is impossible to directly print the document with the current browser.
                    //Instead, let's give them the option to export the pdf so that they can print it themselves with a 3rd party PDF reader application.

                    if (confirm("ActiveX and PDF Native Print support is not supported in your browser. The system is unable to print your document directly. Would you like to download the PDF version instead? You may print the document by opening the PDF using your PDF reader application.")) {
                        window.open($find(reportViewerName)._getInternalViewer().ExportUrlBase + 'PDF');
                    }
                }

            })

            //Bind the iframe we created to an invisible div.
            $('.pdf').html(iframe);


        }

// 2. Add Print button for non-IE browsers
        if (!isIE) {

            $('#PrintButton').click(function (e) {
                e.preventDefault();
                printReport();
            })
        }

});

Code explanation :

First we created a variable which detects if the browser is IE or not.

By using the _getInternalViewer() method in Reserved.ReportViewerWebControl.axd we can request a PDF version of the report as a request which is originally retrieved upon clicking the export button.

We then assigned a contentDisposition variable as 'AlwaysInline' because we want to request the report as a PDF, not as an attachment but as a PDF that we can render in an html element. https://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.reportviewer.exportcontentdisposition.aspx

The src_new variable replaces the default EXPORT button content disposition request (which is set to AlwaysAttachment by default) with our new request 'AlwaysInline'.

Next, we then set the src of the iframe to our new url which when loaded, will reveal our report from reportviewer as PDF.

The chained commands in the iframe includes hiding the pdf element, rendering it and printing it right away after it finishes loading the pdf.

Ending remarks

I hope that someone will find this code useful because I had a hard time finding a decent solution online and this is what I came up with after doing some research.



回答3:

Please find the code for SSRS report that has Print Icon with Printing functionality for Firefox and Chrome:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Report.aspx.cs" Inherits="DemoMVC.Report.Report" %>


<%@ 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>

    <script src="../Scripts/jquery-1.7.1.js"></script>

    <script type="text/javascript" lang="javascript">

        $(document).ready(function () {

            if ($.browser.mozilla || $.browser.webkit) {

                try {

                    showPrintButton();

                }

                catch (e) { alert(e); }

            }

        });



        function showPrintButton() {

            var table = $("table[title='Refresh']");

            var parentTable = $(table).parents('table');

            var parentDiv = $(parentTable).parents('div').parents('div').first();

            parentDiv.append('<input type="image" style="border-width: 0px; padding: 3px;margin-top:2px; height:16px; width: 16px;" alt="Print" src="/Reserved.ReportViewerWebControl.axd?OpType=Resource&amp;Version=9.0.30729.1&amp;Name=Microsoft.Reporting.WebForms.Icons.Print.gif";title="Print" onclick="PrintReport();">');



        }

         // Print Report function

        function PrintReport() {



            //get the ReportViewer Id

            var rv1 = $('#MyReportViewer_ctl09');

            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><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();

            newWin.focus();

            // uncomment to autoclose the preview window when printing is confirmed or canceled.

            // newWin.close();

        };

    </script>









</head>

<body>

     <form id="form1" runat="server">

    <div>

    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" EnablePartialRendering="False" />

        <rsweb:ReportViewer ID="MyReportViewer" runat="server">

        </rsweb:ReportViewer>

    </div>

    </form>

</body>

</html>


回答4:

I made some changes with regards to the above and it works well for me in both Chrome and Firefox.

function PrintReport() {        
    var reportViewerName = 'ReportViewer1';
    var src_url = $find(reportViewerName)._getInternalViewer().ExportUrlBase + 'PDF';

    var contentDisposition = 'AlwaysInline';
    var src_new = src_url.replace(/(ContentDisposition=).*?(&)/, '$1' + contentDisposition + '$2');

    var iframe = $('<iframe>', {
        src: src_new,
        id: 'iframePDF',
        frameborder: 0,
        scrolling: 'no'
    });

    $('#pdfPrint').html(iframe);    //There should be a div named "pdfPrint"

    if (iframe != undefined && iframe.length > 0) {
        var frame = iframe[0];

        if (frame != null || frame != undefined) {
            var contentView = iframe[0].contentWindow;

            contentView.focus();
            contentView.print();
        }
    }
}