How to trace Print Jobs Statues from Javascript
Product JSPrintManager Published 06/26/2020 Updated 05/02/2024 Author Neodynamic
Overview
In this walkthrough, you'll learn how to trace print jobs status from Javascript and get notified whether the print job completed, number of printed pages, and many more related information.
JSPrintManager allows you to trace print jobs status when targeting any installed client printers.
Try reproducing the following sample code locally...
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 JSPrintManager.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:
<!XLSTYPE html> <html> <head> <title>JSPrintManager</title> <meta charset="utf-8" /> </head> <body> <div style="text-align:center"> <h1>Print Job Status/Trace from Javascript</h1> <hr /> <fieldset> <legend><strong>File to print (try an Image or PDF)</strong></legend> <label> Local file: <input id="input-local-file" type="file" /> </label> <br /><br /> <strong>OR...</strong> <br /><br /> <label> File from URL <span> (e.g. <a href="https://neodynamic.com/temp/penguins300dpi.jpg" target="_blank"> https://neodynamic.com/temp/penguins300dpi.jpg </a>) </span> <input id="input-file-url" /> </label> </fieldset> <br /><br /> <fieldset> <legend><strong>Target Printer</strong></legend> <label>Printer:</label> <select id="printerName"> </select> </fieldset> <br /><br /> <fieldset> <legend><strong>Print Job Trace</strong></legend> <textarea id="txtPrintJobTrace" readOnly rows="30" cols="200" style="font-family:Courier New, Courier, monospace"></textarea> </fieldset> <br /> <button onclick="doPrinting();"><h2>Print File Now...</h2></button> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <script src="scripts/JSPrintManager.js"></script> <script> var clientPrinters = null; var _this = this; //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 (printersList) { clientPrinters = printersList; var options = ''; for (var i = 0; i < clientPrinters.length; i++) { options += '<option>' + clientPrinters[i] + '</option>'; } $('#printerName').html(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) { console.warn('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 doPrinting() { if (jspmWSStatus()) { //create ClientPrintJob var cpj = new JSPM.ClientPrintJob(); //Set Printer info var myPrinter = new JSPM.InstalledPrinter($('#printerName').val()); cpj.clientPrinter = myPrinter; //Set file var local_file = $("#input-local-file").prop('files'); var my_file = null; var file_name; var file_ext; if (local_file && local_file.length > 0) { file_ext = local_file[0].name.substring(local_file[0].name.lastIndexOf('.')); file_name = local_file[0].name; if (file_ext == '.pdf') my_file = new JSPM.PrintFilePDF(local_file[0], JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.doc' || file_ext == '.docx') my_file = new JSPM.PrintFileDOC(local_file[0], JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.xls' || file_ext == '.xlsx') my_file = new JSPM.PrintFileXLS(local_file[0], JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.txt') my_file = new JSPM.PrintFileTXT(local_file[0], file_name, 1, JSPM.FileSourceType.BLOB); else my_file = new JSPM.PrintFile(local_file[0], JSPM.FileSourceType.BLOB, file_name, 1); } else if ($("#input-file-url").val().length > 0) { var file_url = $("#input-file-url").val(); file_ext = file_url.substring(file_url.lastIndexOf('.')); file_name = file_url.substring(file_url.lastIndexOf('/') + 1); if (file_ext == '.pdf') my_file = new JSPM.PrintFilePDF($("#input-file-url").val(), JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.doc' || file_ext == '.docx') my_file = new JSPM.PrintFileDOC($("#input-file-url").val(), JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.xls' || file_ext == '.xlsx') my_file = new JSPM.PrintFileXLS($("#input-file-url").val(), JSPM.FileSourceType.BLOB, file_name, 1); else if (file_ext == '.txt') my_file = new JSPM.PrintFileTXT($("#input-file-url").val(), file_name, 1, JSPM.FileSourceType.BLOB); else my_file = new JSPM.PrintFile($("#input-file-url").val(), JSPM.FileSourceType.ExternalURL, file_name, 1); } else { alert('Must specify a local file or a URL!'); return; } //add file to ClientPrintJob cpj.files.push(my_file); /* CPJ Events */ cpj.jobInfo = { states: "", printedPages: 0, printedBytes: 0, totalPages: 0, totalBytes: 0 }; //Handle print job events cpj.onUpdated = function (data) { $("#txtPrintJobTrace").val($("#txtPrintJobTrace").val() + "> " + JSON.stringify(data) + "\r\n"); console.info(data); if (data.id) { if (data['completed-pages'] && data['completed-pages'] > this.jobInfo.printedPages) this.jobInfo.printedPages = data['completed-pages']; if (data['total-pages'] && data['total-pages'] > this.jobInfo.totalPages) this.jobInfo.totalPages = data['total-pages']; if (data['total-bytes'] && data['total-bytes'] > this.jobInfo.totalBytes) this.jobInfo.totalBytes = data['total-bytes']; if (data['printed-bytes'] && data['printed-bytes'] > this.jobInfo.printedBytes) this.jobInfo.printedBytes = data['printed-bytes']; if (data['state-description']) this.jobInfo.states += ',' + data['state-description']; } if (data.result === "ClientPrintJob done") { // SOME SOURCES ABOUT THE MEANING OF SOME STATES // RETAINED: https://stackoverflow.com/q/26862882 // COMPLETE: https://learn.microsoft.com/en-us/dotnet/api/system.printing.printjobstatus let success = (this.jobInfo.totalBytes > 0 && this.jobInfo.printedBytes > 0 && this.jobInfo.printedBytes >= this.jobInfo.totalBytes) || (this.jobInfo.totalPages > 0 && this.jobInfo.printedPages > 0 && this.jobInfo.printedPages >= this.jobInfo.totalPages) || this.jobInfo.states.includes('PRINTED') || this.jobInfo.states.includes('RETAINED') || this.jobInfo.states.includes('COMPLETE'); if (success) { $("#txtPrintJobTrace").val($("#txtPrintJobTrace").val() + "> " + "Print success" + "\r\n"); console.log("Print success"); } else { $("#txtPrintJobTrace").val($("#txtPrintJobTrace").val() + "> " + "Print with error" + "\r\n"); console.log("Print with error"); } } }; cpj.onFinished = function (data) { $("#txtPrintJobTrace").val($("#txtPrintJobTrace").val() + "> " + JSON.stringify(data) + "\r\n"); console.info(data); }; //Send print job to printer! cpj.sendToClient(); } } </script> </body> </html>
- That's it! Run your website and test it.