Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make genral setting to find printer terminal with one command #74

Open
mikebgrep opened this issue Oct 30, 2021 · 22 comments
Open
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@mikebgrep
Copy link

mikebgrep commented Oct 30, 2021

I like the library but I can't understand how to set a method with witch will connect to the terminal printer.If the printer is network based with Ip and port or the printer is connected to laptop/pc with a cable I am not very familiar with the connection types.I need this for a project witch the user can use what terminal printer he have.I need with one general setting the user can connect the printer.I am open to any suggestions.

If I use this example I need to change only the printer name value with the name of actual printer

PrintService printService = PrinterOutputStream.getPrintServiceByName("printerName");
 PrinterOutputStream printerOutputStream = new PrinterOutputStream(printService);
 EscPos escpos = new EscPos(printerOutputStream);
 escpos.writeLF("Hello Wold");
 escpos.feed(5);
 escpos.cut(EscPos

if so what printers support can you give me live example for printer name

@mikebgrep mikebgrep added help wanted Extra attention is needed question Further information is requested labels Oct 30, 2021
@mikebgrep
Copy link
Author

mikebgrep commented Nov 3, 2021

Thank you actually is very simple to configure.Just one more question do in this case will print correct I don't have printer to test: If not how to print data from arraylist
pos

@anastaciocintra
Copy link
Owner

I don't know if it exists escpos printer emulator or simulator, but it is possible.
For now, the best way to test it is sending the content to one "real thermal printer"

@mikebgrep
Copy link
Author

Ok thank you I found emulator Just another question when i print the recipient when i don''t do escpos.close() it appear this in the emulator to much free space between each print (I don't know maybe is from emulator) and the name of the market got in cut_full section.If i close escpos.close(); I can't print again any hint here.Regards

<<CUT_FULL>>M0My Market

Client: John Doe

Product Demo product 1 name x3 17.97


TOTAL 17.97

Date: 06-11-2021 Time: 12:06:57

@mikebgrep
Copy link
Author

`M0�E �!"�-0�a1�2�B My Market
�M0�E �! �-0�a0�2�B

�M0�E��! �-1�a0�3 �B RECEIPT
�M0�E��! �-1�a0�3 �B -----------------
�M0�E �! �-0�a0�2�B

�M0�E �! �-0�a0�2�B Item Unit Price Amount
�M0�E �! �-0�a0�2�B ----------------------------------------
�M0�E �! �-0�a0�2�B

�M0�E �! �-0�a0�2�B Product Demo product 1 name 5.99 17.97
Product Promo Demo product 2 65.99 131.98
Product Promo Demo product 3 10.99 21.98

�M0�E �! �-0�a0�2�B ----------------------------------------
�M0�E �! �-0�a0�2�B

�M0�E��! �-0�a0�3 �B TOTAL 171.93
�M0�E �! �-0�a0�2�B ----------------------------------------
�M0�E �! �-0�a0�2�B Thank you for shopping with us
�M0�E �! �-0�a0�2�B Have a nice day
�M0�E �! �-0�a0�2�B `

this is my system.out output how do you think this will print ok on real printer?

@anastaciocintra
Copy link
Owner

anastaciocintra commented Nov 6, 2021

Hi @mikebgrep
If you want, you can share your piece of code, and I will print and will send one photo.

Just for fun ...

@mikebgrep
Copy link
Author

Hello again @anastaciocintra
Here is the code https://paste.ofcode.org/zdycXYvJQSWvXRpuLAzakE
Thank you for support.

@anastaciocintra
Copy link
Owner

hi, @mikebgrep,
for compiling purposes, I made some modifications

import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.EscPosConst;
import com.github.anastaciocintra.escpos.Style;
import com.github.anastaciocintra.output.PrinterOutputStream;

import javax.print.PrintService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;


class Order {
    public String tableNumber;
    public ArrayList<OrderProduct> products;
    public double totalPrice;

    public Order(String tableNumber, ArrayList<OrderProduct> products){
        this.tableNumber = tableNumber;
        this.products = products;
        totalPrice = 143.0;
    }
}

class OrderProduct {
    public String productCode;
    public String productName;
    public int productQty;
    public double productPrice;


    public OrderProduct(String productCode, String productName, int productQty, double productPrice) {
        this.productCode = productCode;
        this.productName = productName;
        this.productQty = productQty;
        this.productPrice = productPrice;

    }


    public double getPrice(int qty) {
        return this.productPrice *= qty;
    }

    @Override
    public String toString() {
        String productPriceStr = String.format("%.2f", productPrice);
        String qtyPriceStr = String.format("%.2f", productPrice / productQty);
        return "Product " + productName + " " + qtyPriceStr + "  " + productPriceStr + "\n";
    }

}

    public class MikebGrep {

    void printRecipent(String printerName){

//        public void loadData() {
            ArrayList<OrderProduct> products = new ArrayList();
            OrderProduct orderProd = new OrderProduct("4324", "demo product 1", 1,14.4);
            OrderProduct orderProd1 = new OrderProduct("4324", "demo product 2", 1,14.4);
            OrderProduct orderProd2= new OrderProduct("4324", "demo product 3", 1,14.4);
            products.add(orderProd);
            products.add(orderProd1);
            products.add(orderProd2);

            Order order = new Order("1", products);
//        }


        //this call is slow, try to use it only once and reuse the PrintService variable.
        PrintService printService = PrinterOutputStream.getPrintServiceByName(printerName);
        try {
            PrinterOutputStream printerOutputStream = new PrinterOutputStream(printService);
            EscPos escpos = new EscPos(printerOutputStream);

            Style title = new Style()
                    .setFontSize(Style.FontSize._3, Style.FontSize._3)
                    .setJustification(EscPosConst.Justification.Center);

            Style subtitle = new Style(escpos.getStyle())
                    .setBold(true)
                    .setUnderline(Style.Underline.OneDotThick);
            Style bold = new Style(escpos.getStyle())
                    .setBold(true);

            escpos.writeLF("My Business")
                    .feed(3)
                    .writeLF(subtitle, "       RECEIPT")
                    .writeLF(subtitle," -----------------             ")
                    .feed(2)
                    .writeLF("Item          Unit Price          Amount")
                    .writeLF("----------------------------------------")
                    .feed(2)
                    .writeLF(order.products.toString().replace("[", "").replace("]", "").replace(",", "") + "\n")
                    .writeLF("----------------------------------------")
                    .feed(2)
                    .writeLF(bold,
                            "TOTAL                            $" + order.totalPrice)
                    .writeLF("----------------------------------------")
                    .writeLF("     Thank you for shopping with us     ")
                    .writeLF("            Have a nice day             ")

                    .feed(8)
                    .cut(EscPos.CutMode.FULL);



            // do not forget to close...
            escpos.close();

        } catch (IOException ex) {
            Logger.getLogger(MikebGrep.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public static void main(String[] args) {
        if(args.length!=1){
            System.out.println("Usage: java -jar getstart.jar (\"printer name\")");
            System.out.println("Printer list to use:");
            String[] printServicesNames = PrinterOutputStream.getListPrintServicesNames();
            for(String printServiceName: printServicesNames){
                System.out.println(printServiceName);
            }

            System.exit(0);
        }
        MikebGrep obj = new MikebGrep();
        obj.printRecipent(args[0]);


    }
}

mikebgrep_output

@mikebgrep
Copy link
Author

mikebgrep commented Nov 6, 2021

Okay that's look kind of good just curious do the second receipt print the same.Because on the emulator cut paper command appear in the market name line.Thank you again is looking nice if you decide to test it with two recipient in a row message me if its ok or not.(Maybe is from emulator ).I see you close the escpos at the end when I do that i got java.io.IOException: Pipe closed and I can't print anymore what I need to do to print again I reuse tcpOutputStream.Thank you

@mikebgrep
Copy link
Author

I am on Ubuntu maybe this is the problem I see same issue described

@anastaciocintra
Copy link
Owner

I see you close the escpos at the end when I do that i got java.io.IOException: Pipe closed and I can't print anymore what I need to do to print again I reuse tcpOutputStream.Thank you

Answer: Yeap, its necessary to close and its not reusable,

"Streams have a BaseStream.close() method and implement AutoCloseable, but nearly all stream instances do not actually need to be closed after use. Generally, only streams whose source is an IO channel (such as those returned by Files.lines(Path, Charset)) will require closing. Most streams are backed by collections, arrays, or generating functions, which require no special resource management. (If a stream does require closing, it can be declared as a resource in a try-with-resources statement.)"

the stream can be reused?

"A stream should be operated on (invoking an intermediate or terminal stream operation) only once. This rules out, for example, "forked" streams, where the same source feeds two or more pipelines, or multiple traversals of the same stream. A stream implementation may throw IllegalStateException if it detects that the stream is being reused"

source: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

in this case, you need to re-create the instance...
you can make something like this:

            // another ticket ... another time...
            printerOutputStream = new PrinterOutputStream(printService);
            escpos = new EscPos(printerOutputStream);

            escpos.writeLF(title,"My Market")
                    .feed(3)
                    .write("Client: ")
                    .writeLF(subtitle, "John Doe")
                    .feed(3)
                    .writeLF("Cup of coffee                      $1.00")
                    .writeLF("Botle of water                     $0.50")
                    .writeLF("----------------------------------------")
                    .feed(2)
                    .writeLF(bold,
                            "TOTAL                              $1.50")
                    .writeLF("----------------------------------------")
                    .feed(8)
                    .cut(EscPos.CutMode.FULL);
            escpos.close();
            
            // another ticket ... another time...
            printerOutputStream = new PrinterOutputStream(printService);
            escpos = new EscPos(printerOutputStream);
            escpos.writeLF(title,"My Market")
                    .feed(3)
                    .write("Client: ")
                    .writeLF(subtitle, "John Doe")
                    .feed(3)
                    .writeLF("Cup of coffee                      $1.00")
                    .writeLF("Botle of water                     $0.50")
                    .writeLF("----------------------------------------")
                    .feed(2)
                    .writeLF(bold,
                            "TOTAL                              $1.50")
                    .writeLF("----------------------------------------")
                    .feed(8)
                    .cut(EscPos.CutMode.FULL);
            escpos.close();

@anastaciocintra
Copy link
Owner

Hey, did you find any escpos emulator? is it open source? can you share any tip with the us?

@mikebgrep
Copy link
Author

mikebgrep commented Nov 6, 2021

Yes is this one https://github.com/dacduong/escpos-printer-simulator is working like tcpip terminal,
Just run the jar file and set to port 9100 host localhost and its printing in emulator but its not like with real terminal printer

@mikebgrep
Copy link
Author

Its work fine I miss to re-create the instance.

@anastaciocintra
Copy link
Owner

Yes is this one https://github.com/dacduong/escpos-printer-simulator is working like tcpip terminal, Just run the jar file and set to port 9100 host localhost and its printing in emulator but its not like with real terminal printer

good, thank you

@anastaciocintra
Copy link
Owner

Its work fine I miss to re-create the instance.

nice, count on me if you have any other problematic situation.

@mikebgrep
Copy link
Author

mikebgrep commented Nov 12, 2021

@anastaciocintra I just noticed on your receipt amount of the products its not double instead of 14.40 is 1440 and end price must be 14.40 x 3 not $143.00 witch on the emulator is not like this.Can you make a test again the problem must be on that line order.products.toString().replace("[", "").replace("]", "").replace(",", "") + "\n") try to remove replace("," "") if its appear like this again.If you have time Thank you

Edit 143.00 is right but why dot in Amount and Unit Price don't show can you check this thank you

@mikebgrep
Copy link
Author

@anastaciocintra can you propose some solution for printing from list not with the toString() method.
Regards,
Mike

@anastaciocintra
Copy link
Owner

Hi @mikebgrep,
You are saying about transform one list of content like {item1, item2...}
to something like:

(PRINTED CONTENT)
list of products:
- item1
- item2
- item3

isn't it?

@mikebgrep
Copy link
Author

@anastaciocintra yes do you have a solution of it.With toString() method the values of the double don't show properly on the receipt.At least I see in the test you make for me.

@anastaciocintra
Copy link
Owner

Sure man, we have some, for example map with streams, but I think that your algorithm is pretty good and I made some little trick format adjusts , congrats, you have made a good printed receipt work!

receipt

import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.EscPosConst;
import com.github.anastaciocintra.escpos.Style;
import com.github.anastaciocintra.output.PrinterOutputStream;

import javax.print.PrintService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;


class Order {
    public String tableNumber;
    public ArrayList<OrderProduct> products;
    public double totalPrice;

    public Order(String tableNumber, ArrayList<OrderProduct> products){
        this.tableNumber = tableNumber;
        this.products = products;
        totalPrice = 143.0;
    }
}

class OrderProduct {
    public String productCode;
    public String productName;
    public int productQty;
    public double productPrice;


    public OrderProduct(String productCode, String productName, int productQty, double productPrice) {
        this.productCode = productCode;
        this.productName = productName;
        this.productQty = productQty;
        this.productPrice = productPrice;

    }


    public double getPrice(int qty) {
        return this.productPrice * qty;
    }

    @Override
    public String toString() {
        String productPriceStr = String.format("%.2f x %d", productPrice,productQty);
        String qtyPriceStr = String.format("%.2f", getPrice(productQty));
        return String.format("%-15s%12s   %10s",productName,productPriceStr, qtyPriceStr );
    }

}

    public class MikebGrep {

    void printRecipent(String printerName){

//        public void loadData() {
            ArrayList<OrderProduct> products = new ArrayList();
            OrderProduct orderProd = new OrderProduct("4324", "demo product 1", 1,14.4);
            OrderProduct orderProd1 = new OrderProduct("4324", "demo product 2", 2,30.4);
            OrderProduct orderProd2= new OrderProduct("4324", "demo product 3", 8,74.8);
            products.add(orderProd);
            products.add(orderProd1);
            products.add(orderProd2);

            Order order = new Order("1", products);
//        }


        //this call is slow, try to use it only once and reuse the PrintService variable.
        PrintService printService = PrinterOutputStream.getPrintServiceByName(printerName);
        try {
            PrinterOutputStream printerOutputStream = new PrinterOutputStream(printService);
            EscPos escpos = new EscPos(printerOutputStream);

            Style title = new Style()
                    .setFontSize(Style.FontSize._3, Style.FontSize._3)
                    .setJustification(EscPosConst.Justification.Center);

            Style subtitle = new Style(escpos.getStyle())
                    .setBold(true)
                    .setUnderline(Style.Underline.OneDotThick);
            Style bold = new Style(escpos.getStyle())
                    .setBold(true);

            escpos.writeLF(title,"Mikebgrep\n")
                    .writeLF(title,"C o f f e e")
                    .feed(3)
                    .writeLF(subtitle.setJustification(EscPosConst.Justification.Center), "R E C E I P T")
                    .feed(2)
                    .writeLF("Item              Unit Price      Amount")
                    .writeLF("----------------------------------------")
                    .feed(2);
            order.totalPrice =0;
            for(OrderProduct product: order.products){
                escpos.writeLF(product.toString());
                order.totalPrice += product.getPrice(product.productQty);
            }

            String total = String.format("$ %.2f", order.totalPrice);
            escpos.writeLF("----------------------------------------")
                    .feed(2)
                    .writeLF(bold,
                            "TOTAL                         " + String.format("%10s",total))
                    .writeLF("----------------------------------------")
                    .writeLF("     Thank you for shopping with us     ")
                    .writeLF("            Have a nice day             ")

                    .feed(8)
                    .cut(EscPos.CutMode.FULL);



            // do not forget to close...
            escpos.close();


        } catch (IOException ex) {
            Logger.getLogger(MikebGrep.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public static void main(String[] args) {
        if(args.length!=1){
            System.out.println("Usage: java -jar getstart.jar (\"printer name\")");
            System.out.println("Printer list to use:");
            String[] printServicesNames = PrinterOutputStream.getListPrintServicesNames();
            for(String printServiceName: printServicesNames){
                System.out.println(printServiceName);
            }

            System.exit(0);
        }
        MikebGrep obj = new MikebGrep();
        obj.printRecipent(args[0]);


    }
}

@mikebgrep
Copy link
Author

mikebgrep commented Nov 30, 2021

@anastaciocintra Thank you man that is awesome.I actually try one time to do for each loop in the builder but I don't know why everything was red.But this is proper receipt.Thank you again.
ps: I was missing a ; to can make the for loop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants