Overview
By default, the ASP.NET ReportViewer control enables client-side printing when the user browser is Internet Explorer only. If the user opens to the report page through Firefox or Chrome, then ReportViewer will hide the Print button from the toolbar. This happens because the built-in client-side printing mechanism (a.k.a. RSPrintClient.cab) was designed and developed by using ActiveX which is not supported by other browsers but just by IE.

In this walkthrough, you'll learn how to add cross-browser printing to the ASP.NET ReportViewer control that works with any browser on Windows OS like IE (6 or later), Chrome, Firefox, Opera & Safari! After following this guide, you'll get the following custom print elements on the ReportViewer toolbar:

http://www.neodynamic.com/articles/H...int-Button.jpg
ASP.NET ReportViewer Custom Toolbar listing Installed Client Printers and Print button on Chrome

The code provided by this walkthrough allows you:

- To add a custom drop-down-list of the printers installed at the client machine!
- To print the RDLC report to the Default Printer or any installed printer without displaying any dialog!
- To provide the client-side printing feature to any browser on Windows OS like IE, Firefox, Chrome, Opera & Safari!

To test this Cross-Browser printing solution we provide you a sample Local Report RDLC featuring a products list for MS Northwind Traders database.

Want to print the RDLC report without Preview? Refer to our walkthrough How to Print an ASP.NET Local Report RDLC without Preview or Printer Dialog

Requirements

Development/Server-side

- WebClientPrint 2.0 for ASP.NET (or greater)
- ASP.NET 3.5 (or greater)
- Visual Studio 2010 / VWD 2010 (or greater)
- jQuery 1.4.1 (or greater)

Client-side
- WebClientPrint Processor 2.0 for Windows (WCPP) - Part of WebClientPrint Solution
- Adobe Reader

NOTE: In this guide we used VS 2010 and ASP.NET 3.5 but the same code & concept can be applied to VS 2005/2008 and ASP.NET 2.0 as well as VS 2012 and ASP.NET 4.x

Follow up these steps
- Download & install WebClientPrint for ASP.NET
- Open Visual Studio and create a new ASP.NET 3.5 Website naming it PrintRDLCReport
- Add a reference to Neodynamic.SDK.WebClientPrint.dll to your project
- Open your web.config file and add the following entries:

<system.web>
<httpHandlers>
<add verb="*" path="wcp.axd" type="Neodynamic.SDK.Web.WebClientPrint, Neodynamic.SDK.WebClientPrint"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add name="WCP" verb="*" path="wcp.axd" type="Neodynamic.SDK.Web.WebClientPrint, Neodynamic.SDK.WebClientPrint"/>
</handlers>
</system.webServer>

- Open the default.aspx page and paste the following markup. The task of this page is to try to detect the WCPP and inform the user to install it if it's missing.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>

<style>
body{font: 13px 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;}
</style>

<%-- WCPP-detection meta tag for IE10 --%>
<%= Neodynamic.SDK.Web.WebClientPrint.GetWcppDetectionMetaTag() %>
</head>
<body>
<form id="form1" runat="server">
<div id="msgInProgress">
<div id="mySpinner" style="width:32px;height:32px"></div>
<br />
Detecting WCPP utility at client side...
<br />
Please wait a few seconds...
<br />
</div>
<div id="msgInstallWCPP" style="display:none;">
<h3>#1 Install WebClientPrint Processor (WCPP)!</h3>
<p>
<strong>WCPP is a native Windows app (without any dependencies!)</strong> that handles all print jobs
generated by the <strong>WebClientPrint ASP.NET component</strong> at the server side. The WCPP
is in charge of the whole printing process and can be
installed on Windows 98, 2000, Me, XP, Vista, Windows 7 and Windows 8 (Desk-mode). It can print to Serial Port RS232 (e.g. COM1),
Parallel Port (e.g. LPT1), your Windows-Installed Printers (USB) and Network/IP Ethernet printers.
</p>
<p>
The <strong>WCPP</strong> utility <strong>is digitally-signed with a Windows Authenticode</strong> issued by <a href="http://www.digicert.com">DigiCert, Inc.</a>. <strong>Install WCPP only if the <u>Publisher is Neodynamic SRL</u></strong>, otherwise do not proceed. <br /><br />
<a href="http://www.neodynamic.com/downloads/wcpp20-installer.exe" target="_blank">Download and Install WCPP from Neodynamic website</a><br />
</p>
<h3>#2 After installing WCPP...</h3>
<p>
<a href="ReportViewerCrossBrowserClientPrint.aspx">You can go and test WebClientPrint for ASP.NET</a>
</p>

