Export to GitHub

jzebra - TutorialWebApplet.wiki


Tip: Hit and search this page for keywords!!

Introduction

This is a tutorial for web developers to add a web applet to your page capable of sending raw commands to your printer. This is common for Barcodes, Thermal Printing, Point-Of-Sales (POS), and other commercial/industry purposes.

This is possible by using JavaScript to talk to Java through the "Applet" interface that is provided by all major web browsers.

Download and extract a featured version. There's a bunch of files, but we'll primarily be using "sample.html". Also make sure "qz-print.jar" resides in the same folder/location.

https://jzebra.googlecode.com/files/unzip-screenshot.PNG

The sample runs client-side. No uploading to a web server is needed for this tutorial.

There are separate buttons for each type of printing, so study them closely. Behind each button is a small snippet of JavaScript code for interacting with the qz-print applet.

https://jzebra.googlecode.com/files/sample-html.PNG

| Note: qz-print requires Java 5 or higher to run. For help installing Java on your platform, see the Java tutorial. | |:--------------------------------------------------------------------------------------------------------------------------------------------------|

The steps below walk through adding an applet to your web page, and explain how to interact with it through JavaScript.


Steps

Load The Applet

  1. Make sure your printer is set up on your workstation with the name "zebra" (this can be changed later).
  2. Make sure printer is connected as a raw print queue for your operating sytem (Click the Windows, Ubuntu, or Mac logo for details)

    http://2.bp.blogspot.com/_9hmP3Ho0t14/SvXbEnoMELI/AAAAAAAAAT4/eF4xkJ68ALY/s400/config_end.png

  3. Download the latest version and extract the contents to your desktop. Open "sample.html" with a web browser.
    • The following applet code creates the applet. <html><body> <applet id="qz" name="QZ Print Plugin" code="qz.PrintApplet.class" archive="./qz-print.jar" width="100" height="100"></applet><br><br> </html></body>
    • The html file should reside in the same folder as qz-print.jar. Alternately, you can move the JAR to a different location so long as you change archive="./qz-print.jar" to match your new location.

      | Note: Java 7 + Apache users: Change apache config to use "SSLStrictSNIVHostCheck on" and restart apache. read more here https://bitbucket.org/StrangeWill/redmine-inline-attach-screenshot/issue/17/java-17-unrecognized_name-due-sni-support | |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Note: Chrome users may receive a message "The Java plug-in requires your permission to run". Click "Always run on this site"

      http://jzebra.googlecode.com/files/permission.jpg' />

Note: IE7 may receive an ActiveX warning. Click "Allow Blocked Content"

