0

I am facing this issue where I am generating a barcode using code128 and saving it in a PNG file. The same PNG file when supplied to a printer Job with required Document properties for printing on a Label of required size, the size gets reduced and does not get scanned.

Actual Size for print supplied - 40mm x 15mm. Size printed on the label - 20mm x 10mm

I am adding this attribute to PrintRequestAttributeSet - pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM));

But it is not effected accurately, I tried to play around the x and y parameter value there, still, the size printed falls within 25mm x 10mm.

Any inputs to print the barcode of the required size is highly appreciated. I have given the complete code details below.

(PS: I am using "Honeywell PC42t Plus" Thermal Printer to print and currently my labels are of 700mm x 280mm in size, I am waiting to receive the actual labels of 40mm x 15mm size. So this is to test that, I can print an actual 40mm x 15mm barcode utilizing whole label space once I have the actual labels received)

public class One_TestMyBarcode {

    private static final String MIME_TYPE = "image/x-png";
    private static final String DELIMTER = "-";
    static String image_name = "NewBarcode_One.png";

    public static void main(String[] args) {

        FileInputStream textStream = null;
        int lastSeqNo = 001;
        String roCode= "ERO";

        AtomicInteger seqNo = new AtomicInteger(lastSeqNo);
        Code128Bean code128 = new Code128Bean();
        code128.setHeight(15f);
        //code128.setBarHeight(40f);
        //code128.setModuleWidth(0.3);
        code128.setModuleWidth(0.2);
        code128.setQuietZone(10);
        code128.doQuietZone(true);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, MIME_TYPE, 300, BufferedImage.TYPE_BYTE_BINARY,
                false, 0);

        StringBuffer codeData = new StringBuffer();
        codeData.append(roCode);
        codeData.append(DELIMTER);

        int currentSeqNo = seqNo.getAndIncrement();
        String seq = String.format("%07d", currentSeqNo);
        codeData.append(seq);
        codeData.append(DELIMTER);
        Calendar current = Calendar.getInstance();
        String year = Integer.toString(current.get(Calendar.YEAR)).substring(2);
        codeData.append(year);

        //logger.debug("barcode dimension is ");
        code128.calcDimensions(codeData.toString());
        code128.generateBarcode(canvas, codeData.toString());

        try {
            canvas.finish();
        } catch (IOException e) {
            throw new RuntimeException(e);

        }

