How to Print Barcode Labels

Hi
I am using erpnext12
getting like this output
Product name not showing properly

Ispired by @gsarunk I have made custom format for barcode price labels that looks like this.

I have made it to perfectly fit 4x10 (40) labels per A4 paper size, including for safety margins of 5 mm.
But I canā€™t figure out how to print more than one item. And how to include price from a price list.
So what I want to achieve is:

  1. On item list page, select all items you wish to print. Go to action>print and select print format. Print.
    I am guessing that it will be something like {{% for item in items %}}, but I donā€™t know where to look for field names I need to use.
  2. On item label I want to define from which price list is price taken. And to put that price on label.

Thanks in advance.

Here is my html and css code. I improved on @gsarunk code by first checking if barcode is available.

HTML:

<div class="dashboard-section">
  <div class="barcode-label-container">
    <div id="barcode-label" class="barcode-label">
      <div class="label-item-name label-field">
          {{ doc.item_name }}
      </div>
      <div class="label-item-price label-field">
          34.000,00
          <!--{{ doc.standard_rate }}          -->
      </div>
      {% if doc.barcodes %}
      <div class="label-item-code label-field">
       {{ doc.item_code  }}
      </div>
      <div class="label-item-barcode label-field">
        <div class="barcode-container">
            <svg class="barcode" jsbarcode-format="ean13" jsbarcode-value={{ doc.barcodes[0].barcode }} jsbarcode-height=23
            jsbarcode-width="1" js-barcode-fontsize=1 jsbarcode-textmargin="2" jsbarcode-margin="0" jsbarcode-fontoptions="bold">
        </svg>
        </div>
      </div>
      {% else %}
      <div class="label-item-code-alone label-field">
       {{ doc.item_code  }}
      </div>
      {% endif %}
    </div>
  </div>
</div>

		
<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.0/dist/JsBarcode.all.min.js"></script>
<script>

JsBarcode(".barcode").init();
</script>

CSS:

.barcode-label{
    height: 29mm;
    width: 50mm;
}
.barcode-label {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  gap: 0px 0px;
  justify-items: center;
    align-items: center;
  grid-template-areas:
    "label-item-name label-item-name label-item-name label-item-name"
    "label-item-price label-item-price label-item-price label-item-price"
    "label-item-code label-item-barcode label-item-barcode label-item-barcode";
    
}

.label-item-name { 
    grid-area: label-item-name;
    font-size: 3mm;
    width: 50mm;
    height: 10mm;
    line-height: 3.5mm;
    z-index: 1;
    overflow: hidden;
}

.label-item-price { 
    grid-area: label-item-price;
    font-size: 2em;
    font-weight: 600;
    width: 50mm;
    height: 8mm;
}

.label-item-code { 
    grid-area: label-item-code;
    width: 15mm;
    height: 11mm;
    font-size: 2.5mm;
    overflow-wrap: break-word;
    
    
}

.label-item-code-alone { 
    grid-area: label-item-code;
    width: 25mm;
    height: 11mm;
    font-size: 2.5mm;
    overflow-wrap: break-word;
}

.label-item-barcode { 
    grid-area: label-item-barcode;
    width: 35mm !important;
    height: 12mm;
    font-size: 0.5em;
    
}
.barcode-container{
    max-width: 100%;
    max-height: 100%;
    
}
.barcode-label-container {
border: 1px solid #d1d8dd;
width: fit-content;
overflow: hidden;
}
.print-format, .barcode-label-container, .dashboard-section{
margin: 0;
padding: 0;
}
.label-field{
    
    padding: 1mm;
    //border: 1px solid black;
    text-align: center;
    
}
1 Like

You need to loop through the barcode not the CSS.

{%- for item in doc.items -%}
{% set item_barcode = frappe.get_doc("Item Barcode", {"parent": item.item_code, "idx": 1,}) %}
{% set item_details = frappe.get_doc("Item", item.item_code) %}
{% for i in range((item.qty) |round|int ) %}


    <div class="dashboard-section pagebreak">
      <div class="barcode-label-container">
        <div id="barcode-label" class="barcode-label">
          <div class="barcode-header">Style Advisor</div>
          
         
          
          <div class="text-center barcode-area">
              <svg class="barcode"
                  jsbarcode-format="ean13"
                  jsbarcode-value= {{ item_barcode.barcode }}
                  jsbarcode-height = 25
                  jsbarcode-width = 1
                  js-barcode-fontSize = 10
                  jsbarcode-textmargin="0"
    
                  jsbarcode-fontoptions="bold">
              </svg>
          </div>
          <div class="barcode-text">
            <span class="barcode-strong">{{ item.item_name }}</span>
          </div>
          {% if item_details.standard_rate %}
              <div class="barcode-foot barcode-strong barcode-rotated">
                {{ item_details.get_formatted("standard_rate", doc)  }} 
               
              </div>
          {% endif %}
        </div>
      </div>
    </div>
{% endfor %}

{%- endfor-%}

The above is the one i have created for printing multiple barcodes for all items and quantity during a material receipt. Similarly you can adapt it for your use case.

3 Likes

Thanks for sharing step by step points

But I need to know one more thing how I can split that into 2 r 5 columns,
For more clarification, Iā€™ve attached a screenshot below
image

This should be a pure CSS work. If you are good at CSS you can achieve this. I am not an CSS expert though :slight_smile:

Fine, Thanks for reply

I did that but on click of print, browser simply displaying {body}
image

Is this working with version 13

Try adding CSS within the html section. I found sometimes the CSS does not work properly. So I usually add it to the HTML section. Most of the time this worked fine.

1 Like

Iā€™m trying in v12

yes working in v13

@gsarunk Thanks a lot