</div>
</form>

<%-- Add Reference to jQuery at Google CDN --%>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

<%-- Add Reference to spin.js (an animated spinner) --%>
<script src="http://fgnass.github.io/spin.js/dist/spin.min.js"></script>

<script type="text/javascript">

var wcppPingDelay_ms = 10000;
function wcppDetectOnSuccess(){
<%-- WCPP utility is installed at the client side
redirect to WebClientPrint sample page --%>

<%-- get WCPP version --%>
var wcppVer = arguments[0];
if(wcppVer == "2.0.0.0")
window.location.href = "ReportViewerCrossBrowserClientPrint.aspx";
else //force to install WCPP v2.0
wcppDetectOnFailure();
}

function wcppDetectOnFailure() {
<%-- It seems WCPP is not installed at the client side
ask the user to install it --%>
$('#msgInProgress').hide();
$('#msgInstallWCPP').show();
}

$(document).ready(function () {
<%-- Create the Spinner with options (http://fgnass.github.io/spin.js/) --%>
var spinner = new Spinner({
lines: 12,
length: 7,
width: 3,
radius: 10,
color: '#336699',
speed: 1,
trail: 60
}).spin($('#mySpinner')[0]);
});

</script>

<%-- WCPP detection script --%>
<%= Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript() %>

</body>
</html>

- The Local Report RDLC we've created for this sample is a simple product list for MS Northwind Traders database and it has an XML data source. The report looks like the following figure.

http://www.neodynamic.com/articles/H...nd-traders.jpg
Sample RDLC report featuring Northwind Traders product list

- Download and copy both MyReport.rdlc & NorthwindProducts.xml files to your website root folder
- Finally, add a new ASPX page and name it ReportViewerCrossBrowserClientPrint.aspx (be sure to UNSELECT the "Place code in separate file" checkbox)

In this page, we'll customize the ReportViewer toolbar by adding a list of installed client printers and our own Print button. The user will be able to print to the Defaul Printer or any other installed printer without displaying any print dialog!

At server-side, we convert the report to PDF format and then we pass it to the WCPP utility to print it to the desired client printer. The user is required to have Adobe Reader installed to get this code working.

Please paste the following markup and code depending on your preferred language i.e. C# or VB on your ReportViewerCrossBrowserClientPrint.aspx file.

VB
<%@ Page Language="VB" %>

<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="Neodynamic.SDK.Web" %>

<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

Protected Sub Page_Init(sender As Object, e As System.EventArgs)
'Print report???
If (WebClientPrint.ProcessPrintJob(Request)) Then

'create PDF version of RDLC report
Dim myReport As New LocalReport()
myReport.ReportPath = "MyReport.rdlc"
Dim ds As New DataSet()
ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"))
myReport.DataSources.Add(New ReportDataSource("Products", ds.Tables(0)))

'Export to PDF. Get binary content.
Dim pdfContent As Byte() = myReport.Render("PDF", Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)

'Now send this file to the client side for printing
'IMPORTANT: Adobe Reader needs to be installed at the client side

'Get printer name
Dim printerName As String = Server.UrlDecode(Request("printerName"));

'create a temp file name for our PDF report...

Dim fileName As String = Guid.NewGuid().ToString("N") + ".pdf"

'Create a PrintFile object with the pdf report
Dim file As New PrintFile(pdfContent, fileName)
'Create a ClientPrintJob and send it back to the client!
Dim cpj As New ClientPrintJob()
'set file to print...
cpj.PrintFile = file
'set client printer...
If (printerName = "Default Printer") Then
cpj.ClientPrinter = New DefaultPrinter()
Else
cpj.ClientPrinter = New InstalledPrinter(printerName)
End If
'send it...
cpj.SendToClient(Response)

End If
End Sub

Protected Sub Page_Load(sender As Object, e As System.EventArgs)
If (IsPostBack = False) Then
'load report in case user want to preview it
ReportViewer1.ProcessingMode = ProcessingMode.Local
ReportViewer1.LocalReport.ReportPath = "MyReport.rdlc"
Dim ds As New DataSet()
ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"))
ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("Products", ds.Tables(0)))
End If
End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Print Local Report RDLC without Previewing nor Print Dialog!</title>

