mirror of
				https://github.com/inventree/inventree-website.git
				synced 2025-11-04 07:25:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			554 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			554 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<html lang=" en-US ">
 | 
						||
 | 
						||
<head>
 | 
						||
    <meta charset="UTF-8">
 | 
						||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
						||
<meta name="viewport" content="width=device-width, initial-scale=1">
 | 
						||
 | 
						||
<link rel="stylesheet" href="/assets/splide/css/splide.min.css">
 | 
						||
<link rel="stylesheet" href="/assets/index.css">
 | 
						||
<link rel="shortcut icon" type="image/png" href="/assets/icon/favicon.ico">
 | 
						||
 | 
						||
<script src="/assets/splide/js/splide.min.js"></script>
 | 
						||
 | 
						||
<!-- Fontawesome integration -->
 | 
						||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css">
 | 
						||
 | 
						||
<title>InvenTree - Inventree Zebra Plugin</title>
 | 
						||
<meta itemprop="description" name="description"
 | 
						||
    content="InvenTree is an open-source inventory management system which provides intuitive parts management and stock control. It is at the center of an ecosystem of a..." />
 | 
						||
 | 
						||
<!-- Begin Jekyll SEO tag v2.8.0 -->
 | 
						||
<title>Inventree Zebra Plugin | InvenTree</title>
 | 
						||
<meta name="generator" content="Jekyll v4.3.3" />
 | 
						||
<meta property="og:title" content="Inventree Zebra Plugin" />
 | 
						||
<meta name="author" content="SergeoLacruz" />
 | 
						||
<meta property="og:locale" content="en_US" />
 | 
						||
<meta name="description" content="Zebra Label Printer Plugin for Inventree" />
 | 
						||
<meta property="og:description" content="Zebra Label Printer Plugin for Inventree" />
 | 
						||
<link rel="canonical" href="/SergeoLacruz/inventree-zebra-plugin" />
 | 
						||
<meta property="og:url" content="/SergeoLacruz/inventree-zebra-plugin" />
 | 
						||
<meta property="og:site_name" content="InvenTree" />
 | 
						||
<meta property="og:type" content="article" />
 | 
						||
<meta property="article:published_time" content="2025-06-07T01:19:31+00:00" />
 | 
						||
<meta name="twitter:card" content="summary" />
 | 
						||
<meta property="twitter:title" content="Inventree Zebra Plugin" />
 | 
						||
<script type="application/ld+json">
 | 
						||
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"SergeoLacruz"},"dateModified":"2025-06-07T01:19:31+00:00","datePublished":"2025-06-07T01:19:31+00:00","description":"Zebra Label Printer Plugin for Inventree","headline":"Inventree Zebra Plugin","mainEntityOfPage":{"@type":"WebPage","@id":"/SergeoLacruz/inventree-zebra-plugin"},"url":"/SergeoLacruz/inventree-zebra-plugin"}</script>
 | 
						||
<!-- End Jekyll SEO tag -->
 | 
						||
 | 
						||
</head>
 | 
						||
 | 
						||
<body class="flex flex-col antialiased cm-gray-1 min-h-screen">
 | 
						||
    <div class="flex-none">
 | 
						||
        <header class="cm-gray-2 body-font sticky top-0 z-50 bg-gradient-to-r from-white to-secondary">
 | 
						||
    <div class="container mx-auto flex flex-wrap p-5 flex-row items-center">
 | 
						||
        <a class="flex title-font font-medium items-center cm-gray-1 mb-0 mr-2" href="/">
 | 
						||
            <img src="/assets/logo.png" alt="logo" height="32" width="32" class="h-8">
 | 
						||
            <span class="ml-3 text-xl">InvenTree</span>
 | 
						||
        </a>
 | 
						||
 | 
						||
        <div class="flex-grow xs:flex-none"></div>
 | 
						||
 | 
						||
        <nav class="md:mr-auto md:py-1 xs:ml-4 xs:pl-4 xs:border-l xs:border-gray-400	flex flex-wrap items-center text-base justify-center">
 | 
						||
            <a class="mr-5 hover:cm-gray-1" href="/deploy.html">Deploy</a>
 | 
						||
            <a class="mr-5 hover:cm-gray-1" href="https://docs.inventree.org/en/stable/">Docs</a>
 | 
						||
            <a class="mr-5 hover:cm-gray-1" href="/blog">Blog</a>
 | 
						||
        </nav>
 | 
						||
 | 
						||
        
 | 
						||
    </div>
 | 
						||