Note: IE7 may be prompt to Click to Activate This Control each time the applet loads. Click here for details.
  1. The applet will begin to load in the web page.
    Note: Chrome users on Linux with outdated plugins, launch chrome with "google-chrome --always-authorize-plugins --allow-outdated-plugins". This will allow Java to load in Chrome without warnings of outdated plugins!
    http://2.bp.blogspot.com/_9hmP3Ho0t14/SxgoGt3lmKI/AAAAAAAAAXA/jsqVvrlRl4k/s400/applet_loading.PNG
  2. Next, Java security dialog prompt is shown. Click "Run".
    https://jzebra.googlecode.com/files/trusted-warning.PNG
  3. The applet should be loaded. At this point it will look like a plain html page with a few sample buttons.
    https://jzebra.googlecode.com/files/sample-html.PNG
  4. Right click the Java system tray icon (Windows) and clicking "Open Java Console". Linux Oracle Java users run: jcontrol --> Advanced --> Java Console --> Show Console. Linux OpenJDK users, run the web browser from a command line.
    Note: The Java Console is critical for calibrating qz-print for your printer.
  5. You should see the version of qz-print "INFO: qz-print 1.x.x" followed by "===== JAVASCRIPT LISTENER THREAD STARTED =====" in the log. Sample:
           Java Plug-in 10.45.2.18
    Using JRE version 1.7.0_45-b18 Java HotSpot(TM) Client VM
    User home directory = %USERPROFILE%
    ----------------------------------------------------
    c: clear console window
    f: finalize objects on finalization queue
    g: garbage collect
    h: display this help message
    l: dump classloader list
    m: print memory usage
    o: trigger logging
    q: hide console
    r: reload policy configuration
    s: dump system and deployment properties
    t: dump thread list
    v: dump thread stack
    x: clear classloader cache
    0-5: set trace level to <n>
    ----------------------------------------------------
    Oct 19, 2013 1:40:05 AM qz.LogIt log
    INFO: QZ-PRINT 1.6.8
    Oct 19, 2013 1:40:05 AM qz.LogIt log
    INFO: ===== JAVASCRIPT LISTENER THREAD STARTED =====
    Oct 19, 2013 1:40:09 AM qz.LogIt log
    INFO: ===== SEARCHING FOR PRINTER =====
    Oct 19, 2013 1:40:10 AM qz.LogIt log
    INFO: Found 4 attached printers.
    Oct 19, 2013 1:40:10 AM qz.LogIt log
    INFO: Printer specified: \QZebra\E
    Oct 19, 2013 1:40:10 AM qz.LogIt log
    INFO: Printer name match: \\myserver\Zebra LP2844
    Oct 19, 2013 1:40:10 AM qz.LogIt log
    INFO: Using best match: \\myserver\Zebra LP2844
    Oct 19, 2013 1:40:10 AM qz.LogIt log
    WARNING: Tried calling JavaScript function "jzebraDoneFindingPrinters" through web browser but it has not been implemented (No such method "jzebraDoneFindingPrinters" on JavaScript object)
    CacheEntry[file:/C:/Users/Owner/Desktop/dist/qz-run.jnlp]: updateAvailable=false,lastModified=Sat Oct 19 01:27:44 EDT 2013,length=599
    CacheEntry[file:/C:/Users/Owner/Desktop/dist/qz-print.jar]: updateAvailable=false,lastModified=Sat Oct 19 01:27:44 EDT 2013,length=105639
    CacheEntry[file:/C:/Users/Owner/Desktop/dist/lib/jssc_qz.jar]: updateAvailable=false,lastModified=Sat Oct 19 01:27:44 EDT 2013,length=158623
    CacheEntry[file:/C:/Users/Owner/Desktop/dist/lib/pdf-renderer_qz.jar]: updateAvailable=false,lastModified=Sat Oct 19 01:27:44 EDT 2013,length=1639200
    At this point, your applet has now been loaded into the web browser. See Printing section for printer discovery and for sending print commands directly to your printer.

Printing

  1. qz-print's parameters are set through JavaScript commands.
  2. First, insert (or modify) the JavaScript code to search for a printer named "zebra". The printer name can be anything you wish, i.e: "Epson", "Citizen", "Generic", "BOCA", etc.
          <script>
    function findPrinter() {
    // Searches for locally installed printer with "zebra" in the name
    qz.findPrinter("zebra");

    // *Note, to get the default printer, call:
    // qz.findPrinter(); // or
    // qz.findPrinter(null);
    }
    </script>
    See also sample.html, section "findPrinter()". Note: To select another printer, you can also choose it by index using applet.setPrinter(index);
  3. Second, use html code for a Find Printer button using standard HTML input button. This button has already been provided in sample.html.
          <input type=button onClick="findPrinter()" value="Detect Printer"><br><br>
  4. Third, test the Find Printer button.
    • Load page in web browser and click "Find Printer" button.
    • View Java console for output. Look for "INFO: Printer found..."
    • TODO: Find Printer Button Screenshot
  5. Fourth, insert (or modify) this JavaScript code to send commands to printer. This button has already been provided in sample.html.
    • JavaScript Code: (Example)
            function print() {
      // Send characters/raw commands to applet using "append"
      // Hint: Carriage Return = \r, New Line = \n, Escape Double Quotes= \"
      qz.append("A37,503,0,1,2,3,N,QZ-PRINT TEST PRINT\n");

      // Send characters/raw commands to printer
      qz.print();
      }
      See also sample.html, section "print()".
    Note: The raw commands provided in the sample are not intended for use with your printer, they're provided as an example.
  6. Next, add html code for a Print button. This button has already been provided in sample.html.
           <input type=button onClick="print()" value="Print"><br><br>
  7. Last, test "print.html"
    • Load page in web browser and click "Find Printer" button
    • Click "Print" button
    • TODO: Print Button Screenshot
    • TODO: Console Output Screenshot
    • View Java console for output
  8. If problems exist, try the included sample.html or email the author.