        FileOutputStream fos = null;
        try {
            //fos = new FileOutputStream("C:\\Users\\Vinayak\\Desktop\\barcode\\" +image_name);
            fos = new FileOutputStream(image_name);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            //textStream = new FileInputStream("C:\\Users\\Vinayak\\Desktop\\barcode\\" +image_name);
            textStream = new FileInputStream(image_name);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        DocFlavor flavor = DocFlavor.INPUT_STREAM.PNG;

        // Position the default print service
        PrintService printService = PrintServiceLookup.lookupDefaultPrintService();

        // Create a print job
        DocPrintJob job = printService.createPrintJob();

        // Set the print properties
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();

        //printed a very small size (20mm x 10mm) and does not scan
        pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM));


        //DOESN'T Scan Either
        //pras.add(OrientationRequested.LANDSCAPE);
        //pras.add(OrientationRequested.PORTRAIT);
        //pras.add(MediaSizeName.ISO_A10);  

        //Doesn't print at all
        //pras.add(new MediaPrintableArea(0, 0, 40, 15, MediaPrintableArea.MM));


        pras.add(new Copies(1));
        DocAttributeSet das = new HashDocAttributeSet();

        // Specify print content
        Doc doc = new SimpleDoc(textStream, flavor, das);

        // Do not display the print dialog, print directly
        try {
               System.err.println("Loop - print");
               job.print(doc, pras); // Make specific print operations for each page

        } catch (PrintException pe) {
            pe.printStackTrace();
        }

    }

}
Sanjay Sharma
  • 3,687
  • 2
  • 22
  • 38
  • 1
    Is it better to create and print a barcode with the printer's own function than to print a barcode image created with other software? [PC42t Desktop Printer User Guide - Honeywell Scanning and](https://country.honeywellaidc.com/CatalogDocuments/PC42T-EN-UG_Rev_C.pdf), [How to create a Printer Command Code generator in Windows](https://honeywellaidc.force.com/supportppr/s/article/How-to-create-a-Printer-Command-Code-generator-in-Windows) – kunif May 05 '20 at 06:46
  • According to the data sheet, the printer understands ZPL II which is a de-facto-standard printer language for label printers. Printing a Barcode using ZPL II is in my opinion better than doing it over the generic Windows printer driver, fighting with all the annoying driver issues that make the barcode unreadable. – Erich Kitzmueller May 05 '20 at 11:43
  • @kunif, thanks for your comment. I understand your point of view but my current project requirement is to generate the barcode in realtime from a Web Application based on the user login detail and a sequence number and encode this string to Barcode label of 40mm x 15mm size. – Vinayak Satapute May 05 '20 at 16:08
  • @ErichKitzmueller Thanks. I am currently using Honeywell PC42t Plus thermal printer. As per the shared Java code , I am able to call the printer directly and print the barcode, the only issue is the size of the barcode printed is not in expected size. pras.add(MediaSize.findMedia(40, 15, Size2DSyntax.MM)); I expected the label to print the barcode of 40mm x 15mm but actually it generates barcode of 20mm x 10mm size when printed. So I need to get the actual size there. (PS: My current label size is 70mm x 28mm there, I had wrongly mentioned it as 700mm x 280mm in my initial post) – Vinayak Satapute May 05 '20 at 16:13
  • If so, aren't you making a mistake in the value of the resolution and calculation that are the prerequisites for barcode creation? The resolution of the printer is 203dpi. Maybe you need to create a bit image for it and print it dot by dot? – kunif May 05 '20 at 16:16
  • @kunif, yes I am creating the bit image here. ByteArrayOutputStream baos = new ByteArrayOutputStream(); BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, MIME_TYPE, 300, BufferedImage.TYPE_BYTE_BINARY, false, 0); MIME_TYPE = imgage/x-png 300 = Resolution – Vinayak Satapute May 05 '20 at 16:20
  • Probably 300 is the resolution, so try changing it to 203. [Class BitmapCanvasProvider](http://barcode4j.sourceforge.net/trunk/javadocs/org/krysalis/barcode4j/output/bitmap/BitmapCanvasProvider.html) – kunif May 05 '20 at 16:36

2 Answers2

0

You can make your program shorter and faster, and also make sure it always prints a legible barcode, by using the printer language instead of using the barcode printer as if it was a generic printer.

import javax.print.*;

public class PrintUsingZPL {
  public static void main(String[] args) {
    StringBuilder codeData = new StringBuilder();
    codeData.append("Stackoverflow"); // example

    String printCommand = "^XA^LH0,0^FO50,50^BCN,100,Y,N,N^FD"+
                          codeData.toString()+
                          "^FS^XZ";
    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    try {
      DocPrintJob job = printService.createPrintJob();
      Doc doc = new SimpleDoc(printCommand.getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
      job.print(doc, null);
    }
    catch(PrintException e) { /* error handling goes here */ }
  }
}
Erich Kitzmueller
  • 36,381
  • 5
  • 80
  • 102
  • Thanks @ErichKitzmueller for detailed code and info. I used your program to verify the Label printing as it is, the printer just rolled out an empty label. I have left the printer setting to its default values for ZSim, ESim and DPL. (I am using Honeywell PrintSet 5 tool to configure the printer). Am I missing something ? – Vinayak Satapute May 07 '20 at 16:16
  • @VinayakSatapute I inserted a ^LH command in my example program, this command sets the label home - maybe this helps. If not, try a few other values for the ^FO (field origin) command - sometimes a combination of other settings places the barcode completely outside of the label. Make sure your printer is set up to use ZSim as printer language. You might also try to use DPL instead of ZPL II; I think it's the more native language for your printer. – Erich Kitzmueller May 08 '20 at 07:09
0

Thanks @Erich. I have used your given code and updated the printCommand for both ZPL and DP Language. Your updated code (^LH) was able to print the Barcode but it was not getting scanned (not sure, I tried some variation but did not help), so I tried DPL command there as shown in code here, and it was able to print the Barcode and successfully got scanned too. Thank you so much for your help and guidance.


package BARCODE;

import javax.print.*;
import javax.print.PrintService;

public class PrintUsingZPL1 {
  public static void main(String[] args) {
    StringBuilder codeData = new StringBuilder();
    //codeData.append("Stackoverflow"); // example
    codeData.append("CRO-0000100-20"); // example
    String printData = codeData.toString();
    System.out.println("Data for Barcode " +printData);

    /*String printCommand = "^XA^LH0,0^FO50,50^BCN,100,Y,N,N^FD"+
                          codeData.toString()+
                          "^FS^XZ";*/

   /* String printCommand = "PP65,107:AN7\r\n" + 
            "BARSET \"CODE128B\",2,1,1,71\r\n" + 
            "PB \"CRO-0000001-20\"\r\n" + 
            "PP79,37:NASC 8\r\n" + 
            "FT \"CG Triumvirate Condensed Bold\",8,0,98\r\n" + 
            "PT \"CRO-0000001-20\"\r\n" + 
            "LAYOUT RUN \"\"\r\n" + 
            "PF"; */
  String printCommand = "PP35,90:AN7\r\n" + 
    "BARSET \"CODE39A\",3,1,1,67\r\n" + 
    "PB " +codeData.toString()+ "\r\n" + 
    "PP65,23:NASC 9\r\n" + 
    "FT \"Andale Mono Bold\",8,0\r\n" + 
    "PT " +codeData.toString()+ "\r\n" + 
    "LAYOUT RUN \"\"\r\n" + 
    "PF";

    /*String printCommand = "PP65,107:AN7\r\n" + 
            "BARSET \"CODE128B\",2,1,1,71\r\n" + 
            "PB "+printData+"\r\n" + 
            "PP79,37:NASC 8\r\n" + 
            "FT \"CG Triumvirate Condensed Bold\",8,0,98\r\n" + 
            "PT "+printData+"\r\n" + 
            "LAYOUT RUN \"\"\r\n" + 
            "PF";*/

    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    try {
      DocPrintJob job = printService.createPrintJob();
      Doc doc = new SimpleDoc(printCommand.getBytes(), DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
      job.print(doc, null);
    }
    catch(PrintException e) { /* error handling goes here */ }
  }
}

  • Vinayak - Do not forget to accept your answer so that future visitors can also use the solution confidently. Check https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work to learn how to do it. – Arvind Kumar Avinash May 11 '20 at 17:49
  • I'm sorry, I could not respond to your message. It's not that I missed your message...I got the message but became busy with something and later it slipped from my mind. – Arvind Kumar Avinash May 11 '20 at 17:52
  • 1
    Thanks @Arvind, I have updated the answer there for working printCommand. – Vinayak Satapute May 17 '20 at 08:27