How to generate and print advanced ZPL commands from Javascript and ThermalLabel Web API
Product JSPrintManager Published 02/02/2021 Updated 08/01/2022 Author Neodynamic
Overview
In this article, you'll learn how to generate and print advanced ZPL commands from Javascript directly to the client printer without displaying a print dialog at all. You'll be able to print advanced ZPL commands to the Default client printer as well as to any other installed printer at the client machine. This solution works with any popular browser like Chrome, Firefox, IE/Edge & Safari on Windows, Linux, Raspberry Pi and Mac systems!
If you don't know how to write advanced ZPL commands, then you can take advantage of our On-premise ThermalLabel Web API for Docker to generate the advanced ZPL commands by writing simple and dev-friendly Javascript code to finally print it from any Web Platform/Framework you use (ASP.NET, PHP, Django, Ruby On Rails (RoR), Express.js, AngularJS/SPA, etc.) right to the client printer through JSPrintManager solution.
ThermalLabel Web API for Docker is a on-premise REST API available as a Linux Docker image that you can host and run anywhere i.e. locally or in the cloud.
AVAILABLE DISCOUNT If you find this API usefull then we're providing a great discount for buying it bundled with JSPrintManager. Please contact sales team for further details.
In this article we'll generate and print out a simple label that will look like this:
Follow up these steps
-
JSPrintManager Client App
Be sure you install in your dev machine JSPrintManager (JSPM) (Available for Windows, Linux, Raspberry Pi & Mac)
IMPORTANT: This small app must be installed on each client! -
HTML & Script References
- Download and run the ThermalLabel Web API for Docker image. In the source code below, we'll suppose that the URL to access it is
https://localhost:8080
(change it in the code below if you are running the Docker image under another URL) - Download JSPrintManager.js
- Download cptable.js & cputils.js
- Copy all of these *.js files to the same folder where the next
index.html
page sample will be located in. - By using your favorite Web Development IDE or Text Editor, create a new HTML file naming it
index.html
Copy/paste the following code inside that html file:
<!DOCTYPE html> <html> <head> <title>JSPrintManager</title> <meta charset="utf-8" /> </head> <body> <div style="text-align:center"> <h1>Print Advanced Zebra ZPL Commands From ThermalLabel Web API</h1> <hr /> <label class="checkbox"> <input type="checkbox" id="useDefaultPrinter" /> <strong>Print to Default printer</strong> </label> <p>or...</p> <div id="installedPrinters"> <label for="installedPrinterName">Select an installed Printer:</label> <select name="installedPrinterName" id="installedPrinterName"></select> </div> <br /><br /> <button onclick="printLabel();">Print Now...</button> </div> <script src="scripts/JSPrintManager.js"></script> <script> // The URL to the ThermalLabel Web API instance const API_URL = 'https://localhost:8080'; // the label items objs var myBarcode = null; var myText = null; var myImage = null; var myThermalLabel = null; // http request obj for API comm var request = new XMLHttpRequest(); // a generic func to request the API function reqApi(objUrl, method, acceptHeader, reqType, respType, data) { return new Promise(function (resolve, reject) { const URL = API_URL + objUrl; request.open(method, URL); if (respType) request.responseType = respType; if (reqType) request.setRequestHeader('Content-Type', reqType); if (acceptHeader) request.setRequestHeader('Accept', acceptHeader); request.onload = function () { if (this.status === 200) { resolve(this.response); } else { reject(Error(request.statusText)); } } if (data) request.send(data); else request.send(); }); } // JSPM WebSocket settings JSPM.JSPrintManager.auto_reconnect = true; JSPM.JSPrintManager.start(); JSPM.JSPrintManager.WS.onStatusChanged = function () { if (jspmWSStatus()) { // get client installed printers JSPM.JSPrintManager.getPrinters().then(function (myPrinters) { var options = ''; for (var i = 0; i < myPrinters.length; i++) { options += '<option>' + myPrinters[i] + '</option>'; } //$('#installedPrinterName').html(options); document.getElementById('installedPrinterName').innerHTML = options; }); } }; // Check JSPM WebSocket status function jspmWSStatus() { if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Open) return true; else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Closed) { alert('JSPrintManager (JSPM) is not installed or not running! Download JSPM Client App from https://neodynamic.com/downloads/jspm'); return false; } else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Blocked) { alert('JSPM has blocked this website!'); return false; } } // Do printing... function printLabel() { if (jspmWSStatus()) { // create a BarcodeItem obj reqApi('/Items/BarcodeItem', 'GET', null, null, 'json').then(function (response) { console.log(response); myBarcode = response; // create a TextItem obj reqApi('/Items/TextItem', 'GET', null, null, 'json').then(function (response) { console.log(response); myText = response; // create an ImageItem obj reqApi('/Items/ImageItem', 'GET', null, null, 'json').then(function (response) { console.log(response); myImage = response; // create a ThermalLabel obj reqApi('/ThermalLabel', 'GET', null, null, 'json').then(function (response) { console.log(response); // COMPOSE the label positioning the different items created above // ThermalLabel settings myThermalLabel = response; // default unit is INCH myThermalLabel.width = 4; myThermalLabel.height = 3; myThermalLabel.gapLength = 0.05; // Image settings myImage.x = 0.1; myImage.y = 0.1; myImage.width = 2.66; myImage.height = 0.72; myImage.sourceBase64 = "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"; // Text settings myText.x = 0.1; myText.y = 1; myText.width = 3; myText.height = 0.25; myText.text = "Sample Text 1234567890"; myText.font.name = "ZPL Font 0"; myText.font.size = 14; // Barcode settings myBarcode.x = 0.1; myBarcode.y = 1.5; myBarcode.width = 1; myBarcode.height = 1; myBarcode.sizing = "FitProportional"; myBarcode.symbology = "QRCode"; myBarcode.code = "Data to encode here"; // add items to the label myThermalLabel.items = []; myThermalLabel.items.push(myImage); myThermalLabel.items.push(myText); myThermalLabel.items.push(myBarcode); console.log(myThermalLabel); let convertParam = {}; convertParam["thermalLabel"] = JSON.stringify(myThermalLabel); convertParam["dpi"] = 203; console.log(convertParam); // convert label to ZPL commands!!! reqApi('/ThermalLabel/Convert', 'POST', 'application/vnd.zpl', 'application/json', 'arraybuffer', JSON.stringify(convertParam)).then(function (response) { console.log(response); // Create a ClientPrintJob for printing the ZPL commands var cpj = new JSPM.ClientPrintJob(); // Set Printer type (Refer to the help, there are many of them!) var useDefPrinter = document.getElementById("useDefaultPrinter").checked; if (useDefPrinter) { cpj.clientPrinter = new JSPM.DefaultPrinter(); } else { var pn = document.getElementById("installedPrinterName"); var printerName = pn.options[pn.selectedIndex].text; cpj.clientPrinter = new JSPM.InstalledPrinter(printerName); } // Set printer commands... cpj.binaryPrinterCommands = new Uint8Array(response); // Send print job to printer! cpj.sendToClient(); }, function (Error) { console.log(Error); }); }, function (Error) { console.log(Error); }); }, function (Error) { console.log(Error); }); }, function (Error) { console.log(Error); }); }, function (Error) { console.log(Error); }); } } </script> </body> </html>
- Download and run the ThermalLabel Web API for Docker image. In the source code below, we'll suppose that the URL to access it is
- That's it! Run your website and test it.