php Printing

  1. If you would rather use php, replace print() function with this code:
          function print() {
    // Uses the php `"echo"` function in conjunction with qz-print `"append"` function
    // This assumes you have already assigned a value to `"$commands"` with php
    qz.append(<?php echo $commands; ?>);

    // Send characters/raw commands to printer
    qz.print();
    }

Base64 Printing

  1. Note: For Base64 image printing, see TutorialWebApplet#Printing_Images
  2. If print data is base64 encoded, replace print() function with this code: (Note: Versions 1.4.1 & 1.4.2 have a bug, see Issue 73.)
          // Use qz-print's `"append64"` function. This will automatically convert provided
    // base64 encoded text into ascii/bytes, etc.
    function print() {
    qz.append64("SEVMTE8hICBZT1UgQVJFIFJFQURJTkcgQSBERUNPREVE");
    qz.append64("IEJBU0U2NCBNRVNTQUdFIFNFTlQgRlJPTSBKWkVCUkEu");

    // Send characters/raw commands to printer
    qz.print();
    }
    See also sample.html, section "print()".

Epson/Citizen ESC/P Printing

Note: See ESCPCommands for many more examples
  1. Optional CHR() function for easier reading
            function chr(i) {
    return String.fromCharCode(i);
    }
  2. Open cash drawer (usually connected to printer via cable)
            function openCashDrawer() {
    qz.append(chr(27) + "\x70" + "\x30" + chr(25) + chr(25) + "\r");
    qz.print();
    }
  3. Cut paper
            function cutPaper() {
    qz.append(chr(27) + chr(105)); // cut paper
    }
  4. Basic font styling
            function boldAndCenter() {
    qz.append(chr(27) + chr(69) + "\r"); // bold on
    qz.append(chr(27) + "\x61" + "\x31"); // center justify
    }
  5. Print Image (Still experimental, needs testing)
    See TutorialWebApplet#Printing_Images

