• Products
    •  Barcode Professional
      Encoder / Writer / Generator

      •  Compare Barcode Professional Products...
      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • SDK for .NET Windows
      • for Windows Forms
      • for WPF
      • for Blazor
      • for ASP.NET (Web Forms & MVC)
      • for Reporting Services (SSRS)

       ThermalLabel
      Design & Print Barcode Thermal Labels

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • Visual Editor for Windows Add-on
      • Web Editor for ASP.NET Add-on

      Web Printing Solutions

      •  Compare JSPrintManager vs WebClientPrint...

      JS Print Manager
      Printing Solution for Any Web Platform

      • for Any Web Platform
      • for Blazor

       WebClientPrint
      RAW & File Printing for ASP.NET & PHP

      • for ASP.NET (Core, MVC & WebForms)
      • for PHP

       Printer Emulator SDKs

      ZPL Printer Emulator SDK
      Convert, Preview & Render ZPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

      EPL Printer Emulator SDK
      Convert, Preview & Render EPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

       Virtual Printer Drivers

      Virtual ZPL Printer Driver
      Convert, Print, Preview & Render ZPL

      • Virtual ZPLPrinter Driver for Windows & macOS

      Virtual EPL Printer Driver
      Convert, Print, Preview & Render EPL

      • Virtual EPLPrinter Driver for Windows & macOS

       On-Premise Web APIs for Docker

      • BarcodePro Web API for Docker
        2D & Linear Barcode Encoder / Writer / Generator
      • ThermalLabel Web API for Docker
        Design, Preview, Export & Print Barcode Thermal Labels
      • ZPLPrinter Web API for Docker
        Convert, Preview & Render ZPL to Image & PDF
      • EPLPrinter Web API for Docker
        Convert, Preview & Render EPL to Image & PDF

       Download

      • Take advantage of our Trial versions!

      • Download Now!

       Product's Documentation

      • Review product help docs online

      • Help Doc Center

       Tech Questions?

      • Get assistance right from members of our Dev Team!

      • Contact Support

  • Downloads
    •  Barcode Professional
      Encoder / Writer / Generator

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • SDK for .NET Windows
      • for Windows Forms
      • for WPF
      • for Blazor
      • for ASP.NET (Web Forms & MVC)
      • for Reporting Services (SSRS)

       ThermalLabel
      Design & Print Barcode Thermal Labels

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • VISUAL LABEL EDITORS Add-on
      • Visual Editor for Windows Add-on
      • Web Editor for ASP.NET Add-on
      • ASP.NET CLIENT SIDE PRINT
      • TLClientPrint (ASP.NET Client Print)

      JS Print Manager
      Printing Solution for Any Web Platform

      • WEB DEV SIDE
      • Javascript Object
      • Blazor Component
      • CLIENT SIDE
      • JSPM for Windows, Linux, RPi, Android & Mac

       WebClientPrint
      RAW & File Printing for ASP.NET & PHP

      • SERVER SIDE
      • for ASP.NET (Core, MVC & WebForms)
      • for PHP
      • CLIENT SIDE
      • WCPP for Windows, Linux, RPi & Mac

       Download Printer Emulator SDKs

      ZPL Printer Emulator SDK
      Convert, Preview & Render ZPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

      EPL Printer Emulator SDK
      Convert, Preview & Render EPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

       Download Virtual Printer Drivers

      Virtual ZPL Printer Driver
      Convert, Print, Preview & Render ZPL

      • Virtual ZPLPrinter Driver for Windows & macOS

      Virtual EPL Printer Driver
      Convert, Print, Preview & Render EPL

      • Virtual EPLPrinter Driver for Windows & macOS

       Download On-Premise Web APIs for Docker

      • BarcodePro Web API for Docker
        2D & Linear Barcode Encoder / Writer / Generator
      • ThermalLabel Web API for Docker
        Design, Preview, Export & Print Barcode Thermal Labels
      • ZPLPrinter Web API for Docker
        Convert, Preview & Render ZPL to Image & PDF
      • EPLPrinter Web API for Docker
        Convert, Preview & Render EPL to Image & PDF
  • Get Help
    •  Contact Support


      •  Get assistance right from members of our Dev Team!
      •  24hs Max Turn-around
      •  Bilingual - English / Español

      • Contact Support Now!

       Product's Documentation


      •  Review product help docs online

      • Go to Documentation Center

       Barcode Center


      •  Learn more about barcode symbologies
      •  Linear (1D), Postal, Component Composite, MICR & 2D

      • Go to Barcode Center

  • Articles
    •  Barcode Professional
      Encoder / Writer / Generator

      • SDK for .NET Windows
      • for Windows Forms
      • for WPF
      • for ASP.NET (Web Forms & MVC)
      • for Reporting Services (SSRS)

       ThermalLabel
      Design & Print Barcode Thermal Labels

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

      ZPL Printer Emulator SDK
      Convert, Preview & Render ZPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

      JS Print Manager
      Printing Solution for Any Web Platform

      • for Any Web Platform
      • for Blazor

       WebClientPrint
      RAW & File Printing for ASP.NET & PHP

      • for ASP.NET (Core, MVC & WebForms)
      • for PHP
  • Purchase
    •  Barcode Professional
      Encoder / Writer / Generator

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • SDK for .NET Windows
      • for Windows Forms
      • for WPF
      • for Blazor
      • for ASP.NET (Web Forms & MVC)
      • for Reporting Services (SSRS)

       ThermalLabel
      Design & Print Barcode Thermal Labels

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)
      • Visual Editor for Windows Add-on
      • Web Editor for ASP.NET Add-on

      JS Print Manager
      Printing Solution for Any Web Platform

      • for Any Web Platform
      • for Blazor

       WebClientPrint
      RAW & File Printing for ASP.NET & PHP

      • for ASP.NET (Core, MVC & WebForms)
      • for PHP

       Buy Printer Emulator SDKs

      ZPL Printer Emulator SDK
      Convert, Preview & Render ZPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

      EPL Printer Emulator SDK
      Convert, Preview & Render EPL to Image & PDF

      • SDK for .NET Standard (.NET, CORE, Xamarin, Mono & UWP)

       Buy Virtual Printer Drivers

      Virtual ZPL Printer Driver
      Convert, Print, Preview & Render ZPL

      • Virtual ZPLPrinter Driver for Windows & macOS

      Virtual EPL Printer Driver
      Convert, Print, Preview & Render EPL

      • Virtual EPLPrinter Driver for Windows & macOS

       Buy On-Premise Web APIs for Docker

      • BarcodePro Web API for Docker
        2D & Linear Barcode Encoder / Writer / Generator
      • ThermalLabel Web API for Docker
        Design, Preview, Export & Print Barcode Thermal Labels
      • ZPLPrinter Web API for Docker
        Convert, Preview & Render ZPL to Image & PDF
      • EPLPrinter Web API for Docker
        Convert, Preview & Render EPL to Image & PDF

      • FAQ
      • Licensing & EULA
      • Request a Quote
      • Renewal & Upgrade
      • Export Regulations
      • Distributors & Resellers
  • Company
    •  About Us

      Founded in 2004, Neodynamic designs and develops Barcode, Imaging, Labeling & Printing Tools for .NET & Web developers. We are experts in those fields with strong know-how on .NET, ASP.NET, SSRS, PHP & HTML/JS projects. More...

       Contact Us

       Customers

      Our products are used by many of the world's most important companies, government agencies, banks, and universities. See our most notable customers...

       Testimonials

       Awards

      • Neodynamic is recognized by its high-quality products and first-class support services that have been acknowledged by its customers around the world.

       Blog

  • Products
  • Printing
  • WebClientPrint
  • for ASP.NET
  • Articles