</header> <article class="max-w-p90">
 | 
						||
    
 | 
						||
    <h2>inventree-zebra-plugin
 | 
						||
<span class="sm:ml-2 text-sm">
 | 
						||
<a href="/SergeoLacruz">
 | 
						||
<span class="inline-flex">
 | 
						||
    <img src="https://github.com/SergeoLacruz.png?size=40" alt="mdo" class="self-center w-5 h-5 rounded-full" style="margin:0px">
 | 
						||
    <p> SergeoLacruz</p>
 | 
						||
</span>
 | 
						||
</a></span>
 | 
						||
<span class="sm:ml-2 text-sm">last modified: 07 Jun 2025</span>
 | 
						||
</h2>
 | 
						||
 | 
						||
<div class="flex-wrap md:flex md:flex-nowrap">
 | 
						||
    <div class="w-full md:w-auto md:mr-4">
 | 
						||
        <p>Zebra Label Printer Plugin for Inventree</p>
 | 
						||
 | 
						||
<p>This is a label printing plugin for <a href="https://inventree.org">InvenTree</a>, which provides
 | 
						||
support for Zebra Label printers. It allows two modes of operation:</p>
 | 
						||
 | 
						||
<ul>
 | 
						||
  <li>Use the ZPL library to convert the png data provided by InvenTree to Zebra’s bitmap
 | 
						||
format and send this to the printer.</li>
 | 
						||
  <li>Write a ZPL template and let the printer do the rendering.</li>
 | 
						||
</ul>
 | 
						||
 | 
						||
<p>It can output the print data either to a local printer connected to the computer via
 | 
						||
USB or to a network printer with an IP address. The output can be configured in the
 | 
						||
InvenTree plugin user interface.</p>
 | 
						||
 | 
						||
<p>Error handling is very basic.</p>
 | 
						||
 | 
						||
<h2 id="installation">Installation</h2>
 | 
						||
 | 
						||
<p>The plugin is on pypi. Install this plugin using pip with the following command:</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip install inventree-zebra-plugin
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<h2 id="configuration-options">Configuration Options</h2>
 | 
						||
<h3 id="printer-interface">Printer Interface</h3>
 | 
						||
<p>Here you can chose between local printer, network printer or the labelary.com API.
 | 
						||
The last one is useful for preview of labels, especially when ZPL templates are used.
 | 
						||
Default value is a local printer.</p>
 | 
						||
 | 
						||
<h3 id="ip-address">IP address</h3>
 | 
						||
<p>In case you use an IP printer set the IPv4 address here.</p>
 | 
						||
 | 
						||
<h3 id="port">Port</h3>
 | 
						||
<p>In case you use an IP printer set the port number here. The default port number is 9100.</p>
 | 
						||
 | 
						||
<h3 id="local-device">Local Device</h3>
 | 
						||
<p>In case of a local printer set the device here. The plugin actually puts the data directly to the
 | 
						||
device /dev/usb/lp0. No printer spooler is involved so far.</p>
 | 
						||
 | 
						||
<h3 id="threshold">Threshold</h3>
 | 
						||
<p>The image from pillow comes in greyscale. The plugin converts it ti pure BW because this gives a much
 | 
						||
better print result. The threshold between black and white can be adjusted here.</p>
 | 
						||
 | 
						||
<h3 id="darkness">Darkness</h3>
 | 
						||
<p>This is a value that influences the darkness of the print. Allowed values are 0 (white) to 30 (black).
 | 
						||
It is directly converted to a SD command in ZPL. If your black areas tend to blur out reduce the
 | 
						||
darkness.</p>
 | 
						||
 | 
						||
<h3 id="dots-per-mm">Dots per mm</h3>
 | 
						||
<p>This sets the resolution of the printer. You can choose between 8, 12 and 24
 | 
						||
dpmm depending on your printer model.</p>
 | 
						||
 | 
						||
<h3 id="printer-init">Printer init</h3>
 | 
						||
<p>This string added to the printer output. It can be used to set special commands
 | 
						||
e.g. label rotation, mirror or white on black. Please refer to the ZPL manual
 | 
						||
for more information.</p>
 | 
						||
 | 
						||