<style>
body{font: 13px 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;background:#ddd;color:#333;margin:0;}
h1{background:#333;color:#fff;padding:10px;font: 29px 'Segoe UI Light', 'Tahoma Light', 'Arial Light', 'Helvetica Light', sans-serif;}
.myRow{width:auto;padding:0 20px 0 20px;height:auto;}
</style>

</head>
<body>
<%-- Store User's SessionId --%>
<input type="hidden" id="sid" name="sid" value="<%=Session.SessionID%>" />

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

<h1>ReportViewer with Cross-Browser Client Print</h1>
<div class="myRow" style="clear:both" id="pnlReport">
<br /><br />
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Height="450px" Width="960px">
</rsweb:ReportViewer>
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</form>

<%-- Add Reference to jQuery at Google CDN --%>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<%-- Register the WebClientPrint script code --%>
<%=Neodynamic.SDK.Web.WebClientPrint.CreateScript()%>

<script type="text/javascript">
$(document).ready(function () {

<%-- hide built-in print button from ReportViewer toolbar --%>
$('table[title="Print"]').hide();

<%-- embed custom DropDownList for listing installed client printers and print image button --%>
$('#<%=ReportViewer1.ClientID%>_ctl05:last-child').children().append('<div class=" " style="display:inline-block;font-family:Verdana;font-size:8pt;vertical-align:top;"><table cellpadding="0" cellspacing="0" style="display:inline;"><tbody><tr><td height="28px"><select name="ddlClientPrinters" id="ddlClientPrinters" style="font-family:Verdana;font-size:8pt;" title="Select Printer"><option>Loading printers...</option></select></td><td width="4px"></td><td height="28px"><div><div id="<%=ReportViewer1.ClientID%>_Custom_Print_Button" style="border: 1px solid transparent; background-color: transparent; cursor: default;"><table title="Print"><tbody><tr><td><input type="image" title="Print" src="Reserved.ReportViewerWebControl.axd?OpType=Resource&Name=Microsoft.Reporting.WebForms.Icons.Print.gif" alt="Refresh" style="border-style:None;height:16px;width:16px;border-width:0px;"></td></tr></tbody></table></div></div></td></tr></tbody></table></div>');

<%-- mouse hover effect for our new print image button --%>
$('#<%=ReportViewer1.ClientID%>_Custom_Print_Button').hover(function() { //hover style
$(this).css({'border': '1px solid #336699', 'background-color': '#DDEEF7', 'cursor': 'pointer'});
}, function() { //normal style
$(this).css({'border': '1px solid transparent', 'background-color': 'transparent', 'cursor': 'default'})
});

<%-- load client printers through WebClientPrint --%>
jsWebClientPrint.getPrinters();

<%-- add click handler for print button --%>
$('#<%=ReportViewer1.ClientID%>_Custom_Print_Button').click(function() {
jsWebClientPrint.print('printerName=' + $('#ddlClientPrinters').val());
});
});

<%-- Time delay we'll wait for getting client printer names --%>
var wcppGetPrintersDelay_ms = 5000; //5 sec

function wcpGetPrintersOnSuccess(){
<%-- Display client installed printers --%>
if(arguments[0].length > 0){
var p=arguments[0].split("|");
var options = '<option>Default Printer</option>';
for (var i = 0; i < p.length; i++) {
options += '<option>' + p[i] + '</option>';
}
$('#ddlClientPrinters').html(options);
}else{
alert("No printers are installed in your system.");
}
}

function wcpGetPrintersOnFailure() {
<%-- Do something if printers cannot be got from the client --%>
alert("No printers are installed in your system.");
}

</script>
</body>
</html>

- That's it! Run your website and test it. WebClientPrint will load the installed printers at the client machine and will list it in the ReportViewer toolbar. User can select any of the installed printers and by clicking on Print icon button (that now will be available in IE, Firefox, Chrome, Opera or Safari) the printing process will be performed.


Links:
This Demos
Demos
Download WebClientPrint for ASP.NET
More Information about Neodynamic WebClientPrint for ASP.NET

Neodynamic
NET Components & Controls
http://www.neodynamic.com