I'm developing a POS system with Java SE. I need to print long bill like supermarket bills.
I'm hoping to use EPSON TM-U220D(https://www.epson.eu/products/sd/pos-printer/epson-tm-u220b-series) as receipt printer.
But the problem is receipt printing stop after some length. I have used java.awt.print.PrinterJob to generate receipt and print. I found the code from internet. But it is not printing the receipt as expected.
This is the code I'm using in my program:
BillPrinter {
private DBQuery dbq;
private String billid;
private Bill bill;
private BillItem billitems[];
private int maxTextLength = 34;
private int y = 0;
private int yShift = 10;
public BillPrinter(DBQuery dbq) {
this.dbq = dbq;
}
public void printBill(String billid) {
this.billid = billid;
try {
bill = dbq.getBillByBillID(billid);
if (bill != null) {
billitems = dbq.getBillItemByBill(bill);
System.out.println(bill.getBillid() + " - " + bill.getId());
if (billitems.length > 0) {
PrinterJob printerJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = printerJob.defaultPage();
Paper paper = new Paper();
paper = new Paper();
double **middleHeight** = billitems.length * 0.1;
double **headerHeight** = 0.5;
double **footerHeight** = 0.5;
double **width** = convert_CM_To_PPI(7);
double **height** = convert_CM_To_PPI(headerHeight + middleHeight + footerHeight);
paper.setSize(width, height);
pageFormat.setPaper(paper);
pageFormat.setOrientation(PageFormat.PORTRAIT);
paper.setImageableArea(
convert_CM_To_PPI(0.025),
convert_CM_To_PPI(0.05),
width - convert_CM_To_PPI(0.035),
height - convert_CM_To_PPI(0.1)
);
printerJob.setPrintable(new BillPrintable(), pageFormat);
try {
printerJob.print();
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
}
} catch (NullPointerException npe) {
npe.printStackTrace();
}
}
private double convert_CM_To_PPI(double cm) {
return toPPI(cm * 0.393600787);
}
private double toPPI(double inch) {
return inch * 72d;
}
public class BillPrintable implements Printable {
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
int result = NO_SUCH_PAGE;
if (pageIndex == 0) {
y = 10;
Graphics2D g2d = (Graphics2D) graphics;
g2d.translate((double) pageFormat.getImageableX(), (double)pageFormat.getImageableY());
try {
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "----------------------------------");
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "<Company Name>");
g2d.setFont(new Font("Monospaced", Font.PLAIN, 10));
TextLengthFormater(g2d, "<Address>");
TextLengthFormater(g2d, "<Contact>");
TextLengthFormater(g2d, "<Email>");
TextLengthFormater(g2d, "<Website>");
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "----------------------------------");
g2d.setFont(new Font("Monospaced", Font.PLAIN, 8));
TextLengthFormater(g2d, "Bill ID: " + billid);
TextLengthFormater(g2d, "Date: " + bill.getDate());
TextLengthFormater(g2d, "Description: " + bill.getDescription());
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "----------------------------------");
g2d.setFont(new Font("Monospaced", Font.PLAIN, 8));
for (int i = 0; i < billitems.length; i++) {
TextLengthFormater(g2d, billitems[i].getItem().getName());
StringBuilder sb = new StringBuilder("");
sb = addStringTo(sb, Integer.toString(billitems[i].getQuntity()), 3);
sb = addStringTo(sb, "X", 5);
sb = addStringTo(sb, Double.toString(billitems[i].getItem().getPrice()), 10);
sb = addStringTo(sb, "=", 5);
double amount = (billitems[i].getItem().getPrice() * billitems[i].getQuntity());
sb = addStringTo(sb, Double.toString(amount), 10);
TextLengthFormater(g2d, sb.toString());
}
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "----------------------------------");
g2d.setFont(new Font("Monospaced", Font.PLAIN, 8));
double total = bill.getTotal() * 100 /(100 - billitems[0].getDiscount());
TextLengthFormater(g2d, "Total: " + addStringTo(new StringBuilder(), Double.toString(total), 26).toString());
TextLengthFormater(g2d, "Discount: " + addStringTo(new StringBuilder(), Double.toString(total - bill.getTotal()), 23).toString());
TextLengthFormater(g2d, "Sub Total: " + addStringTo(new StringBuilder(), Double.toString((bill.getTotal())), 22).toString());
TextLengthFormater(g2d, "Pay: " + addStringTo(new StringBuilder(), Double.toString(bill.getPayment()), 28).toString());
TextLengthFormater(g2d, "Change: " + addStringTo(new StringBuilder(), Double.toString(bill.getPayment() - (bill.getTotal())), 25).toString());
g2d.setFont(new Font("Monospaced", Font.BOLD, 10));
TextLengthFormater(g2d, "----------------------------------");
TextLengthFormater(g2d, " THANK YOU");
TextLengthFormater(g2d, "----------------------------------");
} catch (Exception r) {
r.printStackTrace();
}
result = PAGE_EXISTS;
}
return result;
}
}
private void TextLengthFormater(Graphics2D g2d, String text) {
Vector<String> vtr = new Vector<String>();
while (text.length() > 0) {
vtr.add(text.substring(0, (text.length() > maxTextLength ? maxTextLength : text.length())));
text = text.substring((text.length() > maxTextLength ? maxTextLength : text.length()));
}
for (String str : vtr) {
g2d.drawString(str, 0, y);
y += yShift;
}
}
private StringBuilder addStringTo(StringBuilder sb, String value, int place) {
int count = 0;
while (value.length() + count < place) {
sb.append(" ");
count++;
}
sb.append(value);
return sb;
}}
What is the problem and how can I solve it?
I think that, I'm not setting the right parameters at middleHeight, headerHeight, footerHeight, width and height.
Also I think it is problem with printer that printer only can print for that length only.
Or is there problem in my code to stop printing? is there another way of printing long receipt?
how can I solve it?
Your help would be greatly appreciated!