<p>Zebra printers store settings after printing. So if a rotated label has been
 | 
						||
printed all following label will be rotated unless you change it. The default
 | 
						||
sets the printer to settings that have been useful for me. You might want to
 | 
						||
change it according to your requirements. Please keep in mind that this string
 | 
						||
is passed directly to the printer without any checks. So be careful when editing
 | 
						||
here.</p>
 | 
						||
 | 
						||
<h3 id="get-printer-info">Get Printer info</h3>
 | 
						||
<p>Turn this switch on to display a collection of all IP printers below on this page.</p>
 | 
						||
 | 
						||
<h2 id="label-template">Label Template</h2>
 | 
						||
<p>The label needs a template described in html and css. The template should
 | 
						||
start with a page definition that defines the label size as shown below:</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
 | 
						||
    @page {
 | 
						||
        {% localize off %}
 | 
						||
        height: {{ height }}mm;
 | 
						||
        width: {{ width }}mm;
 | 
						||
        {% endlocalize %}
 | 
						||
        padding: 0mm;
 | 
						||
        margin: 0px 0px 0px 0px;
 | 
						||
        background-color: white;
 | 
						||
    }
 | 
						||
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>The height and width parameters are defined in the InvenTree admin panel
 | 
						||
in the label section. These values have to fit the label size that is in
 | 
						||
the printer. See the example templates for details on template definition.</p>
 | 
						||
 | 
						||
<h2 id="multi-printer-hack">Multi printer hack</h2>
 | 
						||
<p>We have the requirement to print labels in different sizes. As we do not
 | 
						||
want to change the reel for each print we set up a second printer loaded
 | 
						||
with a different label size. InvenTree is not yet able to handle different
 | 
						||
printers. So I added a multi printer hack. You can define a key with an IP
 | 
						||
address in the label meta data:</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"ip_address":"xxx.yyy.zzz.eee"}
 | 
						||
{"darkness":xx}
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>If the printer driver finds that key, the IP address from the printer settings
 | 
						||
is overwritten with the address from the meta data. So the print will end up
 | 
						||
in another printer.</p>
 | 
						||
 | 
						||
<p>Only the IP address and darkness can be overwritten so far. All other settings remain.</p>
 | 
						||
 | 
						||
<h2 id="quality-matters">Quality matters</h2>
 | 
						||
<p>The InvenTree printer system uses a graphical representation of the label. The label is described
 | 
						||
in HTML, converted to a pixel graphic and printed. The advantage is independency from  printer
 | 
						||
models and systems. Disadvantage is larger data and quality problems with darkness and scaling.
 | 
						||
Let’s have a look at the following printout:</p>
 | 
						||
 | 
						||
<p><img src="/assets/plugins/qr.png" alt="QRCodes"></p>
 | 
						||
 | 
						||
<p>Both codes have been printed with the same printer on the same reel. The left one is
 | 
						||
hardly readable using my mobile. The right one reads easily even as it is smaller.</p>
 | 
						||
 | 
						||
<h3 id="secret-1-scale">Secret 1, Scale</h3>
 | 
						||
<p>The printer resolution is 8 dots per mm resulting in a dot size of 0.125mm. The QR code pixel
 | 
						||
and the printer pixel size should be integrally divisible. The code in the picture has 21
 | 
						||
pixels plus one in the frame, so 23 pixel. The frame is set in the HTML description.</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{% qrcode qr_data border=1 %}
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>I selected two dots per pixel. So 23 * 2 * 0.125 = 6.125mm. If the size is something different
 | 
						||
scaling takes place and the result might be worse. If you like a larger printout select more
 | 
						||
dots per pixel. From a certain size upwards the value does not matter any more because the code
 | 
						||
gets large enough to be readable in any quality.</p>
 | 
						||
 | 
						||
<h3 id="secret-2-darkness">Secret 2: Darkness</h3>
 | 
						||
<p>Zebra printers allow to set the darkness of the print in values between 0 (white) and 30 (max)
 | 
						||
The left code was printed with a value of 30. The black dots tend to blur out a bit resulting
 | 
						||
in smaller white areas. The right code was printed with a value of 25 resulting in larger white
 | 
						||
pixels.  The darkness values are just examples. Your values will differ based on printer model,
 | 
						||
media type and printer age. The printer head tends to wear out and the darkness value might
 | 
						||