How to Directly Print a Crystal Reports to Default Client Printer from ASP.NET without Preview or Printer Dialog


Product WebClientPrint for ASP.NET Published 04/11/2013 Updated 10/25/2019 Author Neodynamic

Overview

In this walkthrough, you'll learn how to directly print a Crystal Reports (RPT file) to the Default Client printer from an ASP.NET website without preview! In fact, you'll be able to print the RPT report to any installed printer at the client machine without displaying any Printer Dialog at all! And one important thing... it works with any browser on Windows OS like IE (6 or later), Chrome, Firefox, Opera & Safari as well as on Linux & Mac OS clients!

Directly Print Crystal Reports to Default Client Printer from ASP.NET without Preview or Printer Dialog
Directly Print Crystal Reports to Default Client Printer from ASP.NET without Preview or Printer Dialog

The sample report is a Crystal Reports (RPT) designed to print a products list of the classic and famous MS Northwind Traders database. In a simple ASP.NET webpage, we provide all the needed code in C# and VB to print the rpt sample report file without previewing or displaying any printer dialog by using WebClientPrint for ASP.NET solution

By using WebClientPrint solution in your ASP.NET website, your users will be able to print the Crystal Reports RPT file to the Default client printer as well as to any other installed printer available at the client machine without displaying any print dialog.