1 Like

i have given the print format as given but barcode is not showing in print in version 13


print format HTML

<div class="dashboard-section">
      <div class="barcode-label-container">
        <div id="barcode-label" class="barcode-label">
          <div class="barcode-header">Test</div>
          <div class="barcode-text">
            <span class="barcode-strong">{{ doc.item_name }}</span>
          </div>
          <div class="text-center">
              <svg class="barcode"
                  jsbarcode-format="ean13"
                  jsbarcode-value= {{ doc.barcodes[0].barcode }}
                  jsbarcode-height = 30
                  jsbarcode-width = "1.5"
                  js-barcode-fontSize = 10
                  jsbarcode-textmargin="0"

                  jsbarcode-fontoptions="bold">
              </svg>
          </div>
          <div class="barcode-foot barcode-strong barcode-rotated">
           {{ doc.get_formatted("standard_rate", doc)  }}
          </div>
        </div>
      </div>
    </div>

    		
    <script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.0/dist/JsBarcode.all.min.js"></script>
    <script>

    JsBarcode(".barcode").init();
    </script>

CSS

.dashboard-section {
display: flex;
flex-flow: row nowrap;
align-items: flex-end;
}
.dashboard-section > button {
margin-left: 10px;
}
.barcode-label-container {
border: 1px solid #d1d8dd;
width: fit-content;
overflow: hidden;
}
.barcode-label {
background-color: #ffffff;
color: #000000;
box-sizing: border-box;
height: 34mm;
width: 64mm;
padding: 1.5mm;
display: grid;
grid-template-columns: 1fr 6mm;
grid-template-rows: 4mm 1fr 17.5mm;
grid-template-areas: ā€˜header footerā€™ ā€˜text footerā€™ ā€˜barcode footerā€™;
font-family: monospace;
font-size: 8pt;
line-height: 1.2;
text-align: center;
}
.barcode-rotated {
line-height: 6mm;
transform: translate(calc(-12.5mm), 0) rotate(-90deg);
transform-origin: center center;
height: 6mm;
width: calc(31mm);
}
.barcode-header {
grid-area: header;
text-transform: uppercase;
}
.barcode-text {
grid-area: text;
height: calc(28.8pt);
overflow-y: hidden;
align-self: center;
}
.barcode-area {
grid-area: barcode;
align-self: center;
}
.barcode-foot {
grid-area: footer;
font-size: 1.4em;
align-self: center;
}
.barcode-strong {
font-weight: bold;
}

Do you have access to the internet ?

Cause you need it to read this.
If you do not want to give access to internet then host this file locally and point it to the local address.

So far the CSS seem to work in your screenshot only barcode is missing.

Can it be a conflict ?

In v13 I can see JsBarcode has been included in frappe node module

I have the same difficulty with v13 too and I can confirm I have the internet access

Can you recheck the same by clicking on the ā€œFull Pageā€ Button if it is being rendered there?

no picture nor barcode rendered.
I even removed all css and no barcode rendered.

Iā€™ve also tried to host the jsbarcode on local server and no barcode rendered either.

Do you know how to debug this print format ? Because itā€™s a blind act here without knowing whatā€™s wrong

Iā€™ve tried to work it out in v13 , and this time mimic-ing frappe repo from this file

frappe\public\js\frappe\form\controls\barcode.js

And another difference is I import the barcode js provided by frappe using this tag :

<script src="assets/frappe/node_modules/jsbarcode/dist/JsBarcode.all.min.js"></script>

The complete my try-out html script is like this :

<div class="dashboard-section">
<div class="barcode-label-container">
<div id="barcode-label" class="barcode-label">
  <div class="barcode-header">TESTER</div>
  <div class="serial-no">
    <span class="barcode-strong">serial number : {{ doc.serial_no }}</span>
  </div>
  <div class="barcode-text">
    <span class="barcode-strong">serial number barcode type : {{ doc.serial_barcode }}</span>
  </div>
  <div class="barcode-text">
    <span class="barcode-info">serial number jsbarcode import </span>
  </div>      

<div class="text-center">
        <span class="barcode-data">
        <svg class="barcode"
          width="100%"
          data-barcode-value="{{ doc.serial_barcode }}"
          >
      </svg>
      </span>
  </div>      

</div>
</div>
</div>

<script type="text/javascript">
   JsBarcode(".barcode", "{{ doc.serial_barcode }}", {
    	format: "code128",
        height: 50,
        fontSize: 16,
        width: 3,
        });
</script>	

<script src="assets/frappe/node_modules/jsbarcode/dist/JsBarcode.all.min.js">   </script>

By using this method, I was able to perform print directly to the printer, but it will not work is the target print is pdf like .

Is there any difference in the method between direct print and pdf print ? Can someone elaborate on this ?

Hi @Tribikram_Sahu

On one of our V13 sites, clicking on ā€œFull Pageā€ made the barcodes visible. Any idea why this behavior ?

Kind regards

I think it has some thing to do with website rendering capabilites offered by the wkhtmltopdf.

In my v13 erpnext full web page view, from what I saw, it was a full standard website that allow javascript execution and the barcode rendered successfully.

But in PDF-like view, the erpnext system only call the wkhtmltopdf get_pdf method, which I believe they do not render the javascript. Iā€™ve tried this by getting the output of the get_pdf() method of frappeā€™s pdf.py file in frappe utils directory and the output was clearly a plain text of jsbarcode javascript without being rendered.

I also notice that in v13 of erpnext, the barcode type is included in the database as an svg tag longtext type , therefore when erpnext print a pdf like page, it doensā€™t render any javascript aymore. Instead, erpnext just show the svg data already saved previously in the database.

1 Like