need an adjustment from time to time.</p>
 | 
						||
 | 
						||
<h2 id="in-printer-rendering">In printer rendering</h2>
 | 
						||
<p>You can also bypass the InvenTree print engine and render the label inside the printer.
 | 
						||
The printer knows how to render the label for best quality. Inspired by the 
 | 
						||
inventree-zpl-plugin <a href="https://github.com/yellowcrescent/inventree-zpl-plugin">inventree-zpl-plugin</a> a similar
 | 
						||
function was aded to the zebra printer driver. You can write a ZPL template and upload
 | 
						||
it to the InvenTree Label templates as usual. Add a command to the template’s metadata:</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"zpl_template": "True"}
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>In that case the printer driver ignores the picture rendered by WeasyPrint. Instead
 | 
						||
it calls the render_to_string function of the template and sends the
 | 
						||
result to the printer. The result can look like:</p>
 | 
						||
 | 
						||
<p><img src="/assets/plugins/example_label.png" alt="Label Example"></p>
 | 
						||
 | 
						||
<p>The upper label was created using this template:</p>
 | 
						||
 | 
						||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
 | 
						||
{% autoescape off %}
 | 
						||
^FT30,25^A0N,18,22^FDIPN^FS
 | 
						||
^FT150,30^FB100,1,,C,,^A0N,24,32^FDACME^FS
 | 
						||
^FT320,25^A0N,18,22^FD{{ item.pk }}^FS
 | 
						||
^FT100,70^FB200,2,,C,,^A0N,18,22^FD{{ part.name }}^FS
 | 
						||
^FT100,100^FB200,1,,C,,^A0N,18,22^FD{{ part.manufacturer_parts.first.manufacturer.name }}^FS
 | 
						||
^FT30,150^FB340,1,,C,,^A0N,30,40^FD{{ part.IPN }}^FS
 | 
						||
^FT20,210^FB360,3,,L,,^A0N,18,22^FD{{ part.description }}^FS
 | 
						||
^FT15,110^BQ,2,3^FDQA,{{ part.IPN }}^FS
 | 
						||
^FT310,130^BQ,2,3^FDQA,{{ qr_data }}^FS
 | 
						||
{% endautoescape %}
 | 
						||
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>Autoescape must be off. We do not need &quot and similar escapes here.
 | 
						||
Context variables can be used as usual.</p>
 | 
						||
 | 
						||
<p>!!! warning “Limitation”
 | 
						||
    ZPL commands starting with backslash like \& cannot be used so far.</p>
 | 
						||
 | 
						||
<h3 id="preview">Preview</h3>
 | 
						||
<p>The printer driver allows an output device called “preview”. If this is selected
 | 
						||
the ZPL code is sent to the API of labelary.com. The API sends back pdf data
 | 
						||
which is displayed in a new browser window. This is helpful while writing ZPL
 | 
						||
templates but works with HTML templates too. Please be careful and do not send
 | 
						||
confidential information to the API.</p>
 | 
						||
 | 
						||
<p>In case you need to pass a proxy for the POST requests set the environment
 | 
						||
variables PROXY_CON and PROXY_URL on the server. The plugin does not have
 | 
						||
settings for this.</p>
 | 
						||
 | 
						||
<h2 id="getting-printer-info">Getting printer info</h2>
 | 
						||
<p>With the multi printer feature it can happen that you have several printers in
 | 
						||
your setup. When the Get Printer Info switch is set ON, the driver calls each printer
 | 
						||
once a minute and collects some info about it. It calls the printer configured
 | 
						||
in the settings as well as all printers it finds in the label templates.
 | 
						||
In case a printer is unreachable, an error message is shown. If a printer is used
 | 
						||
in several templates it is listed only once.</p>
 | 
						||
 | 
						||
<p>The printer info feature works for local USB printers too.</p>
 | 
						||
 | 
						||
<p><img src="/assets/plugins/printer_info.png" alt="Printer Info"></p>
 | 
						||
 | 
						||
<h2 id="how-it-works">How it works</h2>
 | 
						||
<p>First import all the stuff you need. Here we use the translation mechanism from Django for multi language support.
 | 
						||
The import the InvenTree libs and everything you need for plugin. Here we have ZPL for the Zebra bitmaps and socket
 | 
						||
for the IP connection to the printer.</p>
 | 
						||
 | 
						||
