qzindustries / qz-print

Free browser applet for sending documents and raw commands to a printer.
Other
49 stars 4 forks source link

Hi-Res HTML5 Printing #51

Closed tresf closed 9 years ago

tresf commented 9 years ago

QZ Print needs the ability to easily print Hi-Resolution HTML components using the html2canvas plugin.

Here's the first attempt at printing some scannable barcodes using pure HTML5/JavaScript.

If you have recommendations on how to improve this approach, please post in the comments below.

Note, this specific sample requires code39.js

-Tres

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <meta charset="utf-8">
    <title>HTML5 Barcode Sample</title>
    <script type="text/javascript" src="js/deployJava.js"></script>
    <script type="text/javascript" src="js/jquery-1.10.2.js"></script>
    <script type="text/javascript" src="js/jquery.plugin.html2canvas.js"></script>
    <script type="text/javascript" src="js/html2canvas.js"></script>

    <!-- ADDITIONAL LIBRARY REQUIRED FOR THIS SAMPLE TO WORK -->
    <script type="text/javascript" src="js/code39.js"></script>

    <script type="text/javascript">

    // Just a dummy barcode "000" before getversion is finished
    $(function() { $('#barcode').html(Code39(0,0,1000,128, "000" , 18)); });

    /**
     * Call deploy on page load
     */
    deployQZ();

    /**
     * Deploys applet tags to browser
     */
    function deployQZ() {
        var attributes = {id: "qz", code:'qz.PrintApplet.class', 
            archive:'qz-print.jar', width:1, height:1};
        var parameters = {jnlp_href: 'qz-print_jnlp.jnlp', 
            cache_option:'plugin', disable_logging:'false', 
            initial_focus:'false'};
        deployJava.runApplet(attributes, parameters, '1.5');
    }

    /**
     * Called when applet is loaded
     */
    function qzReady() {
        // Setup our global qz object
        window["qz"] = document.getElementById('qz');
        if (qz) {
            try {
                /*
                 * Code39(theX, theY, theBarHeight, theFontHeight, theBarCodeText[, theBarCodeSize])
                 */
                var version = qz.getVersion().replace(/\./g,'');
                $('#barcode').html(Code39(0,0,1000,128, version , 18)); 

                findPrinter("xps");
            } catch(err) { // LiveConnect error, display a detailed meesage
                alert(err.message + "\nERROR:  \nThe applet did not load correctly.");
            }
        }

    }

    /**
    * Returns whether or not the applet is not ready to print.
    * Displays an alert if not ready.
    */
    function notReady() {
        // If applet is not loaded, display an error
        if (!isLoaded()) {
            return true;
        }
        // If a printer hasn't been selected, display a message.
        else if (!qz.getPrinter()) {
            alert('Please select a printer first by using the "Detect Printer" button.');
            return true;
        }
        return false;
    }

    /**
    * Returns is the applet is not loaded properly
    */
    function isLoaded() {
        if (!qz) {
            alert('Error:\n\n\tPrint plugin is NOT loaded!');
            return false;
        } else {
            try {
                if (!qz.isActive()) {
                    alert('Error:\n\n\tPrint plugin is loaded but NOT active!');
                    return false;
                }
            } catch (err) {
                alert('Error:\n\n\tPrint plugin is NOT loaded properly!');
                return false;
            }
        }
        return true;
    }

    /**
    * Automatically gets called when "qz.print()" is finished.
    */
    function qzDonePrinting() {
        // Alert error, if any
        if (qz.getException()) {
            alert('Error printing:\n\n\t' + qz.getException().getLocalizedMessage());
            qz.clearException();
            return; 
        }

        // Alert success message
        alert('Successfully sent print data to "' + qz.getPrinter() + '" queue.');
    }

    /***************************************************************************
    * Prototype function for finding the closest match to a printer name.
    * Usage:
    *    qz.findPrinter('zebra');
    *    window['qzDoneFinding'] = function() { alert(qz.getPrinter()); };
    ***************************************************************************/
    function findPrinter(name) {
        if (isLoaded()) {
            // Searches for locally installed printer with specified name
            qz.findPrinter(name);
        }
    }

    /**
     * Called when finding is done
     */
    function qzDoneFinding() {
        printHTML5Div();
    }

    /***************************************************************************
    * Prototype function for printing an HTML screenshot of the existing page
    * Usage: (identical to appendImage(), but uses html2canvas for png rendering)
    *    qz.setPaperSize("8.5in", "11.0in");  // US Letter
    *    qz.setAutoSize(true);
    *    qz.appendImage($("canvas")[0].toDataURL('image/png'));
    ***************************************************************************/ 
    function printHTML5Div() {
        $('#hidden_content').html($('#content').html());
        var w = $('#hidden_content').width();
        var h = $('#hidden_content').height();
        $("#hidden_content").html2canvas({ 
            canvas: hidden_canvas,
            onrendered: function() {
                if (notReady()) { return; }
                // Convert 1 px ~= .26mm
                qz.setPaperSize(.05 * w, .05 * h, 'mm');
                qz.setAutoSize(true);
                qz.appendImage($("canvas")[0].toDataURL('image/png'));
                // Automatically gets called when "qz.appendFile()" is finished.
                window['qzDoneAppending'] = function() {
                    // Tell the applet to print.
                    qz.printPS();

                    // Remove reference to this function
                    window['qzDoneAppending'] = null;
                };
            },
            // Note:  Width and height are CRITICAL to get the rendering working
            width: w,
            height: h
        });
    }

    </script>
<style>

#hideme {
    /* Render horizontally without overflow */
    width: 9999px;

    /* From the top left corner and down */
    display: inline-block;
    position: absolute;
    top: 0;
    left: 0;

    /* Draw but hide content */
    height: 0;
    overflow: hidden;

    /* Remove any default spacing */
    margin: 0;
    padding: 0;
}

#hidden_content {
    display: inline-block;
    text-align:center;
}

#content {
    display: inline-block;
    text-align:center;
    zoom:15%;
}

#barcode {
    display: inline-block;
}

h1 {
    margin: 0 auto;
    font-size: 8em;
}

.preview {
    color: red;
    font-size: 3em;
    position: relative;
    top: -2.5em;
    left: 0px;
    font-weight: 900;
    background-color: #fff;
}

</style>
</head>

<body>
    <div id="content" >
        <h1>QZ-PRINT</h1>
        <div id="barcode"></div>
    </div>
    <div id="hideme" height="100px">
        <div id="hidden_content"></div>
    </div>
    <div class="preview">PREVIEW</div>

    <canvas id="hidden_canvas" style="display:none;"></canvas>
</body>
</html>
tresf commented 9 years ago

Hi-res HTML5 printing is on the radar for this summer. Closing this out as we'll be tracking this at our new repository, once started: https://github.com/qzind/qz-print