Printing Support In Asp.Net Core
In this article we will be demonstrating how to print document in Asp.Net Core. That is, we will be looking at WebClientPrint 3.0. WebClientPrint for ASP.NET Core is a lightweight and plugin-free solution for Client-side Raw Data Printing scenarios for Windows, Linux, Raspberry Pi & Mac clients, exclusively designed for ASP.NET Core MVC projects. With our WebClientPrint solution, you can easily send raw data, text and native commands as well as known file & document formats to printers installed at the client machine without showing or displaying any print dialog box!
Now let’s get started.
Open Visual Studio 2015 Update 3 or higher version.
- File >> New Project.
- Choose Asp.Net Core Web Application.
- Provide a suitable name for the project
- Click Ok.
- Now choose the Web Application Template.
- Tap Ok.
It will take a few seconds to create our project. The default screen of Visual Studio appears like this:
Now, first thing we need to do is install Neodynamic.SDK.WebClientPrintCore. We can install the package through Nuget Packet Manager or simply write this in project.json file in the Solution Explorer.
After installing package lets write some code now. Go to HomeController and write the following code as shown in the code snippet below:
Now let’s create a view page. For this lets go to Views/Home/Index.cshtml file and add the following code:
@{ ViewData["Title"] = "Detecting WebClientPrint Processor (WCPP)"; } @section styles{
<style type="text/css">
.glyphicon-refresh-animate {
-animation: spin .7s infinite linear;
-webkit-animation: spin2 .7s infinite linear;
}
@@-webkit-keyframes spin2 {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@@keyframes spin {
from {
transform: scale(1) rotate(0deg);
}
to {
transform: scale(1) rotate(360deg);
}
}
</style>
}
<div id="msgInProgress">
<div id="mySpinner" style="width:32px;height:32px"></div>
<br />
<h3>Detecting WCPP utility at client side...</h3>
<h3>
<span class="label label-info">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> Please wait a few seconds...
</span>
</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 Core 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="http://www.neodynamic.com/downloads/wcpp/" target="_blank" class="btn btn-warning">Download and Install WCPP from Neodynamic website</a>
<br />
</p>
<h3>#2 After installing WCPP...</h3>
<p>
<a asp-controller="Home" asp-action="Samples" class="btn btn-info">You can go and test the printing page...</a>
</p>
</div>
@section scripts {
<script type="text/javascript">
//var wcppPingDelay_ms = 5000;
var wcppPingTimeout_ms = 10000; //10 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) == "3")
window.location.href = '@Url.Action("samples", "home")';
else //force to install WCPP v3.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"]) } @{ ViewData["Title"] = "Detecting WebClientPrint Processor (WCPP)"; } @section styles{
<style type="text/css">
.glyphicon-refresh-animate {
-animation: spin .7s infinite linear;
-webkit-animation: spin2 .7s infinite linear;
}
@@-webkit-keyframes spin2 {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@@keyframes spin {
from {
transform: scale(1) rotate(0deg);
}
to {
transform: scale(1) rotate(360deg);
}
}
</style>
}
<div id="msgInProgress">
<div id="mySpinner" style="width:32px;height:32px"></div>
<br />
<h3>Detecting WCPP utility at client side...</h3>
<h3>
<span class="label label-info">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> Please wait a few seconds...
</span>
</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 Core 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="http://www.neodynamic.com/downloads/wcpp/" target="_blank" class="btn btn-warning">Download and Install WCPP from Neodynamic website</a>
<br />
</p>
<h3>#2 After installing WCPP...</h3>
<p>
<a asp-controller="Home" asp-action="Samples" class="btn btn-info">You can go and test the printing page...</a>
</p>
</div>
@section scripts {
<script type="text/javascript">
//var wcppPingDelay_ms = 5000;
var wcppPingTimeout_ms = 10000; //10 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) == "3")
window.location.href = '@Url.Action("samples", "home")';
else //force to install WCPP v3.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["DetectionScript"]) }
Now lets render the sections that we created in Layout file.
- Go to Views/Shared/_Layout.cshtml
- Add the following code in it.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - TestWebClientPrint 3.0 for ASP.NET Core</title>
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
@RenderSection("styles", required: false)
<style type="text/css">
.navbar-custom {
background-color: #373c3e;
color: #ffffff;
border-radius: 0;
}
.navbar-custom .navbar-nav > li > a {
color: #fff;
}
.navbar-custom .navbar-nav > .active > a,
.navbar-nav > .active > a:hover,
.navbar-nav > .active > a:focus {
color: #ffffff;
background-color: transparent;
}
.navbar-custom .navbar-nav > li > a:hover,
.nav > li > a:focus {
text-decoration: none;
background-color: #acdaee;
}
.navbar-custom .navbar-brand {
color: #eeeeee;
}
.navbar-custom .navbar-toggle {
background-color: #eeeeee;
}
.navbar-custom .icon-bar {
background-color: #acdaee;
}
</style>
</head>
<body>
<div class="navbar navbar-default navbar-custom navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<img alt="Neodynamic" src="//www.neodynamic.com/images/webclientprinticon.png">
</a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="//www.neodynamic.com/products/printing/raw-data/aspnet-core/download/" target="_blank" class="navbar-brand">WebClientPrint 3.0 for ASP.NET Core</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-controller="Home" asp-action="Samples">Samples</a></li>
<li><a asp-controller="DemoPrintFile" asp-action="Index">Print Files</a></li>
<li><a asp-controller="DemoPrintCommands" asp-action="Index">Print RAW Commands</a></li>
<li><a href="//www.neodynamic.com/products/printing/raw-data/aspnet-core/" target="_blank">About</a></li>
</ul>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="//www.neodynamic.com/products/printing/raw-data/aspnet-mvc/download/" target="_blank"><i class="glyphicon glyphicon-download-alt"></i> Download SDK for ASP.NET</a>
</div>
<hr />
<p>
<small><em>Cross-browser Client-side Printing Solution for Windows, Linux, Mac & Raspberry Pi</em></small>
</p>
</div>
</div>
<div class="container body-content">
<br />
<br />
<br />
<br />
<br />
<br />
<br /> @RenderBody()
<footer>
<br />
<br />
<br />
<br />
<hr />
<p>
<a href="//www.neodynamic.com/products/printing/raw-data/aspnet-mvc/" target="_blank">WebClientPrint for ASP.NET Core</a> |
<i class="icon-user"></i> <a href="http://www.neodynamic.com/spport" target="_blank">Contact Tech Support</a>
</p>
<p>© Copyright @DateTime.Now.Year - Neodynamic SRL
<br />All rights reserved.</p>
</footer>
</div>
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js" asp-fallback-src="~/lib/jquery/dist/jquery.min.js" asp-fallback-test="window.jQuery">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js" asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js" asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("scripts", required: false)
</body>
</html>
Now run the application and output looks like this:
Now we need to add the following code in the StartUp class as shown in the code snippet below:
Now after creating View, lets create another controller and name it as “WebClientAPIController”.
- Right Click on Controllers Folder
- Add New Item
- Choose WebAPI Controller class from the Template and provide name.
- Click on Add.
Now let’s add some code in this Controller as shown in the code snippet below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Caching.Memory;
using Neodynamic.SDK.Web;
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace TestWebClientPrint.Controllers
{
[Authorize]
public class WebClientPrintAPIController : Controller
{
//IMPORTANT NOTE >>>>>>>>>>
// We're going to use MemoryCache to store users related staff like
// the list of printers and they have the WCPP client utility installed
// BUT you can change it based on your dev needs!!!
// For instance, you could use a Distributed Cache instead!
//>>>>>>>>>>>>>>>>>>>>>>>>>
private readonly IMemoryCache _MemoryCache;
public WebClientPrintAPIController(IMemoryCache memCache)
{
_MemoryCache = memCache;
}
[AllowAnonymous]
public IActionResult ProcessRequest()
{
//get session ID
string sessionID = HttpContext.Request.Query["sid"].ToString();
//get Query String
string queryString = HttpContext.Request.QueryString.Value;
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.Scheme), queryString);
return File(script, "application/x-javascript", "WebClientPrintScript");
}
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.Query["wcppVer"];
if (string.IsNullOrEmpty(wcppVersion))
wcppVersion = "1.0.0.0";
_MemoryCache.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.Query["printers"].ToString();
if (!string.IsNullOrEmpty(printers) && printers.Length > 0)
printers = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(printers));
_MemoryCache.Set(sessionID + "printers", printers);
}
else if (prType == RequestType.ClientGetWcppVersion)
{
//return the WCPP version for the specified sid if any
bool sidWcppVersion = (_MemoryCache.Get<string>(sessionID + "wcppInstalled") != null);
return Ok(sidWcppVersion ? _MemoryCache.Get<string>(sessionID + "wcppInstalled") : "");
}
else if (prType == RequestType.ClientGetInstalledPrinters)
{
//return the installed printers for the specified sid if any
bool sidHasPrinters = (_MemoryCache.Get<string>(sessionID + "printers") != null);
return Ok(sidHasPrinters ? _MemoryCache.Get<string>(sessionID + "printers") : "");
}
}
catch
{
return BadRequest();
}
return null;
}
}
}
Now run the application and you will see the following output:
Here we need to install WebClientPrint Processor(WCPP) then we can test the print page.
Now let’s go the Home Controller and add action method as shown in the code snippet below:
Now let’s create a view in Views/Home folder named as Samples.cshtml
- Right Click on Home Folder.
- Add New Item.
- Choose MVC View Page from the Templates.
- Click on Add.
And add the codes as shown below:
Now run the application and we will see this screen:
Now we will add a Controller named “DemoPrintCommandController” and add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Neodynamic.SDK.Web;
namespace TestWebClientPrint.Controllers
{
public class DemoPrintCommandsController : Controller
{
//We're going to use MemoryCache BUT you can change it based on your dev needs!!!
private readonly IMemoryCache _MemoryCache;
public DemoPrintCommandsController(IMemoryCache memCache)
{
_MemoryCache = memCache;
}
public IActionResult Index()
{
ViewData["WCPScript"] = Neodynamic.SDK.Web.WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, Url.ActionContext.HttpContext.Request.Scheme), Url.Action("PrintCommands", "DemoPrintCommands", null, Url.ActionContext.HttpContext.Request.Scheme), Url.ActionContext.HttpContext.Session.Id);
return View();
}
const string PRINTER_ID = "-PID";
const string INSTALLED_PRINTER_NAME = "-InstalledPrinterName";
const string NET_PRINTER_HOST = "-NetPrinterHost";
const string NET_PRINTER_PORT = "-NetPrinterPort";
const string PARALLEL_PORT = "-ParallelPort";
const string SERIAL_PORT = "-SerialPort";
const string SERIAL_PORT_BAUDS = "-SerialPortBauds";
const string SERIAL_PORT_DATA_BITS = "-SerialPortDataBits";
const string SERIAL_PORT_STOP_BITS = "-SerialPortStopBits";
const string SERIAL_PORT_PARITY = "-SerialPortParity";
const string SERIAL_PORT_FLOW_CONTROL = "-SerialPortFlowControl";
const string PRINTER_COMMANDS = "-PrinterCommands";
[HttpPost]
public void ClientPrinterSettings(string sid,
string pid,
string installedPrinterName,
string netPrinterHost,
string netPrinterPort,
string parallelPort,
string serialPort,
string serialPortBauds,
string serialPortDataBits,
string serialPortStopBits,
string serialPortParity,
string serialPortFlowControl,
string printerCommands)
{
try
{
//save settings in the global cahe obj
//save the type of printer selected by the user
int i = int.Parse(pid);
_MemoryCache.Set(sid + PRINTER_ID, i.ToString());
if (i == 2)
{
_MemoryCache.Set(sid + INSTALLED_PRINTER_NAME, installedPrinterName);
}
else if (i == 3)
{
_MemoryCache.Set(sid + NET_PRINTER_HOST, netPrinterHost);
_MemoryCache.Set(sid + NET_PRINTER_PORT, netPrinterPort);
}
else if (i == 4)
{
_MemoryCache.Set(sid + PARALLEL_PORT, parallelPort);
}
else if (i == 5)
{
_MemoryCache.Set(sid + SERIAL_PORT, serialPort);
_MemoryCache.Set(sid + SERIAL_PORT_BAUDS, serialPortBauds);
_MemoryCache.Set(sid + SERIAL_PORT_DATA_BITS, serialPortDataBits);
_MemoryCache.Set(sid + SERIAL_PORT_FLOW_CONTROL, serialPortFlowControl);
_MemoryCache.Set(sid + SERIAL_PORT_PARITY, serialPortParity);
_MemoryCache.Set(sid + SERIAL_PORT_STOP_BITS, serialPortStopBits);
}
//save the printer commands specified by the user
_MemoryCache.Set(sid + PRINTER_COMMANDS, printerCommands);
}
catch (Exception ex)
{
throw ex;
}
}
//sid: user session id who is requesting a ClientPrintJob
public IActionResult PrintCommands(string sid)
{
try
{
//Create a ClientPrintJob obj that will be processed at the client side by the WCPP
ClientPrintJob cpj = new ClientPrintJob();
//get printer commands for this user id
object printerCommands = _MemoryCache.Get<string>(sid + PRINTER_COMMANDS);
if (printerCommands != null)
{
cpj.PrinterCommands = printerCommands.ToString();
cpj.FormatHexValues = true;
}
//get printer settings for this user id
int printerTypeId = int.Parse(_MemoryCache.Get<string>(sid + PRINTER_ID));
if (printerTypeId == 0) //use default printer
{
cpj.ClientPrinter = new DefaultPrinter();
}
else if (printerTypeId == 1) //show print dialog
{
cpj.ClientPrinter = new UserSelectedPrinter();
}
else if (printerTypeId == 2) //use specified installed printer
{
cpj.ClientPrinter = new InstalledPrinter(_MemoryCache.Get<string>(sid + INSTALLED_PRINTER_NAME));
}
else if (printerTypeId == 3) //use IP-Ethernet printer
{
cpj.ClientPrinter = new NetworkPrinter(_MemoryCache.Get<string>(sid + NET_PRINTER_HOST), int.Parse(_MemoryCache.Get<string>(sid + NET_PRINTER_PORT)));
}
else if (printerTypeId == 4) //use Parallel Port printer
{
cpj.ClientPrinter = new ParallelPortPrinter(_MemoryCache.Get<string>(sid + PARALLEL_PORT));
}
else if (printerTypeId == 5) //use Serial Port printer
{
cpj.ClientPrinter = new SerialPortPrinter(_MemoryCache.Get<string>(sid + SERIAL_PORT),
int.Parse(_MemoryCache.Get<string>(sid + SERIAL_PORT_BAUDS)),
(SerialPortParity)Enum.Parse(typeof(SerialPortParity), _MemoryCache.Get<string>(sid + SERIAL_PORT_PARITY)),
(SerialPortStopBits)Enum.Parse(typeof(SerialPortStopBits), _MemoryCache.Get<string>(sid + SERIAL_PORT_STOP_BITS)),
int.Parse(_MemoryCache.Get<string>(sid + SERIAL_PORT_DATA_BITS)),
(SerialPortHandshake)Enum.Parse(typeof(SerialPortHandshake), _MemoryCache.Get<string>(sid + SERIAL_PORT_FLOW_CONTROL)));
}
//Send ClientPrintJob back to the client
return File(cpj.GetContent(), "application/octet-stream");
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
}
}
Now lets create a view page. Lets go to Views and add a folder named “DemoPrintCommands” and add a view page Index.cshtml and the following code:
@{
ViewData["Title"] = "Printing RAW Commands";
}
@section styles{
<style type="text/css">
fieldset {
width: 700px;
border: 0 none #ffffff;
}
legend {
visibility: hidden;
}
label {
display: block;
margin: 15px 0 5px;
}
input[type=text], input[type=password] {
width: 300px;
padding: 5px;
border: solid 1px #000;
}
.prev {
float: left;
}
.next {
float: right;
}
#steps {
list-style: none;
width: 100%;
overflow: hidden;
margin: 0px;
padding: 0px;
}
#steps li {
font-size: 24px;
float: left;
padding: 10px;
color: #b0b1b3;
}
#steps li span {
font-size: 11px;
display: block;
}
#steps li.current {
color: #000;
}
</style>
}
<h3>Print Raw/Text Commands</h3>
<div class="container">
<div class="row">
<form id="myForm" action="">
@* Store User's SessionId *@
<input type="hidden" id="sid" name="sid" value="@Url.ActionContext.HttpContext.Session.Id" />
@* Collect User's printer settings *@
<fieldset>
<legend>Client Printer Settings</legend>
<div>
WebClientPrint does support all common printer communications like USB-Installed
Drivers, Network/IP-Ethernet, Serial COM-RS232 and Parallel (LPT).
<br />
<br />
I want to:
<select id="pid" name="pid">
<option selected="selected" value="0">Use Default Printer</option>
<option value="1">Display a Printer dialog</option>
<option value="2">Use an installed Printer</option>
<option value="3">Use an IP/Etherner Printer</option>
<option value="4">Use a LPT port</option>
<option value="5">Use a RS232 (COM) port</option>
</select>
<br />
<br />
<div id="info" class="alert alert-info" style="font-size:11px;"></div>
<br />
</div>
<div id="installedPrinter">
<div id="loadPrinters" name="loadPrinters">
WebClientPrint can detect the installed printers in your machine. <a onclick="javascript:jsWebClientPrint.getPrinters();" class="btn btn-success">Load installed printers...</a>
<br /><br />
</div>
<label for="installedPrinterName">Select an installed Printer:</label>
<select name="installedPrinterName" id="installedPrinterName"></select>
<script type="text/javascript">
//var wcppGetPrintersDelay_ms = 5000; //5 sec
var wcppGetPrintersTimeout_ms = 10000; //10 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>';
}
$('#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>
</div>
<div id="netPrinter">
<label for="netPrinterHost">Printer's DNS Name or IP Address:</label>
<input type="text" name="netPrinterHost" id="netPrinterHost" />
<label for="netPrinterPort">Printer's Port:</label>
<input type="text" name="netPrinterPort" id="netPrinterPort" />
</div>
<div id="parallelPrinter">
<label for="parallelPort">Parallel Port:</label>
<input type="text" name="parallelPort" id="parallelPort" value="LPT1" />
</div>
<div id="serialPrinter">
<table border="0">
<tr>
<td valign="top">
<label for="serialPort">Serial Port:</label>
<input type="text" name="serialPort" id="serialPort" value="COM1" />
<label for="serialPortBauds">Baud Rate:</label>
<input type="text" name="serialPortBauds" id="serialPortBauds" value="9600" />
<label for="serialPortDataBits">Data Bits:</label>
<input type="text" name="serialPortDataBits" id="serialPortDataBits" value="8" />
</td>
<td style="width:30px;"></td>
<td valign="top">
<label for="serialPortParity">Parity:</label>
<select id="serialPortParity" name="serialPortParity">
<option selected="selected">None</option>
<option>Odd</option>
<option>Even</option>
<option>Mark</option>
<option>Space</option>
</select>
<label for="serialPortStopBits">Stop Bits:</label>
<select id="serialPortStopBits" name="serialPortStopBits">
<option selected="selected">One</option>
<option>Two</option>
<option>OnePointFive</option>
</select>
<label for="serialPortFlowControl">Flow Control:</label>
<select id="serialPortFlowControl" name="serialPortFlowControl">
<option selected="selected">None</option>
<option>XOnXOff</option>
<option>RequestToSend</option>
<option>RequestToSendXOnXOff</option>
</select>
</td>
</tr>
</table>
</div>
</fieldset>
<fieldset>
<legend>Printer Commands</legend>
<p>
Enter the printer's commands you want to send and is supported by the specified printer (ESC/P, PCL, ZPL, EPL, DPL, IPL, EZPL, etc).
<br /><br />
<b>NOTE:</b> You can use the <b>hex notation of VB or C# for non-printable characters</b> e.g. for Carriage Return (ASCII 13) you could use &H0D or 0x0D
</p>
<textarea id="printerCommands" name="printerCommands" rows="10" cols="80" class="form-control" style="min-width: 100%"></textarea>
<br /><br />
<div class="alert alert-info" style="font-size:11px;">
<b>Upload Files</b><br />
This online demo does not allow you to upload files. So, if you have a file containing the printer commands like a PRN file, Postscript, PCL, ZPL, etc, then we recommend you to <a href="//neodynamic.com/products/printing/raw-data/aspnet-core/download/" target="_blank">download WebClientPrint</a> and test it by using the sample source code included in the package. Feel free to <a href="http://www.neodynamic.com/support" target="_blank">contact our Tech Support</a> for further assistance, help, doubts or questions.
</div>
</fieldset>
<fieldset>
<legend>Ready to print!</legend>
<h3>Your settings were saved! Now it's time to <a href="#" onclick="javascript:doClientPrint();" class="btn btn-large btn-success">Print</a></h3>
<br /><br />
</fieldset>
</form>
</div>
</div>
<br />
<br />
<br />
@section scripts {
@* Register the WebClientPrint script code generated by DemoPrintCommandsController. *@
@Html.Raw(ViewData["WCPScript"]);
<script type="text/javascript">
function doClientPrint() {
//collect printer settings and raw commands
var printerSettings = $("#myForm").serialize();
//store printer settings in the server cache...
$.post('DemoPrintCommands/ClientPrinterSettings',
printerSettings
);
// Launch WCPP at the client side for printing...
var sessionId = $("#sid").val();
jsWebClientPrint.print('sid=' + sessionId);
}
$(document).ready(function () {
//jQuery-based Wizard
$("#myForm").formToWizard();
//change printer options based on user selection
$("#pid").change(function () {
var printerId = $("select#pid").val();
displayInfo(printerId);
hidePrinters();
if (printerId == 2)
$("#installedPrinter").show();
else if (printerId == 3)
$("#netPrinter").show();
else if (printerId == 4)
$("#parallelPrinter").show();
else if (printerId == 5)
$("#serialPrinter").show();
});
hidePrinters();
displayInfo(0);
});
function displayInfo(i) {
if (i == 0)
$("#info").html('This will make the WCPP to send the commands to the printer installed in your machine as "Default Printer" without displaying any dialog!');
else if (i == 1)
$("#info").html('This will make the WCPP to display the Printer dialog so you can select which printer you want to use.');
else if (i == 2)
$("#info").html('Please specify the <b>Printer\'s Name</b> as it figures installed under your system.');
else if (i == 3)
$("#info").html('Please specify the Network Printer info.<br /><strong>On Linux & Mac</strong> it\'s recommended you install the printer through <strong>CUPS</strong> and set the assigned printer name to the <strong>"Use an installed Printer"</strong> option on this demo.');
else if (i == 4)
$("#info").html('Please specify the Parallel Port which your printer is connected to.<br /><strong>On Linux & Mac</strong> you must install the printer through <strong>CUPS</strong> and set the assigned printer name to the <strong>"Use an installed Printer"</strong> option on this demo.');
else if (i == 5)
$("#info").html('Please specify the Serial RS232 Port info which your printer does support.<br /><strong>On Linux & Mac</strong> you must install the printer through <strong>CUPS</strong> and set the assigned printer name to the <strong>"Use an installed Printer"</strong> option on this demo.');
}
function hidePrinters() {
$("#installedPrinter").hide(); $("#netPrinter").hide(); $("#parallelPrinter").hide(); $("#serialPrinter").hide();
}
/* FORM to WIZARD */
/* Created by jankoatwarpspeed.com */
(function ($) {
$.fn.formToWizard = function () {
var element = this;
var steps = $(element).find("fieldset");
var count = steps.size();
// 2
$(element).before("<ul id='steps'></ul>");
steps.each(function (i) {
$(this).wrap("<div id='step" + i + "'></div>");
$(this).append("<p id='step" + i + "commands'></p>");
// 2
var name = $(this).find("legend").html();
$("#steps").append("<li id='stepDesc" + i + "'>Step " + (i + 1) + "<span>" + name + "</span></li>");
if (i == 0) {
createNextButton(i);
selectStep(i);
}
else if (i == count - 1) {
$("#step" + i).hide();
createPrevButton(i);
}
else {
$("#step" + i).hide();
createPrevButton(i);
createNextButton(i);
}
});
function createPrevButton(i) {
var stepName = "step" + i;
$("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Prev' class='prev btn btn-info'>< Back</a>");
$("#" + stepName + "Prev").bind("click", function (e) {
$("#" + stepName).hide();
$("#step" + (i - 1)).show();
selectStep(i - 1);
});
}
function createNextButton(i) {
var stepName = "step" + i;
$("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next btn btn-info'>Next ></a>");
$("#" + stepName + "Next").bind("click", function (e) {
$("#" + stepName).hide();
$("#step" + (i + 1)).show();
selectStep(i + 1);
});
}
function selectStep(i) {
$("#steps li").removeClass("current");
$("#stepDesc" + i).addClass("current");
}
}
})(jQuery);
</script>
}
Now Run the application again and navigate to Samples.
Click on Print Raw Commands, this will provide us with 3 easy steps to print a document. We can follow the steps and print the document easily.
Now let’s create another controller for Print Files and name it as “DemoPrintFileController” and the following code in it:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting;
using Neodynamic.SDK.Web;
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace TestWebClientPrint.Controllers
{
public class DemoPrintFileController : Controller
{
// GET: /<controller>/
private readonly IHostingEnvironment _hostEnvironment;
public DemoPrintFileController(IHostingEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
public IActionResult Index()
{
ViewData["WCPScript"] = Neodynamic.SDK.Web.WebClientPrint.CreateScript(Url.Action("ProcessRequest", "WebClientPrintAPI", null, Url.ActionContext.HttpContext.Request.Scheme), Url.Action("PrintFile", "DemoPrintFile", null, Url.ActionContext.HttpContext.Request.Scheme), Url.ActionContext.HttpContext.Session.Id);
return View();
}
public IActionResult PrintFile(string useDefaultPrinter, string printerName, string fileType)
{
string fileName = Guid.NewGuid().ToString("N") + "." + fileType;
string filePath = null;
switch (fileType)
{
case "PDF":
filePath = "/files/LoremIpsum.pdf";
break;
case "TXT":
filePath = "/files/LoremIpsum.txt";
break;
case "DOC":
filePath = "/files/LoremIpsum.doc";
break;
case "XLS":
filePath = "/files/SampleSheet.xls";
break;
case "JPG":
filePath = "/files/penguins300dpi.jpg";
break;
case "PNG":
filePath = "/files/SamplePngImage.png";
break;
case "TIF":
filePath = "/files/patent2pages.tif";
break;
}
if (filePath != null)
{
PrintFile file = new PrintFile(_hostEnvironment.ContentRootPath + filePath, fileName);
ClientPrintJob cpj = new ClientPrintJob();
cpj.PrintFile = file;
if (useDefaultPrinter == "checked" || printerName == "null")
cpj.ClientPrinter = new DefaultPrinter();
else
cpj.ClientPrinter = new InstalledPrinter(System.Net.WebUtility.UrlDecode(printerName));
return File(cpj.GetContent(), "application/octet-stream");
}
else
{
return BadRequest("File not found!");
}
}
}
}
Now lets create a view page for this controller too. Go Views folder and create a new folder named “DemoPrintFile” and create a view page “Index.cshtml’ and add the following code in it:
@{
ViewData["Title"] = "Printing Files";
}
<div class="container">
<div class="row">
<h3>Print File without displaying any Print dialog! <small>(if needed)</small></h3>
<p>
With <strong>WebClientPrint for ASP.NET Core</strong> you can <strong>print most common file formats</strong> <em>(PDF, TXT, DOC/X, XLS/X, JPG/JPEG, PNG, TIF/TIFF)</em> right to any installed printer at the client side.
</p>
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne" class="btn btn-info btn-lg">
Client System Requirements
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr style="background-color:#ececec; font-weight:bold;color:#666">
<td style="width:20%">File Format</td>
<td style="width:40%">Windows Clients</td>
<td style="width:40%">Linux, RPi & Mac Clients</td>
</tr>
</thead>
<tbody>
<tr>
<td>DOC, DOCX</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> Microsoft Word is required</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> LibreOffice is required</td>
</tr>
<tr>
<td>XLS, XLSX</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> Microsoft Excel is required</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> LibreOffice is required</td>
</tr>
<tr>
<td>PDF</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> Adobe Acrobat or Foxit Reader is required</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
</tr>
<tr>
<td>TXT</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> Notepad is required</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
</tr>
<tr>
<td>JPEG</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
</tr>
<tr>
<td>PNG</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
</tr>
<tr>
<td>BMP</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> Natively supported!</td>
</tr>
<tr>
<td>Printer Support</td>
<td><span class="badge alert-warning"><i class="glyphicon glyphicon-info-sign"></i></span> You can print files to local installed printers ONLY! Parallel, Serial and IP/Ethernet printers are NOT supported.</td>
<td><span class="badge alert-success"><i class="glyphicon glyphicon-ok-sign"></i></span> You can print files to any installed printers through CUPS system.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingTwo">
<h4 class="panel-title">
<a class="collapsed btn btn-info btn-lg" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Test Printing Now!
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
<div class="panel-body">
<p>
The following are pre-selected files to test WebClientPrint File Printing feature.
</p>
<div class="row">
<div class="col-md-4 col-md-offset-2">
<hr />
<label class="checkbox">
<input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> or...
</label>
<div id="loadPrinters">
Click to load and select one of the installed printers!
<br />
<a onclick="javascript:jsWebClientPrint.getPrinters();" class="btn btn-success">Load installed printers...</a>
<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 = 5000; //5 sec
var wcppGetPrintersTimeout_ms = 10000; //10 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>
</div>
<div class="col-md-4">
<hr />
<div id="fileToPrint">
<label for="ddlFileType">Select a sample File to print:</label>
<select id="ddlFileType">
<option>PDF</option>
<option>TXT</option>
<option>DOC</option>
<option>XLS</option>
<option>JPG</option>
<option>PNG</option>
<option>TIF</option>
</select>
<br />
<a class="btn btn-info btn-large" onclick="javascript:jsWebClientPrint.print('useDefaultPrinter=' + $('#useDefaultPrinter').attr('checked') + '&printerName=' + $('#installedPrinterName').val() + '&filetype=' + $('#ddlFileType').val());">Print File...</a>
</div>
</div>
</div>
<h5>File Preview</h5>
<iframe id="ifPreview" style="width:100%; height:500px;" frameborder="0"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
@section scripts {
@* Register the WebClientPrint script code generated by DemoPrintFileController. *@
@Html.Raw(ViewData["WCPScript"]);
<script type="text/javascript">
$("#ddlFileType").change(function () {
var s = $("#ddlFileType option:selected").text();
if (s == 'DOC') $("#ifPreview").attr("src", "http://docs.google.com/gview?url=http://webclientprint.azurewebsites.net/files/LoremIpsum.doc&embedded=true");
if (s == 'PDF') $("#ifPreview").attr("src", "http://docs.google.com/gview?url=http://webclientprint.azurewebsites.net/files/LoremIpsum.pdf&embedded=true");
if (s == 'TXT') $("#ifPreview").attr("src", "http://docs.google.com/gview?url=http://webclientprint.azurewebsites.net/files/LoremIpsum.txt&embedded=true");
if (s == 'TIF') $("#ifPreview").attr("src", "http://docs.google.com/gview?url=http://webclientprint.azurewebsites.net/files/patent2pages.tif&embedded=true");
if (s == 'XLS') $("#ifPreview").attr("src", "http://docs.google.com/gview?url=http://webclientprint.azurewebsites.net/files/SampleSheet.xls&embedded=true");
if (s == 'JPG') $("#ifPreview").attr("src", "http://webclientprint.azurewebsites.net/files/penguins300dpi.jpg");
if (s == 'PNG') $("#ifPreview").attr("src", "http://webclientprint.azurewebsites.net/files/SamplePngImage.png");
}).change();
</script>
}
Now again run the application and navigate to samples and then click on Print File
Here, there are the list of formats supported for printing. Now click on Test Printing Now:
Here we can load the printers and select file format and at last click on Print to print the page.