<p>The next part is this:</p>
 | 
						||
 | 
						||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">ZebraLabelPlugin</span><span class="p">(</span><span class="n">LabelPrintingMixin</span><span class="p">,</span> <span class="n">SettingsMixin</span><span class="p">,</span> <span class="n">IntegrationPluginBase</span><span class="p">):</span>
 | 
						||
 | 
						||
    <span class="n">AUTHOR</span> <span class="o">=</span> <span class="sh">"</span><span class="s">Michael Buchmann</span><span class="sh">"</span>
 | 
						||
    <span class="n">DESCRIPTION</span> <span class="o">=</span> <span class="sh">"</span><span class="s">Label printing plugin for Zebra printers</span><span class="sh">"</span>
 | 
						||
    <span class="n">VERSION</span> <span class="o">=</span> <span class="n">ZEBRA_PLUGIN_VERSION</span>
 | 
						||
    <span class="n">NAME</span> <span class="o">=</span> <span class="sh">"</span><span class="s">Zebra labels</span><span class="sh">"</span>
 | 
						||
    <span class="n">SLUG</span> <span class="o">=</span> <span class="sh">"</span><span class="s">zebra</span><span class="sh">"</span>
 | 
						||
    <span class="n">TITLE</span> <span class="o">=</span> <span class="sh">"</span><span class="s">Zebra Label Printer</span><span class="sh">"</span>
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>The name of the class can be freely chosen but should be different from SLUG. Otherwise it does not
 | 
						||
show up. You reference to it in the entry_points section of the setup.py file.
 | 
						||
The parameters need to be like in the example. Then there is the description block. The keywords are fixed and
 | 
						||
need to be like that. The values are found in the UI as shown in the picture below.</p>
 | 
						||
 | 
						||
<p><img src="/assets/plugins/plugin.png" alt="Config"></p>
 | 
						||
 | 
						||
<p>Then we add the configuration parameters.</p>
 | 
						||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">SETTINGS</span> <span class="o">=</span> <span class="p">{</span>
 | 
						||
        <span class="sh">'</span><span class="s">CONNECTION</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span>
 | 
						||
            <span class="sh">'</span><span class="s">name</span><span class="sh">'</span><span class="p">:</span> <span class="nf">_</span><span class="p">(</span><span class="sh">'</span><span class="s">Printer Interface</span><span class="sh">'</span><span class="p">),</span>
 | 
						||
            <span class="sh">'</span><span class="s">description</span><span class="sh">'</span><span class="p">:</span> <span class="nf">_</span><span class="p">(</span><span class="sh">'</span><span class="s">Select local or network printer</span><span class="sh">'</span><span class="p">),</span>
 | 
						||
            <span class="sh">'</span><span class="s">choices</span><span class="sh">'</span><span class="p">:</span> <span class="p">[(</span><span class="sh">'</span><span class="s">local</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Local printer e.g. USB</span><span class="sh">'</span><span class="p">),(</span><span class="sh">'</span><span class="s">network</span><span class="sh">'</span><span class="p">,</span><span class="sh">'</span><span class="s">Network printer with IP address</span><span class="sh">'</span><span class="p">)],</span>
 | 
						||
            <span class="sh">'</span><span class="s">default</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">local</span><span class="sh">'</span><span class="p">,</span>
 | 
						||
        <span class="p">},</span>
 | 
						||
        <span class="sh">'</span><span class="s">PORT</span><span class="sh">'</span><span class="p">:</span> <span class="p">{</span>
 | 
						||
            <span class="sh">'</span><span class="s">name</span><span class="sh">'</span><span class="p">:</span> <span class="nf">_</span><span class="p">(</span><span class="sh">'</span><span class="s">Port</span><span class="sh">'</span><span class="p">),</span>
 | 
						||
            <span class="sh">'</span><span class="s">description</span><span class="sh">'</span><span class="p">:</span> <span class="nf">_</span><span class="p">(</span><span class="sh">'</span><span class="s">Network port in case of network printer</span><span class="sh">'</span><span class="p">),</span>
 | 
						||
            <span class="sh">'</span><span class="s">default</span><span class="sh">'</span><span class="p">:</span> <span class="sh">'</span><span class="s">9100</span><span class="sh">'</span><span class="p">,</span>
 | 
						||
        <span class="p">},</span>
 | 
						||
    <span class="p">}</span>
 | 
						||
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>We need to define a dict with the name SETTINGS. Please be aware the keys need to be in all CAPITAL letters like CONNECTION.
 | 
						||
