Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to improve speed with Receipt printer and ESC/POS commands in Java

I have an application that communicates with a thermal printer in Java and makes the thermal printer print receipts with a barcode/emphasis/different sizes and so forth using a Star tsp 100 Printer.

I can make the program print exaclty what i like but the printer is very slow. I believe the reason is that I am using non-preferable way/method of sending the byte commands.

    public static void Command(byte[] bytes) throws Exception{
    //The bytes array is the argument, consisting of a byte[] array such as
    //byte[] Emphasis = {0x1B, 0x45}; //Which gives the text boldness.
    //And Command(Emphasis); To execute the command with this method.
    DocPrintJob job = PrintServiceLookup.lookupDefaultPrintService().createPrintJob();
    DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
    Doc doc = new SimpleDoc(bytes, flavor, null);
    job.print(doc, null);
    }

And when i want to print a String i use this method.

    public void PrintString(String s) throws Exception{
    DocPrintJob job = PrintServiceLookup.lookupDefaultPrintService().createPrintJob();
    System.out.println(job + " <- printer");
    DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
    byte[] b = s.getBytes("CP437");
    Doc doc = new SimpleDoc(b, flavor, null);
    job.print(doc, null);          
}

So i use this method to print the bulk of the String for as long as the text has the same style(Etc no additional commands necessary). So my code that prints the receipts looks somewhat like this.

PrintClass P = new PrintClass();
String Greating = "Hello";
P.Command(P.Emphasis);
P.Command(P.DoubleSize);
P.Command(P.Underline);
P.PrintString(Greating);
P.Command(P.CancelEmphasis);
P.Command(P.ResetSize);
P.Command(P.CancelUnderline);
String body = GenerateReceiptBody();
P.PrintString(body);
P.Command(P.Halfsize);
String footer = Constants.getFooter();
P.PrintString(footer);
P.Command(P.Cut);

The receipt gets printed exactly the way i want but it is a very sluggish process.

I am by no means an expert when it comes to sending POS/ESC commands. I feel however that there must be a better/faster way to do this since many applications can print a receipt with different size/barcode/style/logo without it taking 10-20 seconds.

When the receipt printer comes to a the main bulk or "body" of the receipt where everything has the same size/styling then it goes quickly, this makes me believe that the reason this is going slow for me is because i am making am creating/executing so many individual "print jobs".

So is there any faster way to send ESC/POS commands to a Thermal printer as byte commands ? In this case the thermal printer is a Star tsp 100 but i don't believe that it makes any difference for the answer.

Any answers would be very appreciated. I am sorry if this was an easy question as I am still learning how to code.

like image 934
Orvil Nordström Avatar asked Feb 20 '15 10:02

Orvil Nordström


1 Answers

I have no idea if this will improve your printing speed, but in answer to your question about reducing the number of "print jobs", you could write all the bytes to a stream first, then send the whole stream to a single print job. I've attempted to convert your code to do this.

    public static void test() throws Exception
    {
        ByteArrayOutputStream printData = new ByteArrayOutputStream();

        printData.write(PrintClass.Emphasis);
        printData.write(PrintClass.DoubleSize);
        printData.write(PrintClass.Underline);
        printData.write("Hello".getBytes("CP437"));
        printData.write(PrintClass.CancelEmphasis);
        printData.write(PrintClass.ResetSize);
        printData.write(PrintClass.CancelUnderline);
        printData.write(GenerateReceiptBody().getBytes("CP437"));
        printData.write(PrintClass.Halfsize);
        printData.write(Constants.getFooter().getBytes("CP437"));
        printData.write(PrintClass.Cut);

        printBytes(printData.toByteArray());
    }

    public static void printBytes(final byte[] bytes) throws Exception
    {
        DocPrintJob job = PrintServiceLookup.lookupDefaultPrintService().createPrintJob();
        System.out.println(job + " <- printer");
        DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
        Doc doc = new SimpleDoc(bytes, flavor, null);
        job.print(doc, null);
    }
like image 107
Frank Avatar answered Sep 17 '22 14:09

Frank