I ended up implementing QZ Tray 2.0.4 the free version .
By modifying the code available on the test page I was able to correctly implement the stickers printing through the browser 1 .
NOTE : If you plan to use this code, you should keep in mind that (also
to install QZ Tray 2.0.4 and modify the code to establish
correctly references to the scripts) the configuration should be
correct and that the "QZ Tray 2.0.4" application is in
execution; besides having the printer of your preference
set to default printer ; as well as allowing QZ Tray to communicate with the assigned localhost.
The following code has been adapted from the test page, but there is more information on the official page according to the type of printing to be generated :
<!-- Scripts requeridos -->
<script type="text/javascript" src="/js/dependencies/rsvp-3.1.0.min.js"></script>
<script type="text/javascript" src="/js/dependencies/sha-256.min.js"></script>
<script type="text/javascript" src="/js/qz-tray.js"></script>
<script type="text/javascript">
/// Uso esta función en el evento "onclick" de un botón.
function printStuff() {
// Crea una conexión a la impresora predefinida "según configuración del equipo del usuario".
var config = getUpdatedConfig();
// Valores de prueba.
var data = ['Raw Data\n', 'More Raw Data\n', 'Even More Raw Data\n'];
// Imprimir.
qz.print(config, data).catch(function(e) { console.error(e); });
}
/// Authentication setup ///
qz.security.setCertificatePromise(function(resolve, reject) {
//Preferred method - from server
//$.ajax("assets/signing/digital-certificate.txt").then(resolve, reject);
//Alternate method 1 - anonymous
//resolve();
//Alternate method 2 - direct
resolve("-----BEGIN CERTIFICATE-----\n" +
"MIIFAzCCAuugAwIBAgICEAIwDQYJKoZIhvcNAQEFBQAwgZgxCzAJBgNVBAYTAlVT\n" +
"MQswCQYDVQQIDAJOWTEbMBkGA1UECgwSUVogSW5kdXN0cmllcywgTExDMRswGQYD\n" +
"VQQLDBJRWiBJbmR1c3RyaWVzLCBMTEMxGTAXBgNVBAMMEHF6aW5kdXN0cmllcy5j\n" +
"b20xJzAlBgkqhkiG9w0BCQEWGHN1cHBvcnRAcXppbmR1c3RyaWVzLmNvbTAeFw0x\n" +
"NTAzMTkwMjM4NDVaFw0yNTAzMTkwMjM4NDVaMHMxCzAJBgNVBAYTAkFBMRMwEQYD\n" +
"VQQIDApTb21lIFN0YXRlMQ0wCwYDVQQKDAREZW1vMQ0wCwYDVQQLDAREZW1vMRIw\n" +
"EAYDVQQDDAlsb2NhbGhvc3QxHTAbBgkqhkiG9w0BCQEWDnJvb3RAbG9jYWxob3N0\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtFzbBDRTDHHmlSVQLqjY\n" +
"aoGax7ql3XgRGdhZlNEJPZDs5482ty34J4sI2ZK2yC8YkZ/x+WCSveUgDQIVJ8oK\n" +
"D4jtAPxqHnfSr9RAbvB1GQoiYLxhfxEp/+zfB9dBKDTRZR2nJm/mMsavY2DnSzLp\n" +
"t7PJOjt3BdtISRtGMRsWmRHRfy882msBxsYug22odnT1OdaJQ54bWJT5iJnceBV2\n" +
"1oOqWSg5hU1MupZRxxHbzI61EpTLlxXJQ7YNSwwiDzjaxGrufxc4eZnzGQ1A8h1u\n" +
"jTaG84S1MWvG7BfcPLW+sya+PkrQWMOCIgXrQnAsUgqQrgxQ8Ocq3G4X9UvBy5VR\n" +
"CwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl\n" +
"bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUpG420UhvfwAFMr+8vf3pJunQ\n" +
"gH4wHwYDVR0jBBgwFoAUkKZQt4TUuepf8gWEE3hF6Kl1VFwwDQYJKoZIhvcNAQEF\n" +
"BQADggIBAFXr6G1g7yYVHg6uGfh1nK2jhpKBAOA+OtZQLNHYlBgoAuRRNWdE9/v4\n" +
"J/3Jeid2DAyihm2j92qsQJXkyxBgdTLG+ncILlRElXvG7IrOh3tq/TttdzLcMjaR\n" +
"8w/AkVDLNL0z35shNXih2F9JlbNRGqbVhC7qZl+V1BITfx6mGc4ayke7C9Hm57X0\n" +
"ak/NerAC/QXNs/bF17b+zsUt2ja5NVS8dDSC4JAkM1dD64Y26leYbPybB+FgOxFu\n" +
"wou9gFxzwbdGLCGboi0lNLjEysHJBi90KjPUETbzMmoilHNJXw7egIo8yS5eq8RH\n" +
"i2lS0GsQjYFMvplNVMATDXUPm9MKpCbZ7IlJ5eekhWqvErddcHbzCuUBkDZ7wX/j\n" +
"unk/3DyXdTsSGuZk3/fLEsc4/YTujpAjVXiA1LCooQJ7SmNOpUa66TPz9O7Ufkng\n" +
"+CoTSACmnlHdP7U9WLr5TYnmL9eoHwtb0hwENe1oFC5zClJoSX/7DRexSJfB7YBf\n" +
"vn6JA2xy4C6PqximyCPisErNp85GUcZfo33Np1aywFv9H+a83rSUcV6kpE/jAZio\n" +
"5qLpgIOisArj1HTM6goDWzKhLiR/AeG3IJvgbpr9Gr7uZmfFyQzUjvkJ9cybZRd+\n" +
"G8azmpBBotmKsbtbAU/I/LVk8saeXznshOVVpDRYtVnjZeAneso7\n" +
"-----END CERTIFICATE-----\n" +
"--START INTERMEDIATE CERT--\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIFEjCCA/qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgawxCzAJBgNVBAYTAlVT\n" +
"MQswCQYDVQQIDAJOWTESMBAGA1UEBwwJQ2FuYXN0b3RhMRswGQYDVQQKDBJRWiBJ\n" +
"bmR1c3RyaWVzLCBMTEMxGzAZBgNVBAsMElFaIEluZHVzdHJpZXMsIExMQzEZMBcG\n" +
"A1UEAwwQcXppbmR1c3RyaWVzLmNvbTEnMCUGCSqGSIb3DQEJARYYc3VwcG9ydEBx\n" +
"emluZHVzdHJpZXMuY29tMB4XDTE1MDMwMjAwNTAxOFoXDTM1MDMwMjAwNTAxOFow\n" +
"gZgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTEbMBkGA1UECgwSUVogSW5kdXN0\n" +
"cmllcywgTExDMRswGQYDVQQLDBJRWiBJbmR1c3RyaWVzLCBMTEMxGTAXBgNVBAMM\n" +
"EHF6aW5kdXN0cmllcy5jb20xJzAlBgkqhkiG9w0BCQEWGHN1cHBvcnRAcXppbmR1\n" +
"c3RyaWVzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTDgNLU\n" +
"iohl/rQoZ2bTMHVEk1mA020LYhgfWjO0+GsLlbg5SvWVFWkv4ZgffuVRXLHrwz1H\n" +
"YpMyo+Zh8ksJF9ssJWCwQGO5ciM6dmoryyB0VZHGY1blewdMuxieXP7Kr6XD3GRM\n" +
"GAhEwTxjUzI3ksuRunX4IcnRXKYkg5pjs4nLEhXtIZWDLiXPUsyUAEq1U1qdL1AH\n" +
"EtdK/L3zLATnhPB6ZiM+HzNG4aAPynSA38fpeeZ4R0tINMpFThwNgGUsxYKsP9kh\n" +
"0gxGl8YHL6ZzC7BC8FXIB/0Wteng0+XLAVto56Pyxt7BdxtNVuVNNXgkCi9tMqVX\n" +
"xOk3oIvODDt0UoQUZ/umUuoMuOLekYUpZVk4utCqXXlB4mVfS5/zWB6nVxFX8Io1\n" +
"9FOiDLTwZVtBmzmeikzb6o1QLp9F2TAvlf8+DIGDOo0DpPQUtOUyLPCh5hBaDGFE\n" +
"ZhE56qPCBiQIc4T2klWX/80C5NZnd/tJNxjyUyk7bjdDzhzT10CGRAsqxAnsjvMD\n" +
"2KcMf3oXN4PNgyfpbfq2ipxJ1u777Gpbzyf0xoKwH9FYigmqfRH2N2pEdiYawKrX\n" +
"6pyXzGM4cvQ5X1Yxf2x/+xdTLdVaLnZgwrdqwFYmDejGAldXlYDl3jbBHVM1v+uY\n" +
"5ItGTjk+3vLrxmvGy5XFVG+8fF/xaVfo5TW5AgMBAAGjUDBOMB0GA1UdDgQWBBSQ\n" +
"plC3hNS56l/yBYQTeEXoqXVUXDAfBgNVHSMEGDAWgBQDRcZNwPqOqQvagw9BpW0S\n" +
"BkOpXjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAJIO8SiNr9jpLQ\n" +
"eUsFUmbueoxyI5L+P5eV92ceVOJ2tAlBA13vzF1NWlpSlrMmQcVUE/K4D01qtr0k\n" +
"gDs6LUHvj2XXLpyEogitbBgipkQpwCTJVfC9bWYBwEotC7Y8mVjjEV7uXAT71GKT\n" +
"x8XlB9maf+BTZGgyoulA5pTYJ++7s/xX9gzSWCa+eXGcjguBtYYXaAjjAqFGRAvu\n" +
"pz1yrDWcA6H94HeErJKUXBakS0Jm/V33JDuVXY+aZ8EQi2kV82aZbNdXll/R6iGw\n" +
"2ur4rDErnHsiphBgZB71C5FD4cdfSONTsYxmPmyUb5T+KLUouxZ9B0Wh28ucc1Lp\n" +
"rbO7BnjW\n" +
"-----END CERTIFICATE-----\n");
});
qz.security.setSignaturePromise(function(toSign) {
return function(resolve, reject) {
//Preferred method - from server
//$.ajax("/secure/url/for/sign-message?request=" + toSign).then(resolve, reject);
//Alternate method - unsigned
resolve();
};
});
/// Connection ///
function launchQZ() {
if (!qz.websocket.isActive()) {
window.location.assign("qz:launch");
//Retry 5 times, pausing 1 second between each attempt
startConnection({ retries: 5, delay: 1 });
}
}
function startConnection(config) {
if (!qz.websocket.isActive()) {
qz.websocket.connect(config).then(function() {
findDefaultPrinter(true); /* Instead of findVersion(); */
}).catch(handleConnectionError);
} else {
displayAlert('An active connection with QZ already exists.');
}
}
function endConnection() {
if (qz.websocket.isActive()) {
qz.websocket.disconnect().then(function() {
alert('Desconectado');
}).catch(handleConnectionError);
} else {
displayAlert('No active connection with QZ exists. Openinig a new one.');
startConnection();
}
}
// Recargar la página para iniciar la conexión.
function restartConnection() {
startConnection({ retries: 5, delay: 1 });
}
/// Detection ///
function findDefaultPrinter(set) {
qz.printers.getDefault().then(function(data) {
displayAlert("La impresora (" + data + ") ha sido encontrada.\nAhora puede proceder a imprimir stickers.");
if (set) { setPrinter(data); }
}).catch(createConsoleLog);
}
/// Raw Printers ///
function printEPL() {
var config = getUpdatedConfig();
/* Información de prueba. */
var printData = [
'\nN\n',
'q609\n',
'Q203,26\n',
'B5,26,0,1A,3,7,152,B,"1234"\n',
'A310,26,0,3,1,1,N,"SKU 00000 MFG 0000"\n',
'A310,56,0,3,1,1,N,"QZ PRINT APPLET"\n',
'A310,86,0,3,1,1,N,"TEST PRINT SUCCESSFUL"\n',
'A310,116,0,3,1,1,N,"FROM SAMPLE.HTML"\n',
'A310,146,0,3,1,1,N,"QZ.IO"\n',
'\nP1,1\n'
];
qz.print(config, printData).catch(createConsoleLog);
}
/// Page load ///
$(document).ready(function() {
window.readingWeight = false;
startConnection();
// ¡La conexión con la impresora se establece cuando la conexión sea exitosa!
alert('============================================\n' +
' Iniciando conexión con QZ Tray software.\n' +
'============================================\n' +
'Para usar la impresión de stickers, debe tener instalado el programa\n' +
'QZ Tray 2.0.4\n\n' +
'QZ Tray 2.0.4 procederá a detectar la impresora predeterminada.\n\n' +
'Acepte las solicitudes que se muestra a continuación y\n' +
'Espere a que se muestre el nombre de la impresora detectada.');
});
qz.websocket.setClosedCallbacks(function(evt) {
console.log(evt);
if (evt.reason) {
displayAlert("Connection closed:" + evt.reason);
}
});
qz.websocket.setErrorCallbacks(handleConnectionError);
/// Helpers ///
function handleConnectionError(err) {
if (err.target != undefined) {
if (err.target.readyState >= 2) { //if CLOSING or CLOSED
createConsoleLog("Connection to QZ Tray was closed");
} else {
createConsoleLog("A connection error occurred, check log for details");
console.error(err);
}
} else {
createConsoleLog(err);
}
}
function createConsoleLog(err) {
console.error(err);
displayAlert(err);
}
function displayAlert(msg, css) {
alert(msg);
}
/// QZ Config ///
var cfg = null;
function getUpdatedConfig() {
if (cfg == null) {
cfg = qz.configs.create(null);
}
updateConfig();
return cfg
}
// Los parámetros estarán como "undefined" ya que no existen en mi código final.
function updateConfig() {
var pxlSize = null;
var pxlMargins = $("#pxlMargins").val(); // = undefined.
var jobName = "Impresión Sticker";
cfg.reconfigure({
altPrinting: $("#rawAltPrinting").prop('checked'),
encoding: $("#rawEncoding").val(),
endOfDoc: $("#rawEndOfDoc").val(),
perSpool: $("#rawPerSpool").val(),
colorType: $("#pxlColorType").val(),
copies: 1,
density: $("#pxlDensity").val(),
duplex: $("#pxlDuplex").prop('checked'),
interpolation: $("#pxlInterpolation").val(),
jobName: jobName,
margins: pxlMargins,
orientation: $("#pxlOrientation").val(),
paperThickness: $("#pxlPaperThickness").val(),
printerTray: $("#pxlPrinterTray").val(),
rasterize: $("#pxlRasterize").prop('checked'),
rotation: $("#pxlRotation").val(),
scaleContent: $("#pxlScale").prop('checked'),
size: pxlSize,
units: $("input[name='pxlUnits']:checked").val()
});
}
function setPrinter(printer) {
var cf = getUpdatedConfig();
cf.setPrinter(printer);
}
</script>
<!--FIN-->
1 Tests in Google Chrome Version 60.0.3112.90 (Official build) (64 bits).