Simple parameters are just text strings like the port. We can set a default. The name and description shows up in the UI.
 | 
						||
Instead of a simple text we can also use choices. The first string like “local” it the key you use in the code. The second
 | 
						||
one is the description in the UI.
 | 
						||
After that we need to define a function:</p>
 | 
						||
 | 
						||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">print_label</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">){</span>
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>The kwargs is a dict with the following keys:</p>
 | 
						||
 | 
						||
<ul>
 | 
						||
  <li>pdf_data</li>
 | 
						||
  <li>user</li>
 | 
						||
  <li>filename</li>
 | 
						||
  <li>label_instance</li>
 | 
						||
  <li>item_instance</li>
 | 
						||
  <li>width</li>
 | 
						||
  <li>height</li>
 | 
						||
  <li>png_file</li>
 | 
						||
</ul>
 | 
						||
 | 
						||
<p>The item_instance is the part to be printed. This allows direct access to all part data. The arguments width and height
 | 
						||
come from the settings of the label in the admin interface. NOT from the html template.
 | 
						||
For the Zebra printer we use the png_file. This is a PIL (python Pillow) object with the graphic of the label in PNG format.
 | 
						||
The PIL object is a greyscale image. Because the printer can just print pure BW we convert this to a BW picture.</p>
 | 
						||
 | 
						||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fn</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span> <span class="p">:</span> <span class="mi">255</span> <span class="k">if</span> <span class="n">x</span> <span class="o">></span> <span class="n">Threshold</span> <span class="k">else</span> <span class="mi">0</span>
 | 
						||
<span class="n">label_image</span> <span class="o">=</span> <span class="n">label_image</span><span class="p">.</span><span class="nf">convert</span><span class="p">(</span><span class="sh">'</span><span class="s">L</span><span class="sh">'</span><span class="p">).</span><span class="nf">point</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="sh">'</span><span class="s">1</span><span class="sh">'</span><span class="p">)</span>
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>The threshold can by modified by a plugin parameter. 200 is a good starting value.  This trick gives much better prints.
 | 
						||
We can put the result of this directly into the ZPL library.</p>
 | 
						||
 | 
						||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">l</span> <span class="o">=</span> <span class="n">zpl</span><span class="p">.</span><span class="nc">Label</span><span class="p">(</span><span class="n">Height</span><span class="p">,</span> <span class="n">Width</span><span class="p">,</span> <span class="n">dpmm</span><span class="p">)</span>
 | 
						||
<span class="n">li</span><span class="p">.</span><span class="nf">set_darkness</span><span class="p">(</span><span class="n">darkness</span><span class="p">)</span>
 | 
						||
<span class="bp">...</span>
 | 
						||
<span class="n">l</span><span class="p">.</span><span class="nf">write_graphic</span><span class="p">(</span><span class="n">label_image</span><span class="p">,</span> <span class="n">Width</span><span class="p">)</span>
 | 
						||
<span class="n">l</span><span class="p">.</span><span class="nf">endorigin</span><span class="p">()</span>
 | 
						||
</code></pre></div></div>
 | 
						||
 | 
						||
<p>Width and Height define is the size of the label in millimeters as described above.
 | 
						||
The third parameter is the resolution of the printer in dots per mm.
 | 
						||
write_graphic converts the pillow data to ZPL.</p>
 | 
						||
 | 
						||
<p>The plugin was tested with a labels of various sizes defined using css and html. The DPI scaling
 | 
						||
can be chosen in the InvenTree settings. 800 is a good value because it gives high quality.</p>
 | 
						||
 | 
						||
<p>The rest of the code is just output to the printer on different interfaces.</p>
 | 
						||
 | 
						||
<p>Happy printing.</p>
 | 
						||
 | 
						||
    </div>
 | 
						||
 | 
						||
    <div class="w-full md:w-1/4">
 | 
						||
      <h2 class="block sm:hidden">Detail section</h2>
 | 
						||
      <div>
 | 
						||
        <p class="mb-0">License:
 | 
						||
          <small>
 | 
						||
          <i class="fa-brands fa-osi"></i>
 | 
						||
          MIT<br>
 | 
						||
          </small>
 | 
						||
          </p>
 | 
						||