Want to add client printing for IE, Firefox & Chrome to CrystalReportViewer? How to add Custom Printing options to ASP.NET Crystal Reports Viewer toolbar



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 PrintCrystalReports
  • Add a NuGet reference to Neodynamic.SDK.WebClientPrint package to your project
  • Now follow up the instructions for each MVC/C#, MVC/VB, SPA/AngularJS+WebAPI, WebForms/CS or WebForms/VB:

    • ASP.NET MVC/C#
    • ASP.NET MVC/VB
    • SPA/AngularJS+WebAPI
    • ASP.NET WebForms/C#
    • ASP.NET WebForms/VB

    Creating/Editing Controllers

    Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

    
    public class WebClientPrintAPIController : Controller
    {
    
        //*********************************
        // 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
        //*********************************
    
        [AllowAnonymous]
        public void ProcessRequest()
        {
            //get session ID
            string sessionID = (HttpContext.Request["sid"] != null ? HttpContext.Request["sid"] : null);
    
            //get Query String
            string queryString = HttpContext.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(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), queryString);
    
                    HttpContext.Response.ContentType = "text/javascript";
                    HttpContext.Response.BinaryWrite(script);
                    HttpContext.Response.End();
                }
                else if (prType == RequestType.ClientSetWcppVersion)
                {
                    //This request is a ping from the WCPP utility
                    //so store the session ID indicating it has the WCPP installed
                    //also store the WCPP Version if available
                    string wcppVersion = HttpContext.Request["wcppVer"];
                    if (string.IsNullOrEmpty(wcppVersion))
                        wcppVersion = "1.0.0.0";
    
                    HttpContext.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 = HttpContext.Request["printers"];
                    if (string.IsNullOrEmpty(printers) == false)
                        printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers));
    
                    HttpContext.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 = HttpContext.Request.Form["printersInfoContent"];
    
                    if (string.IsNullOrEmpty(printersInfo) == false)
                        printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo));
    
                    HttpContext.Application.Set(sessionID + "printersInfo", printersInfo);
    
    
                }
                else if (prType == RequestType.ClientGetWcppVersion)
                {
                    //return the WCPP version for the specified sid if any
                    bool sidWcppVersion = (HttpContext.Application.Get(sessionID + "wcppInstalled") != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write((sidWcppVersion ? HttpContext.Application.Get(sessionID + "wcppInstalled") : ""));
                    HttpContext.Response.End();
    
                }
                else if (prType == RequestType.ClientGetInstalledPrinters)
                {
                    //return the installed printers for the specified sid if any
                    bool sidHasPrinters = (HttpContext.Application.Get(sessionID + "printers") != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write((sidHasPrinters ? HttpContext.Application.Get(sessionID + "printers") : ""));
                    HttpContext.Response.End();
                }
                else if (prType == RequestType.ClientGetInstalledPrintersInfo)
                {
                    //return the installed printers with detailed info for the specified Session ID (sid) if any
                    bool sidHasPrinters = (HttpContext.Application[sessionID + "printersInfo"] != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write(sidHasPrinters ? HttpContext.Application[sessionID + "printersInfo"] : "");
    
                }
    
            }
            catch (Exception ex)
            {
                HttpContext.Response.StatusCode = 500;
                HttpContext.Response.ContentType = "text/plain";
                HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace);
                HttpContext.Response.End();
            }
    
                
        }
    }
    

    Edit the HomeController to the following code:

    
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
    
            ViewBag.WCPPDetectionScript = Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID);
    
            return View();
        }
    
        public ActionResult PrintRPT()
        {
            return View();
        }
    
    }
    

    Add a new Controller and name it PrintRPTController and paste the following code:

    
    using Neodynamic.SDK.Web;
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.Shared;
    using System.Data;
    using System.IO;
    
    public class PrintRPTController : Controller
    {
    	public ActionResult Index()
    	{
    		ViewBag.WCPScript = WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), Url.Action("PrintFile", "PrintRPT", null, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID);
    
    		return View();
    	}
    
    	[AllowAnonymous]
    	public void PrintFile(string useDefaultPrinter, string printerName)
    	{
            //load and set report's data source
            DataSet ds = new DataSet();
            ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"));
     
            //create and load rpt in memory
            ReportDocument myCrystalReport = new ReportDocument();
            myCrystalReport.Load(Server.MapPath("~/MyProducts.rpt"));
            myCrystalReport.SetDataSource(ds.Tables[0]);
     
            //Export rpt to a temp PDF and get binary content
            byte[] pdfContent = null;
            using (Stream rptStream = myCrystalReport.ExportToStream(ExportFormatType.PortableDocFormat))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] buffer = new byte[10000];
                    int bytesRead = 0;
                    do
                    {
                         bytesRead = rptStream.Read(buffer, 0, buffer.Length);
                         ms.Write(buffer, 0, bytesRead);
                    } while (bytesRead > 0);
                    ms.Position = 0;
                    pdfContent = ms.ToArray();
                }
            }
            
            //create a temp file name for our PDF file...
            string fileName = "MyFile-" + Guid.NewGuid().ToString("N");
                
            //Create a PrintFilePDF object with the PDF file
            PrintFilePDF file = new PrintFilePDF(pdfContent, fileName);
            //Create a ClientPrintJob and send it back to the client!
            ClientPrintJob cpj = new ClientPrintJob();
            //set file to print...
            cpj.PrintFile = file;
    
    		//set client printer...
    		if (useDefaultPrinter == "checked" || printerName == "null")
    			cpj.ClientPrinter = new DefaultPrinter();
    		else
    			cpj.ClientPrinter = new InstalledPrinter(printerName);
    		
    		//send it...
    		System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
    		System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent());
    		System.Web.HttpContext.Current.Response.End();
    		
    	}
    
    }
    

    Creating/Editing Views

    The default View is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Views / Shared / _Layout.cshtml file and add the folowing section to the BODY:

    Be sure this View links to jQuery 1.4.1+ file!

    
    <body>
        ...
    	
        @RenderSection("scripts", required: false)
    
    	...
    </body>
    

    Edit the Views / Home / Index.cshtml file and copy/paste the folowing code:

    
    @{
        ViewBag.Title = "Home Page";
    }
    
    
    <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="@Url.Action("Index", "PrintRPT")" >You can go and test the printing page...</a>
        </p>
    
    </div>
    
    @section scripts{
        
    <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 = '@Url.Action("Index", "PrintRPT")';
            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 generated by HomeController *@
    
    @Html.Raw(ViewBag.WCPPDetectionScript)
    
    
        }
    

    Add a new View with the following name and under such folders: Views / PrintRPT / Index.cshtml Then, copy/paste the folowing code:

    
    <h3>Print RPT File</h3>
    
    <div>
    <label class="checkbox">
    	<input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
    </label>
    </div>
    
    <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" style="font-size:18px" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val());" value="Print RPT..." />
    
    
    @section scripts{
        
    @* Register the WebClientPrint script code generated by PrintRPTController. *@
    
    @Html.Raw(ViewBag.WCPScript);
    
        }
    

    Creating/Editing Controllers

    Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

    
    Imports Neodynamic.SDK.Web
    
    Namespace Controllers
        Public Class WebClientPrintAPIController
            Inherits Controller
    
            ' GET: WebClientPrintAPI
            Function Index() As ActionResult
                Return View()
            End Function
    
            '*********************************
            ' 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
            '*********************************
    
            <AllowAnonymous>
            Public Sub ProcessRequest()
                'get session ID
                Dim sessionID As String = (If(HttpContext.Request("sid") IsNot Nothing, HttpContext.Request("sid"), Nothing))
    
                'get Query String
                Dim queryString As String = HttpContext.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(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), queryString)
    
                        HttpContext.Response.ContentType = "text/javascript"
                        HttpContext.Response.BinaryWrite(script)
                        HttpContext.Response.End()
    
                    ElseIf prType = RequestType.ClientSetWcppVersion Then
                        'This request is a ping from the WCPP utility
                        'so store the session ID indicating it has the WCPP installed
                        'also store the WCPP Version if available
                        Dim wcppVersion As String = HttpContext.Request("wcppVer")
                        If String.IsNullOrEmpty(wcppVersion) Then
                            wcppVersion = "1.0.0.0"
                        End If
    
                        HttpContext.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 = HttpContext.Request("printers")
                        If String.IsNullOrEmpty(printers) = False Then
                            printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers))
                        End If
    
    
                        HttpContext.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 = HttpContext.Request.Form("printersInfoContent")
                        If Not String.IsNullOrEmpty(printersInfo) Then
                            printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo))
                        End If
    
                        HttpContext.Application.Set(sessionID & "printersInfo", printersInfo)
    
    
                    ElseIf prType = RequestType.ClientGetWcppVersion Then
                        'return the WCPP version for the specified sid if any
                        Dim sidWcppVersion As Boolean = (HttpContext.Application(sessionID & "wcppInstalled") IsNot Nothing)
    
                        HttpContext.Response.ContentType = "text/plain"
                        If (sidWcppVersion) Then
                            HttpContext.Response.Write(HttpContext.Application(sessionID & "wcppInstalled").ToString())
                        End If
                        HttpContext.Response.End()
    
                    ElseIf prType = RequestType.ClientGetInstalledPrinters Then
                        'return the installed printers for the specified sid if any
                        Dim sidHasPrinters As Boolean = (HttpContext.Application(sessionID & "printers") IsNot Nothing)
    
                        HttpContext.Response.ContentType = "text/plain"
                        If (sidHasPrinters) Then
                            HttpContext.Response.Write(HttpContext.Application(sessionID & "printers").ToString())
                        End If
                        HttpContext.Response.End()
    
                    ElseIf prType = RequestType.ClientGetInstalledPrintersInfo Then
                        'return the installed printers with detailed info for the specified Session ID (sid) if any
                        Dim sidHasPrinters As Boolean = (HttpContext.Application(sessionID & "printersInfo") IsNot Nothing)
    
                        HttpContext.Response.ContentType = "text/plain"
    
                        If (sidHasPrinters) Then
                            HttpContext.Response.Write(HttpContext.Application(sessionID & "printersInfo").ToString())
                        End If
                        HttpContext.Response.End()
                    End If
                Catch ex As Exception
                    HttpContext.Response.StatusCode = 500
                    HttpContext.Response.ContentType = "text/plain"
                    HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace)
                    HttpContext.Response.End()
                End Try
    
    
            End Sub
    
        End Class
    End Namespace
    

    Edit the HomeController to the following code:

    
    Public Class HomeController
        Inherits System.Web.Mvc.Controller
    
        Function Index() As ActionResult
            ViewData("WCPPDetectionScript") = Neodynamic.SDK.Web.WebClientPrint.CreateWcppDetectionScript(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID)
    
            Return View()
        End Function
    
        Function PrintRPT() As ActionResult
    
            Return View()
        End Function
    
    End Class
    

    Add a new Controller and name it PrintRPTController and paste the following code:

    
    Imports Neodynamic.SDK.Web
    Imports CrystalDecisions.CrystalReports.Engine
    Imports CrystalDecisions.Shared
    Imports System.Data
    Imports System.IO
    
    Namespace Controllers
        Public Class PrintRPTController
            Inherits Controller
    
            Function Index() As ActionResult
    
                ViewData("WCPScript") = Neodynamic.SDK.Web.WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", Nothing, HttpContext.Request.Url.Scheme), Url.Action("PrintFile", "PrintRPT", Nothing, HttpContext.Request.Url.Scheme), HttpContext.Session.SessionID)
    
                Return View()
            End Function
    
            <AllowAnonymous> Public Sub PrintFile(useDefaultPrinter As String, printerName As String)
    
                'load and set report's data source
                Dim ds As New DataSet()
                ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"))
     
                'create and load rpt in memory
                Dim myCrystalReport As New ReportDocument()
                myCrystalReport.Load(Server.MapPath("~/MyProducts.rpt"))
                myCrystalReport.SetDataSource(ds.Tables(0))
     
                'Export rpt to a temp PDF and get binary content
                Dim pdfContent As Byte() = Nothing
                Using rptStream As Stream = myCrystalReport.ExportToStream(ExportFormatType.PortableDocFormat)
                    Using ms As New MemoryStream()
                        Dim buffer As New Byte(10000)
                        Dim bytesRead As Integer = 0
                        Do
                             bytesRead = rptStream.Read(buffer, 0, buffer.Length)
                             ms.Write(buffer, 0, bytesRead)
                        While (bytesRead > 0)
                        ms.Position = 0
                        pdfContent = ms.ToArray()
                    End Using
                End Using
    
                'create a temp file name for our PDF file...
                Dim fileName As String = "MyFile-" + Guid.NewGuid().ToString("N")
                
                'Create a PrintFile object with the PDF file
                Dim file As New PrintFilePDF(pdfContent, fileName)
                'Create a ClientPrintJob and send it back to the client!
                Dim cpj As New ClientPrintJob()
                'set file to print...
                cpj.PrintFile = file
    
                If (useDefaultPrinter = "checked" OrElse printerName = "null") Then
                    cpj.ClientPrinter = New DefaultPrinter()
                Else
                    cpj.ClientPrinter = New InstalledPrinter(System.Web.HttpUtility.UrlDecode(printerName))
                End If
    
                System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"
                System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent())
                System.Web.HttpContext.Current.Response.End()
    
            End Sub
        End Class
    End Namespace
    

    Creating/Editing Views

    The default View is for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed. Edit the Views / Shared / _Layout.vbhtml file and add the folowing section to the BODY:

    Be sure this View links to jQuery 1.4.1+ file!

    
    <body>
        ...
    	
        @RenderSection("scripts", required: False)
    
    	...
    </body>
    

    Edit the Views / Home / Index.vbhtml file and copy/paste the folowing code:

    
    @Code
        ViewData("Title") = "Home Page"
    End Code
    
    
    <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="@Url.Action("Index", "PrintRPT")" >You can go and test the printing page...</a>
        </p>
    
    </div>
    
    @section scripts
        
    <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 = '@Url.Action("Index", "PrintRPT")';
            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 generated by HomeController *@
    
    @Html.Raw(ViewData("WCPPDetectionScript"))
    
    
        }
    
    End Section
    

    Add a new View with the following name and under such folders: Views / PrintRPT / Index.vbhtml Then, copy/paste the folowing code:

    
    <h3>Print RPT File</h3>
    
    <div>
    <label class="checkbox">
    	<input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
    </label>
    </div>
    
    <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" style="font-size:18px" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val());" value="Print RPT..." />
    
    
    @section scripts
        
        @* Register the WebClientPrint script code generated by PrintRPTController. *@
    
        @Html.Raw(ViewData("WCPScript"))
    
    @end section
    

    Creating/Editing Controllers

    Create a new Controller and name it WebClientPrintAPIController and then copy/paste the following code:

    
    public class WebClientPrintAPIController : Controller
    {
    
        //*********************************
        // 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
        //*********************************
        [AllowAnonymous]
        public void ProcessRequest()
        {
            //get session ID
            string sessionID = (HttpContext.Request["sid"] != null ? HttpContext.Request["sid"] : null);
    
            //get Query String
            string queryString = HttpContext.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(Url.Action("ProcessRequest", "WebClientPrintAPI", null, HttpContext.Request.Url.Scheme), queryString);
    
                    HttpContext.Response.ContentType = "text/javascript";
                    HttpContext.Response.BinaryWrite(script);
                    HttpContext.Response.End();
                }
                else if (prType == RequestType.ClientSetWcppVersion)
                {
                    //This request is a ping from the WCPP utility
                    //so store the session ID indicating it has the WCPP installed
                    //also store the WCPP Version if available
                    string wcppVersion = HttpContext.Request["wcppVer"];
                    if (string.IsNullOrEmpty(wcppVersion))
                        wcppVersion = "1.0.0.0";
    
                    HttpContext.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 = HttpContext.Request["printers"];
                    if (string.IsNullOrEmpty(printers) == false)
                        printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers));
    
                    HttpContext.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 = HttpContext.Request.Form["printersInfoContent"];
    
                    if (string.IsNullOrEmpty(printersInfo) == false)
                        printersInfo = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printersInfo));
    
                    HttpContext.Application.Set(sessionID + "printersInfo", printersInfo);
    
    
                }
                else if (prType == RequestType.ClientGetWcppVersion)
                {
                    //return the WCPP version for the specified sid if any
                    bool sidWcppVersion = (HttpContext.Application.Get(sessionID + "wcppInstalled") != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write((sidWcppVersion ? HttpContext.Application.Get(sessionID + "wcppInstalled") : ""));
                    HttpContext.Response.End();
    
                }
                else if (prType == RequestType.ClientGetInstalledPrinters)
                {
                    //return the installed printers for the specified sid if any
                    bool sidHasPrinters = (HttpContext.Application.Get(sessionID + "printers") != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write((sidHasPrinters ? HttpContext.Application.Get(sessionID + "printers") : ""));
                    HttpContext.Response.End();
                }
                else if (prType == RequestType.ClientGetInstalledPrintersInfo)
                {
                    //return the installed printers with detailed info for the specified Session ID (sid) if any
                    bool sidHasPrinters = (HttpContext.Application[sessionID + "printersInfo"] != null);
    
                    HttpContext.Response.ContentType = "text/plain";
                    HttpContext.Response.Write(sidHasPrinters ? HttpContext.Application[sessionID + "printersInfo"] : "");
    
                }
    
            }
            catch (Exception ex)
            {
                HttpContext.Response.StatusCode = 500;
                HttpContext.Response.ContentType = "text/plain";
                HttpContext.Response.Write(ex.Message + " - StackTrace: " + ex.StackTrace);
                HttpContext.Response.End();
            }
    
                
        }
        
    }
    

    Add a new Controller and name it PrintRPTController and paste the following code:

    
    using Neodynamic.SDK.Web;
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.Shared;
    using System.Data;
    using System.IO;
    
    public class PrintRPTController : Controller
    {
    	public ActionResult Index()
    	{
    		return View();
    	}
    
    	[AllowAnonymous]
    	public void PrintFile(string useDefaultPrinter, string printerName)
    	{
            //load and set report's data source
            DataSet ds = new DataSet();
            ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"));
     
            //create and load rpt in memory
            ReportDocument myCrystalReport = new ReportDocument();
            myCrystalReport.Load(Server.MapPath("~/MyProducts.rpt"));
            myCrystalReport.SetDataSource(ds.Tables[0]);
     
            //Export rpt to a temp PDF and get binary content
            byte[] pdfContent = null;
            using (Stream rptStream = myCrystalReport.ExportToStream(ExportFormatType.PortableDocFormat))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] buffer = new byte[10000];
                    int bytesRead = 0;
                    do
                    {
                         bytesRead = rptStream.Read(buffer, 0, buffer.Length);
                         ms.Write(buffer, 0, bytesRead);
                    } while (bytesRead > 0);
                    ms.Position = 0;
                    pdfContent = ms.ToArray();
                }
            }
            
            //create a temp file name for our PDF file...
            string fileName = "MyFile-" + Guid.NewGuid().ToString("N");
                
            //Create a PrintFilePDF object with the PDF file
            PrintFilePDF file = new PrintFilePDF(pdfContent, fileName);
            //Create a ClientPrintJob and send it back to the client!
            ClientPrintJob cpj = new ClientPrintJob();
            //set file to print...
            cpj.PrintFile = file;
    
    		//set client printer...
    		if (useDefaultPrinter == "checked" || printerName == "null")
    			cpj.ClientPrinter = new DefaultPrinter();
    		else
    			cpj.ClientPrinter = new InstalledPrinter(printerName);
    		
    		//send it...
    		System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
    		System.Web.HttpContext.Current.Response.BinaryWrite(cpj.GetContent());
    		System.Web.HttpContext.Current.Response.End();
    		
    	}
    
    }
    

    Creating SPA by using AngularJS

    Create a new index.html file that will act as our view for detecting whether the client machine has the WebClientPrint Processor (WCPP) Utility installed as well as for listing client printers and to finally perform client side printing. This SPA features two parts or sections, one for "Detecting WCPP" and the other one for "Client side printing". The ClientPrintJob is generated by the controller created above from the Web API server side code. Copy/Paste the following markup:

    Be sure this html file links to jQuery 1.4.1+ and to AngularJS 1.6.4+ files!

    
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
    	<meta charset="utf-8" />
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    </head>
    <body>
    
        <div ng-app="myApp" ng-controller="myCtrl">
    
            <div id="wcppDetection">
                <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="#" onclick="javascript:$('#wcppDetection').hide();$('#printSection').show();">You can go and test the printing page...</a>
                    </p>
    
                    <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"){
                                $('#wcppDetection').hide();
                                $('#printSection').show();
                            }   
                            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>
    
                </div>
                
                <input type="hidden" id="sid" name="sid" ng-value="sid" />
                <script>
                    $(function () {
                        //Gen script for WCPP detection
                        $.getScript('/WebClientPrintAPI/ProcessRequest?d=' + $('#sid').val());
                    });
                </script>
    
            </div>
    
            <div id="printSection" style="display:none;">
                <h3>Print RPT commands</h3>
    
                <div>
                    <label class="checkbox">
                        <input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
                    </label>
                </div>
    
                <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" style="font-size:18px" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val());" value="Print RPT..." />
    
                <script>
                    $(function () {
                        // Create Base64 Object
                        var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function (e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n = e.charCodeAt(f++); r = e.charCodeAt(f++); i = e.charCodeAt(f++); s = n >> 2; o = (n & 3) << 4 | r >> 4; u = (r & 15) << 2 | i >> 6; a = i & 63; if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) } return t }, _utf8_encode: function (e) { e = e.replace(/\r\n/g, "\n"); var t = ""; for (var n = 0; n < e.length; n++) { var r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128) } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128) } } return t } }
    
                        // Creat script for client side printing
                        var rootUrl = $(location).attr('protocol') + "//" + $(location).attr('host');
                        var ABSOLUTE_URL_TO_PRINT_JOB_CONTROLLER = rootUrl + '/PrintRPT/PrintFile';
                        $.getScript('/WebClientPrintAPI/ProcessRequest?v6.0.0.0&' + new Date().getTime() + '&sid=' + $('#sid').val() + '&u=' + Base64.encode(ABSOLUTE_URL_TO_PRINT_JOB_CONTROLLER));
                        
                    });
                </script>
    
    
            </div>
        </div>
    
        <script>
            var app = angular.module('myApp', []);
            app.controller('myCtrl', function($scope) {
                $scope.sid = new Date().getTime();
            });
        </script>
    </body>
    </html>
    
    

    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 PrintRPTHandler and then copy/paste the following code:

    
    <%@ WebHandler Language="C#" Class="PrintRPTHandler" %>
    
    using System;
    using System.Web;
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.Shared;
    using System.Data;
    using System.IO;
    
    using Neodynamic.SDK.Web;
    
    public class PrintRPTHandler : 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))
            {
                           
                bool useDefaultPrinter = (Request["useDefaultPrinter"] == "checked");
                string printerName = Server.UrlDecode(Request["printerName"]);
    
                //load and set report's data source
                DataSet ds = new DataSet();
                ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"));
     
                //create and load rpt in memory
                ReportDocument myCrystalReport = new ReportDocument();
                myCrystalReport.Load(Server.MapPath("~/MyProducts.rpt"));
                myCrystalReport.SetDataSource(ds.Tables[0]);
     
                //Export rpt to a temp PDF and get binary content
                byte[] pdfContent = null;
                using (Stream rptStream = myCrystalReport.ExportToStream(ExportFormatType.PortableDocFormat))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        byte[] buffer = new byte[10000];
                        int bytesRead = 0;
                        do
                        {
                             bytesRead = rptStream.Read(buffer, 0, buffer.Length);
                             ms.Write(buffer, 0, bytesRead);
                        } while (bytesRead > 0);
                        ms.Position = 0;
                        pdfContent = ms.ToArray();
                    }
                }
            
                //create a temp file name for our PDF file...
                string fileName = "MyFile-" + Guid.NewGuid().ToString("N");
                
                //Create a PrintFilePDF object with the PDF file
                PrintFilePDF file = new PrintFilePDF(pdfContent, fileName);
                //Create a ClientPrintJob and send it back to the client!
                ClientPrintJob cpj = new ClientPrintJob();
                //set file to print...
                cpj.PrintFile = file;
    
    		    //set client printer...
    		    if (useDefaultPrinter || printerName == "null")
    			    cpj.ClientPrinter = new DefaultPrinter();
    		    else
    			    cpj.ClientPrinter = new InstalledPrinter(printerName);
    		
    		    //send it...		    
                context.Response.ContentType = "application/octet-stream";
                context.Response.BinaryWrite(cpj.GetContent());
                context.Response.End();
                
            }
            
        }
     
        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="PrintRPT.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 = 'PrintRPT.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 PrintRPT.aspx. Copy/paste the following code inside the BODY:

    
    <h3>Print RPT File</h3>
    
    <div>
    <label class="checkbox">
    	<input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
    </label>
    </div>
    
    <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" style="font-size:18px" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val());" value="Print RPT..." />
    
    <%-- 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 + "/PrintRPTHandler.ashx", HttpContext.Current.Session.SessionID)%>
    
    

    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 PrintRPTHandler and then copy/paste the following code:

    
    <%@ WebHandler Language="VB" Class="PrintRPTHandler" %>
    
    Imports System
    Imports System.Web
    
    Imports Neodynamic.SDK.Web
    
    Public Class PrintRPTHandler : 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
                           
                Dim useDefaultPrinter As Boolean = (Request("useDefaultPrinter") = "checked")
                Dim printerName As String = Server.UrlDecode(Request("printerName"))
    
                'load and set report's data source
                Dim ds As New DataSet()
                ds.ReadXml(Server.MapPath("~/NorthwindProducts.xml"))
     
                'create and load rpt in memory
                Dim myCrystalReport As New ReportDocument()
                myCrystalReport.Load(Server.MapPath("~/MyProducts.rpt"))
                myCrystalReport.SetDataSource(ds.Tables(0))
     
                'Export rpt to a temp PDF and get binary content
                Dim pdfContent As Byte() = Nothing
                Using rptStream As Stream = myCrystalReport.ExportToStream(ExportFormatType.PortableDocFormat)
                    Using ms As New MemoryStream()
                        Dim buffer As New Byte(10000)
                        Dim bytesRead As Integer = 0
                        Do
                             bytesRead = rptStream.Read(buffer, 0, buffer.Length)
                             ms.Write(buffer, 0, bytesRead)
                        While (bytesRead > 0)
                        ms.Position = 0
                        pdfContent = ms.ToArray()
                    End Using
                End Using
    
                'create a temp file name for our PDF file...
                Dim fileName As String = "MyFile-" + Guid.NewGuid().ToString("N")
                
                'Create a PrintFile object with the PDF file
                Dim file As New PrintFilePDF(pdfContent, fileName)
                'Create a ClientPrintJob and send it back to the client!
                Dim cpj As New ClientPrintJob()
                'set file to print...
                cpj.PrintFile = file
    
                If useDefaultPrinter OrElse printerName = "null" Then
                    cpj.ClientPrinter = New DefaultPrinter()
                Else
                    cpj.ClientPrinter = New InstalledPrinter(printerName)
                End If
    
                context.Response.ContentType = "application/octet-stream"
                context.Response.BinaryWrite(cpj.GetContent())
                context.Response.End()
                
            End If
    
        End Sub
    
    
        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="PrintRPT.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 = 'PrintRPT.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 PrintRPT.aspx. Copy/paste the following code inside the BODY:

    
    <h3>Print RPT File</h3>
    
    <div>
    <label class="checkbox">
    	<input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
    </label>
    </div>
    
    <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" style="font-size:18px" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val());" value="Print RPT..." />
    
    <%-- 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 + "/PrintRPTHandler.ashx", HttpContext.Current.Session.SessionID)%>
    
    
  • That's it! Run your website and test it. Click on Print RPT to print the PDF file 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 Custom Printing options to ASP.NET Crystal Reports Viewer toolbar

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.

Products

Barcode Professional
Encoder/Writer/Generator

ThermalLabel
Design &Print Barcode Thermal Labels

ZPLPrinter Emulator SDK
Convert, Preview & Render ZPL

JSPrintManager
Printing Solution for Any Web Platform

WebClientPrint
Raw Data Printing for Websites

Downloads

Download fully-functional trials

Get Help

Contact Support

Articles, Tutorials & Guides
Get Help Docs
Barcode Center
GitHub Projects

Purchase

Buy Licenses
Renewal & Upgrade
Request a Quote

Keep in touch

Contact Us
Follow @neodynamic1

Company

Founded in 2004, Neodynamic designs and develops Barcode, Imaging, Labeling & Printing Tools for .NET, PHP, Docker & Web developers. We are experts in those fields with strong know-how on .NET, ASP.NET, SSRS, PHP & HTML/JS projects.

Copyright © 2004 - 2025 Neodynamic - All rights reserved.  |  Privacy Policy  |  Contact Us  |  Sitemap