How to Print an ASP.NET Local Report RDLC without Preview or Printer Dialog
Product WebClientPrint for ASP.NET Published 03/31/2013 Updated 12/26/2017 Author Neodynamic
Overview
In this walkthrough, you'll learn how to print a Local Report (RDLC) from an ASP.NET website to the client printer without previewing the report through Visual Studio ReportViewer control. In fact, you'll be able to print the RDLC report without displaying any Printer Dialog at all! And one important thing... it works with any browser on Windows OS like IE, Edge, Chrome, Firefox, Opera & Safari as well as on Linux & Mac OS clients!
The sample report is a Local Report RDLC designed to print a product list of the classic and famous MS Northwind Traders database. In a simple ASP.NET webpage, we provide a preview of such report (just for you to know what to expect after printing) and all the needed code in C# and VB to print the report without previewing or displaying any printer dialog by using WebClientPrint for ASP.NET solution
You can print the RDLC local report to the Default client printer as well as to any other installed printer at the client machine.
Print RDLC Local Report without Preview or Print Dialog
Requirements
Development/Server-side
WebClientPrint 6.0 for ASP.NET (or greater)
ASP.NET 4.6.1+ or ASP.NET Core 2.0+
Visual Studio 2015+
jQuery 1.4.1+
Client-side
WebClientPrint Processor 6.0 for Windows, Linux, Raspberry Pi & Mac
Follow up these steps
- Open Visual Studio and create a new ASP.NET Website naming it PrintRDLCReport
- Add a NuGet reference to Neodynamic.SDK.WebClientPrint package to your project
- Now follow up the instructions for each WebForms/CS or WebForms/VB:
Adding sample RDLC local report
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.
Sample RDLC report featuring Northwind Traders product list
Creating HTTP Handlers
Create a new Generic Handler and name it WebClientPrintAPI and then copy/paste the following code:
public class WebClientPrintAPI : IHttpHandler { //********************************* // IMPORTANT NOTE // In this sample we store users related stuff (like // the list of printers and whether they have the WCPP // client utility installed) in the Application cache // object part of ASP.NET BUT you can change it to // another different storage (like a DB or file server)! // which will be required in Load Balacing scenarios //********************************* public void ProcessRequest (HttpContext context) { //get session ID string sessionID = (context.Request["sid"] != null) ? context.Request["sid"].ToString() : null; //get Query String string queryString = context.Request.Url.Query; try { //Determine and get the Type of Request RequestType prType = WebClientPrint.GetProcessRequestType(queryString); if (prType == RequestType.GenPrintScript || prType == RequestType.GenWcppDetectScript) { //Let WebClientPrint to generate the requested script byte[] script = WebClientPrint.GenerateScript(context.Request.Url.AbsoluteUri.Replace(queryString, ""), queryString); context.Response.ContentType = "text/javascript"; context.Response.BinaryWrite(script); } else if (prType == RequestType.ClientSetWcppVersion) { //This request is a ping from the WCPP utility //so store the session ID indicating this user has the WCPP installed //also store the WCPP Version if available string wcppVersion = context.Request["wcppVer"]; if (string.IsNullOrEmpty(wcppVersion)) wcppVersion = "1.0.0.0"; context.Application.Set(sessionID + "wcppInstalled", wcppVersion); } else if (prType == RequestType.ClientSetInstalledPrinters) { //WCPP Utility is sending the installed printers at client side //so store this info with the specified session ID string printers = context.Request["printers"]; if (string.IsNullOrEmpty(printers) == false) printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)); context.Application.Set(sessionID + "printers", printers); } else if (prType == RequestType.ClientSetInstalledPrintersInfo) { //WCPP Utility is sending the client installed printers with detailed info //so store this info with the specified session ID //Printers Info is in JSON format string printersInfo = context.Request.Form["printersInfoContent"]; if (string.IsNullOrEmpty(printersInfo) == false) printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)); context.Application.Set(sessionID + "printersInfo", printersInfo); } else if (prType == RequestType.ClientGetWcppVersion) { //return the WCPP version for the specified Session ID (sid) if any bool sidWcppVersion = (context.Application[sessionID + "wcppInstalled"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidWcppVersion ? context.Application[sessionID + "wcppInstalled"] : ""); } else if (prType == RequestType.ClientGetInstalledPrinters) { //return the installed printers for the specified Session ID (sid) if any bool sidHasPrinters = (context.Application[sessionID + "printers"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidHasPrinters ? context.Application[sessionID + "printers"] : ""); } else if (prType == RequestType.ClientGetInstalledPrintersInfo) { //return the installed printers with detailed info for the specified Session ID (sid) if any bool sidHasPrinters = (context.Application[sessionID + "printersInfo"] != null); context.Response.ContentType = "text/plain"; context.Response.Write(sidHasPrinters ? context.Application[sessionID + "printersInfo"] : ""); } } catch (Exception ex) { context.Response.StatusCode = 500; context.Response.ContentType = "text/plain"; context.Response.Write(ex.Message + " - " + ex.StackTrace); } } public bool IsReusable { get { return false; } } }
Create a new Generic Handler and name it PrintReportHandler and then copy/paste the following code:
<%@ WebHandler Language="C#" Class="PrintReportHandler" %> using System.Collections.Generic; using System.IO; using System.Text; using System.Web; using System.Data; using Microsoft.Reporting.WebForms; using Neodynamic.SDK.Web; public class PrintReportHandler : IHttpHandler { /*############### IMPORTANT!!! ############ If your website requires AUTHENTICATION, then you MUST configure THIS Handler file to be ANONYMOUS access allowed!!! ######################################### */ public void ProcessRequest (HttpContext context) { if (WebClientPrint.ProcessPrintJob(context.Request.Url.Query)) { //Get User selected printer options bool useDefaultPrinter = (context.Request["useDefaultPrinter"] == "checked"); string printerName = context.Server.UrlDecode(context.Request["printerName"]); //load RDLC report using (LocalReport myReport = new LocalReport()) { myReport.ReportPath = "MyReport.rdlc"; DataSet ds = new DataSet(); ds.ReadXml(context.Server.MapPath("~/NorthwindProducts.xml")); myReport.DataSources.Add(new ReportDataSource("Products", ds.Tables[0])); //Export to PNG images per report page string deviceInfo = "<DeviceInfo>" + "<OutputFormat>PNG</OutputFormat>" + "<PageWidth>8.5in</PageWidth>" + "<PageHeight>11in</PageHeight>" + "<MarginTop>0.25in</MarginTop>" + "<MarginLeft>0.25in</MarginLeft>" + "<MarginRight>0.25in</MarginRight>" + "<MarginBottom>0.25in</MarginBottom>" + "</DeviceInfo>"; Warning[] ws; reportPagesBuffer = new List<MemoryStream>(); myReport.Render("Image", deviceInfo, CreateStream, out ws); //Create ClientPrintJob ClientPrintJob cpj = new ClientPrintJob(); if (useDefaultPrinter || printerName == "null") cpj.ClientPrinter = new DefaultPrinter(); else cpj.ClientPrinter = new InstalledPrinter(printerName); for (int i = 0; i < reportPagesBuffer.Count; i++) { reportPagesBuffer[i].Position = 0; cpj.PrintFileGroup.Add(new PrintFile(reportPagesBuffer[i].ToArray(), "ReportPage" + i.ToString().PadLeft(3, '0') + ".png")); } context.Response.ContentType = "application/octet-stream"; context.Response.BinaryWrite(cpj.GetContent()); context.Response.End(); } } } private List<MemoryStream> reportPagesBuffer; //Report Pages Buffer private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { MemoryStream stream = new MemoryStream(); reportPagesBuffer.Add(stream); return stream; } public bool IsReusable { get { return false; } } }
Creating/Editing WebForm Pages
Be sure ALL *.aspx link to jQuery 1.4.1+ file!
The default page is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Default.aspx file and copy/paste the following code inside the BODY:
<div id="msgInProgress"> <div id="mySpinner" style="width:32px;height:32px"></div> <br /> <h3>Detecting WCPP utility at client side...</h3> <h3>Please wait a few seconds...</h3> <br /> </div> <div id="msgInstallWCPP" style="display:none;"> <h3>#1 Install WebClientPrint Processor (WCPP)!</h3> <p> <strong>WCPP is a native app (without any dependencies!)</strong> that handles all print jobs generated by the <strong>WebClientPrint for ASP.NET component</strong> at the server side. The WCPP is in charge of the whole printing process and can be installed on <strong>Windows, Linux, Mac & Raspberry Pi!</strong> </p> <p> <a href="//www.neodynamic.com/downloads/wcpp/" target="_blank" >Download and Install WCPP from Neodynamic website</a><br /> </p> <h3>#2 After installing WCPP...</h3> <p> <a href="PrintReport.aspx" >You can go and test the printing page...</a> </p> </div> <script type="text/javascript"> var wcppPingTimeout_ms = 60000; //60 sec var wcppPingTimeoutStep_ms = 500; //0.5 sec function wcppDetectOnSuccess(){ // WCPP utility is installed at the client side // redirect to WebClientPrint sample page // get WCPP version var wcppVer = arguments[0]; if(wcppVer.substring(0, 1) == "6") window.location.href = 'PrintReport.aspx'; else //force to install WCPP v6.0 wcppDetectOnFailure(); } function wcppDetectOnFailure() { // It seems WCPP is not installed at the client side // ask the user to install it $('#msgInProgress').hide(); $('#msgInstallWCPP').show(); } </script> <%-- WCPP detection script code --%> <%=Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Session.SessionID)%>
Add a new page and name it PrintReport.aspx. Copy/paste the following code inside the BODY:
<form id="form1" runat="server"> <label class="checkbox"> <input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or... </label> <br /><br /> <div id="loadPrinters"> Click to load and select one of the installed printers! <br /> <input type="button" onclick="javascript: jsWebClientPrint.getPrinters();" value="Load installed printers..." /> <br /> <br /> </div> <div id="installedPrinters" style="visibility: hidden"> <label for="installedPrinterName">Select an installed Printer:</label> <select name="installedPrinterName" id="installedPrinterName"></select> </div> <script type="text/javascript"> //var wcppGetPrintersDelay_ms = 0; var wcppGetPrintersTimeout_ms = 60000; //60 sec var wcppGetPrintersTimeoutStep_ms = 500; //0.5 sec function wcpGetPrintersOnSuccess() { // Display client installed printers if (arguments[0].length > 0) { var p = arguments[0].split("|"); var options = ''; for (var i = 0; i < p.length; i++) { options += '<option>' + p[i] + '</option>'; } $('#installedPrinters').css('visibility', 'visible'); $('#installedPrinterName').html(options); $('#installedPrinterName').focus(); $('#loadPrinters').hide(); } 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> <br /> <input type="button" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val())" value="Print RDLC Report..." /> </form> <%-- Add Reference to jQuery at Google CDN --%> <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"></script> <%-- Register the WebClientPrint script code --%> <%=Neodynamic.SDK.Web.WebClientPrint.CreateScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/PrintReportHandler.ashx", HttpContext.Current.Session.SessionID)%>
Adding sample RDLC local report
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.
Sample RDLC report featuring Northwind Traders product list
Creating HTTP Handlers
Create a new Generic Handler and name it WebClientPrintAPI and then copy/paste the following code:
<%@ WebHandler Language="VB" Class="WebClientPrintAPI" %> Imports System Imports System.Web Imports Neodynamic.SDK.Web Public Class WebClientPrintAPI : Implements IHttpHandler '********************************* ' IMPORTANT NOTE ' In this sample we store users related stuff (like ' the list of printers and whether they have the WCPP ' client utility installed) in the Application cache ' object part of ASP.NET BUT you can change it to ' another different storage (like a DB or file server)! ' which will be required in Load Balacing scenarios '********************************* Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest 'get session ID Dim sessionID As String = "" If (context.Request("sid") IsNot Nothing) Then sessionID = context.Request("sid") End If 'get Query String Dim queryString As String = context.Request.Url.Query Try 'Determine and get the Type of Request Dim prType As RequestType = WebClientPrint.GetProcessRequestType(queryString) If prType = RequestType.GenPrintScript OrElse prType = RequestType.GenWcppDetectScript Then 'Let WebClientPrint to generate the requested script Dim script As Byte() = WebClientPrint.GenerateScript(context.Request.Url.AbsoluteUri.Replace(queryString, ""), queryString) context.Response.ContentType = "text/javascript" context.Response.BinaryWrite(script) ElseIf prType = RequestType.ClientSetWcppVersion Then 'This request is a ping from the WCPP utility 'so store the session ID indicating this user has the WCPP installed 'also store the WCPP Version if available Dim wcppVersion As String = context.Request("wcppVer") If String.IsNullOrEmpty(wcppVersion) Then wcppVersion = "1.0.0.0" End If context.Application.Set(sessionID & "wcppInstalled", wcppVersion) ElseIf prType = RequestType.ClientSetInstalledPrinters Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID Dim printers As String = context.Request("printers") If Not String.IsNullOrEmpty(printers) Then printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers)) End If context.Application.Set(sessionID & "printers", printers) ElseIf prType = RequestType.ClientSetInstalledPrintersInfo Then 'WCPP Utility is sending the installed printers at client side 'so store this info with the specified session ID 'Printers Info is in JSON format Dim printersInfo As String = context.Request.Form("printersInfoContent") If Not String.IsNullOrEmpty(printersInfo) Then printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo)) End If context.Application.Set(sessionID & "printersInfo", printersInfo) ElseIf prType = RequestType.ClientGetWcppVersion Then 'return the WCPP version for the specified Session ID (sid) if any Dim sidWcppVersion As Boolean = (context.Application(sessionID & "wcppInstalled") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidWcppVersion) Then context.Response.Write(context.Application(sessionID & "wcppInstalled").ToString()) End If ElseIf prType = RequestType.ClientGetInstalledPrinters Then 'return the installed printers for the specified Session ID (sid) if any Dim sidHasPrinters As Boolean = (context.Application(sessionID & "printers") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidHasPrinters) Then context.Response.Write(context.Application(sessionID & "printers").ToString()) End If ElseIf prType = RequestType.ClientGetInstalledPrintersInfo Then 'return the installed printers with detailed info for the specified Session ID (sid) if any Dim sidHasPrinters As Boolean = (context.Application(sessionID & "printersInfo") IsNot Nothing) context.Response.ContentType = "text/plain" If (sidHasPrinters) Then context.Response.Write(context.Application(sessionID & "printersInfo").ToString()) End If End If Catch ex As Exception context.Response.StatusCode = 500 context.Response.ContentType = "text/plain" context.Response.Write(ex.Message + " - " + ex.StackTrace) End Try End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class
Create a new Generic Handler and name it PrintReportHandler and then copy/paste the following code:
<%@ WebHandler Language="VB" Class="PrintReportHandler" %> Imports System.Collections.Generic Imports System.IO Imports System.Text Imports System.Web Imports System.Data Imports Microsoft.Reporting.WebForms Imports Neodynamic.SDK.Web Public Class PrintReportHandler : Implements IHttpHandler '############### IMPORTANT!!! ############ ' If your website requires AUTHENTICATION, then you MUST configure THIS Handler file ' to be ANONYMOUS access allowed!!! '######################################### Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest If WebClientPrint.ProcessPrintJob(context.Request.Url.Query) Then 'Get User selected printer options Dim useDefaultPrinter As Boolean = (Request("useDefaultPrinter") = "checked") Dim printerName As String = Server.UrlDecode(Request("printerName")) 'load RDLC report Using myReport As New LocalReport myReport.ReportPath = "MyReport.rdlc" Dim ds As New DataSet() ds.ReadXml(context.Server.MapPath("~/NorthwindProducts.xml")) myReport.DataSources.Add(new ReportDataSource("Products", ds.Tables(0))) 'Export to PNG images per report page Dim deviceInfo As String = "<DeviceInfo>" & _ "<OutputFormat>PNG</OutputFormat>" & _ "<PageWidth>8.5in</PageWidth>" & _ "<PageHeight>11in</PageHeight>" & _ "<MarginTop>0.25in</MarginTop>" & _ "<MarginLeft>0.25in</MarginLeft>" & _ "<MarginRight>0.25in</MarginRight>" & _ "<MarginBottom>0.25in</MarginBottom>" & _ "</DeviceInfo>" reportPagesBuffer = New List(Of MemoryStream); Dim warnings() As Warning = Nothing myreport.Render("Image", deviceInfo, AddressOf CreateStream, warnings) 'Create ClientPrintJob Dim cpj As New ClientPrintJob() 'set client printer... If (useDefaultPrinter OrElse printerName = "null") Then cpj.ClientPrinter = New DefaultPrinter() Else cpj.ClientPrinter = New InstalledPrinter(printerName) End If For i As Interger = 0 To reportPagesBuffer.Count - 1 reportPagesBuffer(i).Position = 0 cpj.PrintFileGroup.Add(New PrintFile(reportPagesBuffer(i).ToArray(), "ReportPage" + i.ToString().PadLeft(3, "0"c) + ".png")) Next context.Response.ContentType = "application/octet-stream" context.Response.BinaryWrite(cpj.GetContent()) context.Response.End() End Using End If End Sub Dim reportPagesBuffer As New List(Of MemoryStream) 'Report Pages Buffer Private Function CreateStream(ByVal name As String, _ ByVal fileNameExtension As String, _ ByVal encoding As Encoding, _ ByVal mimeType As String, _ ByVal willSeek As Boolean) As Stream Dim stream As new MemoryStream() reportPagesBuffer.Add(stream) Return stream End Function Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class
Creating/Editing WebForm Pages
Be sure ALL *.aspx link to jQuery 1.4.1+ file!
The default page is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Default.aspx file and copy/paste the following code inside the BODY:
<div id="msgInProgress"> <div id="mySpinner" style="width:32px;height:32px"></div> <br /> <h3>Detecting WCPP utility at client side...</h3> <h3>Please wait a few seconds...</h3> <br /> </div> <div id="msgInstallWCPP" style="display:none;"> <h3>#1 Install WebClientPrint Processor (WCPP)!</h3> <p> <strong>WCPP is a native app (without any dependencies!)</strong> that handles all print jobs generated by the <strong>WebClientPrint for ASP.NET component</strong> at the server side. The WCPP is in charge of the whole printing process and can be installed on <strong>Windows, Linux, Mac & Raspberry Pi!</strong> </p> <p> <a href="//www.neodynamic.com/downloads/wcpp/" target="_blank" >Download and Install WCPP from Neodynamic website</a><br /> </p> <h3>#2 After installing WCPP...</h3> <p> <a href="PrintReport.aspx" >You can go and test the printing page...</a> </p> </div> <script type="text/javascript"> var wcppPingTimeout_ms = 60000; //60 sec var wcppPingTimeoutStep_ms = 500; //0.5 sec function wcppDetectOnSuccess(){ // WCPP utility is installed at the client side // redirect to WebClientPrint sample page // get WCPP version var wcppVer = arguments[0]; if(wcppVer.substring(0, 1) == "6") window.location.href = 'PrintReport.aspx'; else //force to install WCPP v6.0 wcppDetectOnFailure(); } function wcppDetectOnFailure() { // It seems WCPP is not installed at the client side // ask the user to install it $('#msgInProgress').hide(); $('#msgInstallWCPP').show(); } </script> <%-- WCPP detection script code --%> <%=Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Session.SessionID)%>
Add a new page and name it PrintReport.aspx. Copy/paste the following code inside the BODY:
<form id="form1" runat="server"> <label class="checkbox"> <input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or... </label> <br /><br /> <div id="loadPrinters"> Click to load and select one of the installed printers! <br /> <input type="button" onclick="javascript: jsWebClientPrint.getPrinters();" value="Load installed printers..." /> <br /> <br /> </div> <div id="installedPrinters" style="visibility: hidden"> <label for="installedPrinterName">Select an installed Printer:</label> <select name="installedPrinterName" id="installedPrinterName"></select> </div> <script type="text/javascript"> var wcppGetPrintersTimeout_ms = 60000; //60 sec var wcppGetPrintersTimeoutStep_ms = 500; //0.5 sec function wcpGetPrintersOnSuccess() { // Display client installed printers if (arguments[0].length > 0) { var p = arguments[0].split("|"); var options = ''; for (var i = 0; i < p.length; i++) { options += '<option>' + p[i] + '</option>'; } $('#installedPrinters').css('visibility', 'visible'); $('#installedPrinterName').html(options); $('#installedPrinterName').focus(); $('#loadPrinters').hide(); } 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> <br /> <input type="button" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val())" value="Print RDLC Report..." /> </form> <%-- Add Reference to jQuery at Google CDN --%> <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"></script> <%-- Register the WebClientPrint script code --%> <%=Neodynamic.SDK.Web.WebClientPrint.CreateScript(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/WebClientPrintAPI.ashx", HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + ":" + HttpContext.Current.Request.Url.Port + "/PrintReportHandler.ashx", HttpContext.Current.Session.SessionID)%>
- That's it! Run your website and test it. Click on "Print RDL Report" to print the RDLC report without preview. You can print it to the Default client printer or you can get a list of the installed printers available at the client machine.
Useful? Share it!
Tweet |
|
Related Articles
How to add Cross-Browser Printing to ASP.NET ReportViewer toolbarHow to use Codeless Barcode Generation feature in ReportViewer RDLC local reports in ASP.NET
How to Directly Print a Crystal Reports to Default Client Printer from ASP.NET without Preview or Printer Dialog
Need help? Contact Support
We provide best-in-class customer service and support directly from members of our dev team! If we are available when you contact us, you will get a response in few minutes; otherwise the maximum turnaround is 24hs in most cases.