<div class="">
 | 
						||
            Status:<br>
 | 
						||
            <div>
 | 
						||
              <small>
 | 
						||
                
 | 
						||
                <i class="fa-regular fa-circle-check success"></i>Stable
 | 
						||
                
 | 
						||
              </small>
 | 
						||
            </div>
 | 
						||
            <div>
 | 
						||
              <small>
 | 
						||
                
 | 
						||
                <i class="fa-regular fa-circle-check success"></i>Maintained
 | 
						||
                
 | 
						||
              </small>
 | 
						||
            </div>
 | 
						||
          </div>
 | 
						||
          
 | 
						||
        
 | 
						||
 | 
						||
        
 | 
						||
 | 
						||
        
 | 
						||
        <a href="https://github.com/SergeoLacruz/inventree-zebra-plugin/issues" class="no-underline" aria-label="open the issue tracker">
 | 
						||
        <div>
 | 
						||
          <h4 class="plugin_links">Issue Tracker <i class="fa-solid fa-arrow-up-right-from-square" title="External link"></i>
 | 
						||
</h4>
 | 
						||
        </div>
 | 
						||
        </a>
 | 
						||
        
 | 
						||
 | 
						||
        
 | 
						||
        <a href="https://github.com/SergeoLacruz/inventree-zebra-plugin" class="no-underline" aria-label="open source on GitHub">
 | 
						||
        <div>
 | 
						||
          <h4 class="plugin_links">Sourcecode on GitHub <i class="fa-solid fa-arrow-up-right-from-square" title="External link"></i>
 | 
						||
</h4>
 | 
						||
          <p class="font-normal">SergeoLacruz/inventree-zebra-plugin</p>
 | 
						||
        </div>
 | 
						||
        </a>
 | 
						||
        
 | 
						||
        
 | 
						||
        
 | 
						||
 | 
						||
        <div>
 | 
						||
          <h4 class="plugin_links">Categories</h4>
 | 
						||
          <div>
 | 
						||
            
 | 
						||
            <a href="/plugins/categories/#printer"><span class="plugin_cat">Printer</span></a>
 | 
						||
            
 | 
						||
          </div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <div>
 | 
						||
          <h4 class="plugin_links">Tags</h4>
 | 
						||
          <div>
 | 
						||
            
 | 
						||
            <a href="/plugins/tags/#label"><span class="plugin_tag">Label</span></a>
 | 
						||
            
 | 
						||
            <a href="/plugins/tags/#printer"><span class="plugin_tag">Printer</span></a>
 | 
						||
            
 | 
						||
            <a href="/plugins/tags/#zebra"><span class="plugin_tag">Zebra</span></a>
 | 
						||
            
 | 
						||
            <a href="/plugins/tags/#zpl"><span class="plugin_tag">ZPL</span></a>
 | 
						||
            
 | 
						||
          </div>
 | 
						||
        </div>
 | 
						||
      </div>
 | 
						||
    </div>
 | 
						||
</div>
 | 
						||
 | 
						||