Printing Special Characters

  1. If special ascii, chr, hex or escape characters need to be printed, use the char code, or the "\x" notation. Note, the "NUL" character, or "\x00" is not supported in JavaScript, so appendHex() is needed.
          function print() {
    // Appends CHR(27) + CHR(29) using `"fromCharCode"` function
    qz.append(String.fromCharCode(27) + String.fromCharCode(29));

    // Appends hexadecimal data
    qz.appendHex("x00x01x02xFF");

    // Send characters/raw commands to printer
    qz.print();
    }
    See also sample.html, section "print()".
           // Force special DOS/Win characters on UNIX/Linux
    qz.setEncoding("cp866"); // or
    qz.setEncoding("cp1252");

    // Force UTF8 characters on Windows
    qz.setEncoding("UTF-8");

    // Force MS/DOS Western Europe (i.e. "Maçã")
    qz.setEncoding("850");
    See also Issue 28
           // Submitted via Simon on mailing list jzebra-users@googlegroups.com
    // Print GBP '£' sign using ESC/P
    // First change code page to UK
    qz.appendHex("x1Bx52x03");
    // Then just use '#' where you want your E
    qz.append("#5.00");
    See also Issue 61, which also prevents append("\x00") from working. (Using appendHex() fixes this or many choose to use use Base64 encoded print commands

Advanced Print Spooling

  1. Since version 1.0.6, qz-print has the ability to control spooling to the printer. This feature allows to print in batches of 5, 10, etc. This has advantages due to buffer limitation on certain printer models where submitting 100+ labels randomly stop in the middle of printing. In addition, some programmers have had success with using it for easier reprints.
          function print() {

    // Mark the end of a label, in this case P1 plus a newline character
    // qz-printknows to look for this and treat this as the end of a "page"
    // for better control of larger spooled jobs (i.e. 50+ labels)
    qz.setEndOfDocument("P1\n");

    // The amount of labels to spool to the printer at a time. When
    // qz-print counts this many `EndOfDocument`'s, a new print job will
    // automatically be spooled to the printer and counting will start
    // over.
    qz.setDocumentsPerSpool("10");

    // Send characters/raw commands to printer
    qz.print();
    }
See also sample.html, section "printPages()".

File Printing

  1. This feature allows a raw file to be spooled directly to the printer
        function printFile() {
    if (qz != null) {
    // Using qz-print's "appendFile()" function, a file containg your raw EPL/ZPL
    // can be sent directly to the printer
    // Example:
    // qz.appendFile("http://yoursite/zpllabel.txt"); // ...etc
    qz.appendFile(window.location.href + "/../zpl.txt");
    qz.print();
    }
    }

XML Printing

  1. Since version 1.0.8, qz-print has the ability to read the contents of an XML file containing Base64 encoded commands and send these commands to the printer. The function requires two parameters, the URL of the XML file and the tagname containing the Base64 encoded text.
          function printXML() {
    // Appends the contents of an XML file from a SOAP response, etc.
    // a valid relative URL or a valid complete URL is required for the XML
    // file. The second parameter must be a valid XML tag/node containing
    // base64 encoded data, i.e. <node_1>aGVsbG8gd29ybGQ=</node_1>
    // Example:
    // qz.appendXML("http://yoursite.com/zpl.xml", "node_1");
    qz.appendXML("C:\\zpl.xml", "v7:Image");

    // Send characters/raw commands to printer
    qz.print();
    }

See also sample.html, section "printXML()".

Print to File

  1. Since version 1.1.9, qz-print allows printing to a physical file. This is useful for bypassing printer drivers completely and sending raw data to a remote Windows Print Server queue, i.e. \\server\printer. (Thanks André T)
          function printToFile() {
    // Append some data
    qz.append("A37,503,0,1,2,3,N,ABC WIDGET CO\n");

    // Note, the doubly escaped forward slashes!
    qz.printToFile("\\\\server\\printer")
    }

PDF Printing

  1. Since version 1.1.9, qz-print allows printing PDF files directly to a printer. This functionality is experimental and uses a 3rd party renderer "PDF-RENDERER". This feature will not work with many raw printing devices, such as Zebra, Epson, Citizen printers. The data is sent in PostScript format, which is more common for LaserJet printers. USE WITH CAUTION!
          function printPDF() {
    // Make sure pdf-renderer.jar is in the "./lib" folder
    // Append the PDF
    qz.appendPDF(window.location.href + "/../sample.pdf");

    // Very important for PDFs, use "printPS()" instead of "print()"
    qz.printPS();
    }
    Note: If printing dynamically generated PDF from php, make sure to add header 'Content-Type: application/pdf' as well as 'Content-Disposition:inline;filename=example.pdf' or else PDF-RENDERER plugin will throw an error: "Exception occurred: This may not be a PDF File". See Issue 48 for more details CUPS/Linux PDF Printing: Please note, there is a bug preventing margins from working properly on some versions of CUPS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6726691

Printing Images

  1. Experimental support for appending printer-specific images by url and/or Base64.
          // *Note 1:  Applet will append special raw markup, i.e. ^GFA, char(27), etc
    // *Note 2: Image width and image height must be divisible by 8
    // *Note 3: Newline/Carriage Return must be appended manually
    // *Note 4: Images should be strictly black and white

    // Zebra (EPL):
    qz.appendImage("image.png", "EPL");
    while (!qz.isDoneAppending()) {} // wait
    qz.append("\r\n");

    // Zebra (ZPLII):
    qz.appendImage("image.png", "ZPLII");
    while (!qz.isDoneAppending()) {} // wait
    qz.append("\r\n");

    // Zebra (CPCL):
    qz.appendImage("image.png", "CPCL");
    while (!qz.isDoneAppending()) {} // wait
    qz.append("\r\n");




    // Epson (ESCP):
    qz.appendImage("image.png", "ESCP");
    while (!qz.isDoneAppending()) {} // wait
    qz.append("\r\n");

    // Base64
    qz.appendImage("data:image/png;base64,AAAAAAAAA...", "ZPLII");
    qz.append("\n");

    // DeskJet/LaserJet, etc (don't mix with raw devices)
    // Paper size/orientation since version 1.4.5
    qz.setPaperSize("210mm", "297mm"); // A4
    // qz.setPaperSize("8.5in", "11.0in"); // US Letter
    qz.setAutoSize(true); // Preserve proportions
    qz.setOrientation("landscape"); // Default is "portrait"
    qz.appendImage("image.png"); // Append our image. Note: Wait for this to finish, or implement "jzebraDoneAppending()"
    qz.print();

HTML Printing

  1. Since version 1.4.5, qz-print can print advanced HTML components by rendering an HTML component to an image using the html2canvas jQuery plugin (bundled in the /dist/js folder).
           // HTML
    <body id="content" bgcolor="#FFF380"> ...
    <canvas id="hidden_screenshot" style="display:none;" /> ...

    // JavaScript (jQuery)
    $("#content").html2canvas({
    canvas: hidden_screenshot,
    onrendered: function() {
    qz.append64($("canvas")[0].toDataURL('image/png'));
    qz.printPS();
    }
    });
Note: HTML id #content can be virtually any HTML component. HTML id hidden_screenshot is a temporary place to draw the content and should be set display=none to prevent the render from becoming visiable.
  1. Since version 1.3.2, qz-print has the ability to print basic HTML components to a PostScript style printer directly from the browser. (PostScript printers include all major LaserJet, DeskJet, PSC, Home Printers, etc). Mileage may vary across different operating systems. Please file a bug report using ISSUES link above if you encounter issues.
          // Basic HTML Printing
    qz.appendHTML("<html><h1><font color=Red>Hello world!</font></h1>qz-print HTML Printing Demo</html>");
    qz.printHTML();




    // Printing using extra spaces, fixed font, dashes
    var text = "*no-line-break* Hello from ’qz-print’ *no-line-break*";

    // Fix whitespace and special character behavior
    text = text.replace(/ /g, "&nbsp;").replace(/’/g, "'").replace(/-/g,"&#8209;");

    qz.appendHTML('<html><table border=1 style="font-size:10pt; font-face:\'Courier New\';"><tr><td>' + text + '</td></tr></table></html>');

    qz.printHTML();




    // Printing an existing HTML file
    qz.appendHTMLFile("../form.html");

    // Wait for append to finish
    while (!qz.isDoneAppending()) { // wait }

    qz.printHTML();
    Linux HTML Printing: Please note, there is a bug preventing margins from working properly on Linux: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6726691

Experimental / Work Arounds

  1. Since version 1.4.6, An OSX-only work-around was added to qz-print that allows printing through CUPS command line (lp -o raw), Issue 87.
          // Alternate OSX raw printing via CUPS
    qz.useAlternatePrinting(true);

Serial Communication

  1. Since version 1.6.0, You can send and receive data using the jSSC plugin (requires /dist/lib/jssc_qz.jar).
          // List serial ports
    qz.findPorts();

    function jzebraDoneFindingPorts() {
    var ports = qz.getPorts().split(",");
    for (p in ports) {
    alert(ports[p]);
    }
    }


    // Open a serial port
    qz.openPort("COM1"); //Can be dev/ttyS0, /dev/ttyUSB0, depending on platform

    function jzebraDoneOpeningPort(portName) {
    alert("Port [" + portName + "] is open!");
    }


    // Send serial data
    // Beggining and ending patterns that signify port has responded
    // chr(2) and chr(13) surround data on a Mettler Toledo Scale
    qz.setSerialBegin(chr(2));
    qz.setSerialEnd(chr(13));
    // Baud rate, data bits, stop bits, parity, flow control
    // "9600", "7", "1", "even", "none" = Default for Mettler Toledo Scale
    qz.setSerialProperties("9600", "7", "1", "even", "none");
    // Send raw commands to the specified port.
    // W = weight on Mettler Toledo Scale
    qz.send(document.getElementById("port_name").value, "\nW\n");


    // Retrieve serial response (automatically called)
    function jzebraSerialReturned(portName, data) {
    alert("Port [" + portName + "] returned data:\n\t" + data);
    }


    // Close a serial port
    qz.closePort("COM1"); //Can be dev/ttyS0, /dev/ttyUSB0, depending on platform

    function jzebraDoneClosingPort(portName) {
    alert("Port [" + portName + "] is open!");
    }

End of Tutorial

Conclusion

This tutorial needs work. Please help by submitting changes. Email questions or suggestions to the author.

Alternatively, For questions, feedback and updates, subscribe to the qz-print Mailing List on Google Groups:
http://groups.google.com/group/jzebra-users'>http://groups.google.com/intl/en/images/logos/groups_logo_sm.gif' />