</article>
 | 
						||
 | 
						||
    </div>
 | 
						||
 | 
						||
    <div class="flex-grow"></div>
 | 
						||
    <div class="flex-none">
 | 
						||
        <footer class="cm-gray-2 body-font">
 | 
						||
  <div class="container px-5 pt-8 mx-auto flex md:flex-row md:flex-nowrap flex-wrap flex-col">
 | 
						||
    <div class="w-64 flex-shrink-0 md:mx-0 mx-auto text-center md:text-left">
 | 
						||
      <div class="flex title-font font-medium items-center md:justify-start justify-center cm-gray-1">
 | 
						||
        <img src="/assets/logo.png" alt="logo" height="32" width="32" class="h-8">
 | 
						||
        <span class="ml-3 text-xl">InvenTree</span>
 | 
						||
      </div>
 | 
						||
      <p class="mt-2 text-sm cm-gray-3">Intuitive Inventory Management</p>
 | 
						||
    </div>
 | 
						||
 | 
						||
    <div class="flex-grow flex flex-wrap md:pl-10 mb-1 md:mt-0 mt-10 md:text-left text-center md:justify-left justify-center">
 | 
						||
    
 | 
						||
    
 | 
						||
      <div class="md:w-1/4 px-4">
 | 
						||
        <h2 class="footer-categorie title-font">
 | 
						||
          Quick
 | 
						||
        </h2>
 | 
						||
        <nav class="list-none mb-10"><ul>
 | 
						||
          
 | 
						||
          <li><a href="/demo.html" class="footer-link">Demo</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/deploy.html" class="footer-link">Deploy</a></li>
 | 
						||
          
 | 
						||
          <li><a href="https://docs.inventree.org/en/stable/" class="footer-link">Docs</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/news" class="footer-link">News</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/plugins" class="footer-link">Plugin List</a></li>
 | 
						||
          
 | 
						||
        </ul></nav>
 | 
						||
      </div>
 | 
						||
    
 | 
						||
      <div class="md:w-1/4 px-4">
 | 
						||
        <h2 class="footer-categorie title-font">
 | 
						||
          <a href="/extend/">Ecosystem</a>
 | 
						||
        </h2>
 | 
						||
        <nav class="list-none mb-10"><ul>
 | 
						||
          
 | 
						||
          <li><a href="/extend/api.html" class="footer-link">API</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/extend/app.html" class="footer-link">App</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/extend/plugin/" class="footer-link">Plugins</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/extend/integrate/" class="footer-link">Integrations</a></li>
 | 
						||
          
 | 
						||
        </ul></nav>
 | 
						||
      </div>
 | 
						||
    
 | 
						||
      <div class="md:w-1/4 px-4">
 | 
						||
        <h2 class="footer-categorie title-font">
 | 
						||
          Sitemap
 | 
						||
        </h2>
 | 
						||
        <nav class="list-none mb-10"><ul>
 | 
						||
          
 | 
						||
          <li><a href="/about/" class="footer-link">About</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/alternatives/" class="footer-link">Alternatives</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/blog" class="footer-link">Blog</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/contribute.html" class="footer-link">Contribute</a></li>
 | 
						||
          
 | 
						||
          <li><a href="/support.html" class="footer-link">Support</a></li>
 | 
						||
          
 | 
						||
        </ul></nav>
 | 
						||
      </div>
 | 
						||
    
 | 
						||
    </div>
 | 
						||
  </div>
 | 
						||
 | 
						||
  <div class="bg-gray-100">
 | 
						||
    <div class="container mx-auto py-4 px-5 flex flex-wrap flex-col sm:flex-row">
 | 
						||
      <p class="cm-gray-2 text-sm text-center sm:text-left">© 2021-now InvenTree by<a href="https://github.com/inventree" rel="noopener" class="cm-gray-2 ml-1" target="_blank">@inventree</a>— website made with ♥ by<a href="https://github.com/matmair" rel="noopener" class="cm-gray-2 ml-1" target="_blank">@matmair</a></p>
 | 
						||
      <span class="inline-flex sm:ml-auto sm:mt-0 mt-2 justify-center sm:justify-start">
 | 
						||
        <span class="invisible"><a rel="me" href="https://chaos.social/@InvenTree">Mastodon</a></span>
 | 
						||
        <a href="https://github.com/inventree/inventree" alt="github repo" class="ml-3 cm-gray-3">
 | 
						||
          <img class="h-5 w-5" alt="GitHub logo" src="/assets/github.svg">
 | 
						||
        </a>
 | 
						||
        <a href="https://reddit.com/r/inventree" alt="Reddit" class="ml-3 cm-gray-3">
 | 
						||
          <img class="h-5 w-5" alt="Reddit logo" src="/assets/reddit.svg">
 | 
						||
        </a>
 | 
						||
        <a href="https://twitter.com/inventreedb" alt="Twitter" class="ml-3 cm-gray-3">
 | 
						||
          <img class="h-5 w-5" alt="Twitter logo" src="/assets/twitter.svg">
 | 
						||
        </a>
 | 
						||
        <a href="https://chaos.social/@InvenTree" rel="me" alt="Mastodon" class="ml-3 cm-gray-3">
 | 
						||
          <img class="h-5 w-5" alt="Mastodon logo" src="/assets/mastodon.svg">
 | 
						||
        </a>
 | 
						||
      </span>
 | 
						||
    </div>
 | 
						||
  </div>
 | 
						||
</footer>
 | 
						||
 | 
						||
    </div>
 | 
						||
</body>
 | 
						||
 | 
						||
</html>
 |