I use the code above to print receipt
the issue is when I have more than about 10 items it only prints the 10 items and cut receipt
I noticed this also when I print it with A4 paper it only print one page and stop
is there any way to fix that
SimpleDateFormat df = new SimpleDateFormat();
DecimalFormat decf = new DecimalFormat("#,##0.00");
String SPACES20 = " ";//20 spaces
String SPACES15 = " ";//15 spaces
String SPACES10 = " ";//10 spaces
String SPACES7 = " ";//7 spaces
String SPACES5 = " ";//5 spaces
String uline = "___________________________________________";
String dline = "-------------------------------------------";
String etoileline = "*******************************************";
int x = 0;
int y = 15;
int lineheight = 13;
int rightEdge = 182;
Ticket ticket;
String type = "";
public TicketImpression(Ticket ticket_, String type_){
this.ticket = ticket_;
this.type= type_;
}
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
if (page > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
try {
g2d.drawImage(ImageIO.read(getClass().getResource("/resources/logo_bricosmart_52_50.png")), 67, 5, null);
} catch (IOException e) {
e.printStackTrace();
}
Font font = new Font("Monospaced", Font.BOLD, 10);
g2d.setFont(font);
g2d.drawString("Company Name", 16, 75);
font = new Font("Monospaced", Font.BOLD, 8);
g2d.setFont(font);
int i =1;
g2d.drawString(" Tél : 05-22-44-57-68", x, 93);// Tél
g2d.drawString(" Site web : www.company.ma", x, 101);// site web
y = 101;
// some rows to print ...........
g2d.drawString(" Merci de votre visite", x, y+lineheight*i++);
i++;
g2d.drawString(" ", x, y+lineheight*i++);
return PAGE_EXISTS;
}
public static void ImprimerTicket(Ticket ticket, String type) {
PageFormat format = new PageFormat();
Paper paper = new Paper();
double paperWidth = 3;// 3.25
double paperHeight = 3.69;// 11.69
double leftMargin = 0.05;
double rightMargin = 0.10;
double topMargin = 0;
double bottomMargin = 0.01;
String printer =Utils.printerName;
paper.setSize(paperWidth * 200, paperHeight * 200);
paper.setImageableArea(leftMargin*200, topMargin * 200, (paperWidth - leftMargin - rightMargin) * 200,
(paperHeight - topMargin - bottomMargin) * 200);
format.setPaper(paper);
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(OrientationRequested.PORTRAIT);
try {
PrinterJob job = PrinterJob.getPrinterJob();
PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
printServiceAttributeSet.add(new PrinterName(printer, null));
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, printServiceAttributeSet);
job.setPrintService(printServices[0]);// set printer
format = job.validatePage(format);
job.setPrintable(new TicketImpression(ticket, type), format);
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(new Copies(1));
job.print(pras);
} catch (Exception e) {
e.printStackTrace();
}
}
I call this class like that
TicketImpression.ImprimerTicket(ticketObject, "");
Related
My java thermal printer code not able to print long receipt(more than A4 sheet size). Its work fine normally, but in case where there is too much items in cart then it generate half print. My code is under mentioned-
public PrintReceipt(Map<String,String> hm){
/*
product details code..
*/
try{
input = new FileInputStream("C:/printer.properties");
prop.load(input);
printerName=prop.getProperty("receiptPrinter");
System.out.println("Printer Name "+printerName);
}catch(Exception exception){
System.out.println("Properties file not found");
}
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null,null);
for (int i = 0; i < pservices.length; i++) {
if (pservices[i].getName().equalsIgnoreCase(printerName)) {
job = PrinterJob.getPrinterJob();
PageFormat pf = job.defaultPage();
double margin = 1.0D;
Paper paper = new Paper();
paper.setSize(216D, paper.getHeight());
paper.setImageableArea(margin, margin, paper.getWidth() - margin * 1.5D, paper.getHeight() - margin * 1.5D);
pf.setPaper(paper);
job.setCopies(1);
pf.setOrientation(1);
job.setPrintable(this, pf);
try
{
job.print();
}
catch(PrinterException ex)
{
System.out.println("Printing failed");
}
}
}
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if(pageIndex > 0)
return 1;
Graphics2D g2d = (Graphics2D)graphics;
double width = pageFormat.getImageableWidth();
double height = pageFormat.getImageableHeight();
g2d.translate((int) pageFormat.getImageableX(),(int) pageFormat.getImageableY());
Font font = new Font("Monospaced",Font.BOLD,8);
g2d.setFont(font);
try {
/*
* Draw Image*
*/
int x=50 ;
int y=10;
int imagewidth=100;
int imageheight=50;
BufferedImage read = ImageIO.read(new File("C:/hotel.png"));
g2d.drawImage(read,x,y,imagewidth,imageheight,null); //draw image
g2d.drawString("-- * Resturant * --", 20,y+60);
g2d.drawLine(10, y+70, 180, y+70); //draw line
} catch (IOException e) {
e.printStackTrace();
}
try{
/*Draw Header*/
/*
product details code..
*/
/*Footer*/
//end of the receipt
}
catch(Exception r){
r.printStackTrace();
}
return 0;
}
Please let me know how can i generate long receipt print by correcting my code or if you have any better solution to do this.
Right here:
Paper paper = new Paper();
paper.setSize(216D, paper.getHeight());
You are creating a new Paper object and not setting its height.
Here is a link to the documentation of this class.
When creating a Paper object, it is the application's responsibility to ensure that the paper size and the imageable area are compatible
You need to set the height of the paper by calling paper.setSize(width, height) or it will use its default size property.
The dimensions are supplied in 1/72nds of an inch.
So both width and height will need to be provided in this format as doubles
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
PrintService printService[] = PrintServiceLookup.lookupPrintServices(
flavor, pras);
PrintService service = findPrintService(printerName, printService);
PDDocument document = PDDocument.load(bytes);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(service);
job.setPageable(new PDFPageable(document));
job.print();
if (document != null) {
document.close();
}
I have a Problem, My code which converts a PDF to Printable Format that can be printed locks my pdf file.
My Code:
public class PDFPrinter {
public PDFPrinter(File file) {
try {
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
fis.close();
fc.close();
PDFFile pdfFile = new PDFFile(bb); // Create PDF Print Page
PDFPrintPage pages = new PDFPrintPage(pdfFile);
// Create Print Job
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
Paper a4paper = new Paper();
double paperWidth = 8.26;
double paperHeight = 11.69;
a4paper.setSize(paperWidth * 72.0, paperHeight * 72.0);
/*
* set the margins respectively the imageable area
*/
double leftMargin = 0.3;
double rightMargin = 0.3;
double topMargin = 0.5;
double bottomMargin = 0.5;
a4paper.setImageableArea(leftMargin * 72.0, topMargin * 72.0,
(paperWidth - leftMargin - rightMargin) * 72.0,
(paperHeight - topMargin - bottomMargin) * 72.0);
pf.setPaper(a4paper);
pjob.setJobName(file.getName());
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
// Send print job to default printer
if (pjob.printDialog()) {
pjob.print();
}
} catch (IOException e) {
e.printStackTrace();
} catch (PrinterException e) {
JOptionPane.showMessageDialog(null, "Printing Error: "
+ e.getMessage(), "Print Aborted",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
class PDFPrintPage implements Printable {
private PDFFile file;
PDFPrintPage(PDFFile file) {
this.file = file;
}
public int print(Graphics g, PageFormat format, int index)
throws PrinterException {
int pagenum = index + 1;
// don't bother if the page number is out of range.
if ((pagenum >= 1) && (pagenum <= file.getNumPages())) {
// fit the PDFPage into the printing area
Graphics2D g2 = (Graphics2D) g;
PDFPage page = file.getPage(pagenum);
double pwidth = format.getImageableWidth();
double pheight = format.getImageableHeight();
double aspect = page.getAspectRatio();
double paperaspect = pwidth / pheight;
Rectangle imgbounds;
if (aspect > paperaspect) {
// paper is too tall / pdfpage is too wide
int height = (int) (pwidth / aspect);
imgbounds = new Rectangle(
(int) format.getImageableX(),
(int) (format.getImageableY() + ((pheight - height) / 2)),
(int) pwidth, height);
} else {
// paper is too wide / pdfpage is too tall
int width = (int) (pheight * aspect);
imgbounds = new Rectangle(
(int) (format.getImageableX() + ((pwidth - width) / 2)),
(int) format.getImageableY(), width, (int) pheight);
}
// render the page
PDFRenderer pgs = new PDFRenderer(page, g2, imgbounds, null,
null);
try {
page.waitForFinish();
pgs.run();
} catch (InterruptedException ie) {
}
return PAGE_EXISTS;
} else {
return NO_SUCH_PAGE;
}
}
}
}
I call it with:
new PDFPrinter(file);
Everything works fine, but after I started printing the PDF-file is locked by Java. Whats wrong?? When I restart Java it works again but only one time then it's locked again.
I found another solution...
For everyone:
public static void printPdf (String filePath, String jobName) throws IOException, PrinterException {
FileInputStream fileInputStream = new FileInputStream(filePath);
byte[] pdfContent = new byte[fileInputStream.available()];
fileInputStream.read(pdfContent, 0, fileInputStream.available());
ByteBuffer buffer = ByteBuffer.wrap(pdfContent);
final PDFFile pdfFile1 = new PDFFile(buffer);
pdf_print_engine pages1 = new pdf_print_engine(pdfFile1);
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pfDefault = PrinterJob.getPrinterJob().defaultPage();
Paper defaultPaper = new Paper();
defaultPaper.setImageableArea(0, 0, defaultPaper.getWidth(), defaultPaper.getHeight());
pfDefault.setPaper(defaultPaper);
pjob.setJobName("Test");
if (pjob.printDialog()) {
// validate the page against the chosen printer to correct
// paper settings and margins
pfDefault = pjob.validatePage(pfDefault);
Book book = new Book();
book.append(pages1, pfDefault, pdfFile1.getNumPages());
pjob.setPageable(book);
try {
pjob.print();
} catch (PrinterException exc) {
System.out.println(exc);
}
}
Have fun with the Code
Tim
I am trying to create an image with a given text and style. eg;
" textStyle(Offer ends 25/12/2016. Exclusions Apply., disclaimer) textStyle(See Details,underline) "
In above line i am splitting and creating a map that stores the first parameter of textStyle block as key and second parameter as value where second param defines the style to be applied on first param. Hence an entry of map will look like .
Now when i iterate over this map to write the text to image i check if the text is overflowing the width. If yes then it breaks the text and adds it to next line in the horizontal center. So for example lets say i am trying to write "Offer ends 25/12/2016. Exclusions Apply." with Arial and font size 12. While writing i find that i can write till "Offer ends 23/12/2016. " only and "Exclusions apply" has to go in next line. But it writes the text in horizontal center neglecting that as there is space left horizontally i can write "See Details" too in the same line.
Please help. Below is the code what i have tried. I have also tried creating a JTextPane and then converting it to image but this cannot be an option as it first creates the frame, makes it visible, writes it and then disposes it. And most of the times i was getting Nullpointer exception on SwingUtilities.invokeAndWait.
Actual : http://imgur.com/7aIlcEQ
Expected http://imgur.com/038zQTZ
public static BufferedImage getTextImage(String textWithoutStyle, Map<String, String> textToThemeMap, Properties prop, int height, int width) {
BufferedImage img = new BufferedImage(width,height,BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = img.createGraphics();
g2d.setPaint(Color.WHITE);
FontMetrics fm = g2d.getFontMetrics();
Map<String, Font> textToFontMap = new LinkedHashMap<String, Font>();
for(Map.Entry<String, String> entry : textToThemeMap.entrySet()) {
if(StringUtils.isNotBlank(entry.getKey()) && StringUtils.isNotBlank(entry.getValue())) {
Font font = getFont(prop, entry.getValue().trim());
g2d.setFont(font);
fm = g2d.getFontMetrics();
String string = entry.getKey();
char[] chars = null;
int i = 0, pixelWidth = 0;
List<String> newTextList = new ArrayList<String>();
if(fm.stringWidth(string) > (width - 10)) {
chars = string.toCharArray();
for (i = 0; i < chars.length; i++) {
pixelWidth = pixelWidth + fm.charWidth(chars[i]);
if(pixelWidth >= (width - 10)) {
break;
}
}
String newString = WordUtils.wrap(string, i, "\n",false);
String[] splitString = newString.split("\n");
for(String str : splitString) {
newTextList.add(str);
textToFontMap.put(string, font);
}
} else {
newTextList.add(string);
textToFontMap.put(string, font);
}
}
}
Font font = new Font("Arial", Font.BOLD, 14);
int spaceOfLineHeight = (textToFontMap.size() - 1) * 7;
int spaceOfText = textToFontMap.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText ;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
String txt = null;
for(Map.Entry<String, Font> entry : textToFontMap.entrySet()) {
txt = entry.getKey();
font = entry.getValue();
g2d.setFont(font);
fm = g2d.getFontMetrics();
int x = (width - fm.stringWidth(txt)) / 2;
int y = tempHt;
g2d.drawString(txt, x, y);
tempHt = tempHt + fm.getHeight();
}
// g2d.drawString(text.getIterator(), 0, (int)lm.getAscent() + lm.getHeight());
// g2d.dispose();
return img;
}
// Code with JTextPane ------------------------------------------
public static BufferedImage getTextImage(final Map < String, String > textToThemeMap, final Properties prop, final int height, final int width) throws Exception {
JFrame f = new JFrame();
f.setSize(width, height);
final StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
pane.setSize(width, height);
// Build the styles
final Paragraph[] content = new Paragraph[1];
Run[] runArray = new Run[textToThemeMap.size()];
int i = 0;
for (Map.Entry < String, String > entry: textToThemeMap.entrySet()) {
if (StringUtils.isNotBlank(entry.getValue().trim()) && StringUtils.isNotBlank(entry.getKey().trim())) {
Run run = new Run(entry.getValue().trim(), entry.getKey());
runArray[i++] = run;
}
}
content[0] = new Paragraph(null, runArray);
/*createDocumentStyles(sc, prop,textToThemeMap.values());
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);*/
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
createDocumentStyles(sc, prop, textToThemeMap.values());
} catch (MalformedURLException e) {
//e.printStackTrace();
}
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
}
f.getContentPane().add(pane);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gd = img.createGraphics();
f.paint(gd);
f.dispose();
/*ImageIO.write(img, "png", new File("C:\\Users\\spande0\\Desktop\\a.png"));
System.out.println("done");*/
return img;
}
I suspect the issue is in your 'Y' computation.
int spaceOfLineHeight = (newTextList.size() - 1) * 7;
int spaceOfText = newTextList.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
You have to keep the height occupied by the previous lines, and add it to the current 'Y'.
At the moment, for all the lines, the 'Y' values is same.
Declare prevHeight outside the for loop. and then do the following.
int tempHt = marginRemaining / 2 + 10;
tempHT += prevHeight;
prevHeight = tempHeight
Based on the comments, I will suggest you to break down your function into two smaller functions.
// Loop through the strings and find out how lines are split and calculate the X, Y
// This function will give the expected lines
splitLinesAndComputeResult
// Just render the lines
renderLines
I'm trying to print the same that I have in my applet GUI.
The things it's that when I print it it's not exactly the same... the size of each component changes in a disproportionately way.
The GUI:
Printed:
The margins are not a problem, I can fix them easily... but as you can see the barcode and the vertical text has not the proper size.
Main class:
public class Impresion extends Applet{
PrinterJob job = PrinterJob.getPrinterJob();
Panel test;
Label test2;
Label test3;
String copyParam = null;
String dialogParam = null;
String codeParam = null;
String descParam = null;
public void init(){
copyParam = this.getParameter("copias");
dialogParam = this.getParameter("ventanita");
codeParam = this.getParameter("codigo");
descParam = this.getParameter("descripcion");
copyParam = "1";
dialogParam = "1";
codeParam = "002/113";
descParam = "asd";
if (copyParam == null || dialogParam == null || codeParam == null || descParam == null){
System.out.println("Faltan parametros. - "+copyParam+" - "+dialogParam+" - "+codeParam+" - "+descParam);
} else {
job.setPrintable(new Dibujar(codeParam, descParam));
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
float leftMargin = (float) 0.1;
float topMargin = (float) 0.1;
float rightMargin = (float) 0.1;
float bottomMargin = (float) 0.1;
float mediaWidth = (float) 60.0;
float mediaHeight = (float) 50.0;
aset.add(new MediaPrintableArea(leftMargin, topMargin, (mediaWidth - leftMargin - rightMargin), (mediaHeight - topMargin - bottomMargin), Size2DSyntax.MM));
int copias = Integer.parseInt(copyParam);
aset.add(new Copies(copias));
boolean imprimir = true;
if (dialogParam.indexOf('1') != -1){
imprimir = job.printDialog(aset);
}
if (imprimir){
try {
job.print(aset);
} catch (PrinterException e) {
e.printStackTrace();
}
}
}
}
}
Printable class:
public class Dibujar implements Printable{
String codeParam = null;
String descParam = null;
public Dibujar(String code, String desc) {
codeParam = code;
descParam = desc;
}
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException{
if (pageIndex > 0){
return NO_SUCH_PAGE;
}
Barcode b = null;
try {
b = BarcodeFactory.createCodabar(codeParam);
b.setDrawingText(false);
b.setBarWidth(1);
b.draw((Graphics2D) g, 30, 8);
} catch (BarcodeException | OutputException e1) {
e1.printStackTrace();
}
g.setFont(new Font("Arial", Font.BOLD, 9));
String description = descParam;
g.drawString(description, 16, 70);
AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(90),16,8);
Graphics2D g2 = (Graphics2D) g;
g2.transform(at);
g.setFont(new Font("Arial", Font.BOLD, 14));
g2.drawString(codeParam.replace("/", ""),16,8);
g2.transform(new AffineTransform());
return PAGE_EXISTS;
}
}
Adjust the parameters in this:
aset.add(new MediaPrintableArea(leftMargin, topMargin, (mediaWidth - leftMargin - rightMargin), (mediaHeight - topMargin - bottomMargin), Size2DSyntax.MM));
Or adjust the parameters in these two:
b.draw((Graphics2D) g, 30, 8);
//....
g2.drawString(codeParam.replace("/", ""),16,8);
I just got the printer to work in java how I need it too, but there's one last problem I need to solve. When it prints, the font's width is rather stretched, and not crisp and clear like it should be.
Here is my code my the actual drawing to the paper:
FontMetrics metrics = graphics.getFontMetrics(font);
int lineHeight = metrics.getHeight();
arrangePage(graphics, pageFormat, lineHeight);
if (page > pageBreaks.length){
return NO_SUCH_PAGE;
}
Graphics2D g = (Graphics2D) graphics;
g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
g.setFont(font);
int y = 0;
int begin = 0;
if (page == 0){
begin = 0;
}else begin = pageBreaks[page-1];
int end = 0;
if (page == pageBreaks.length){
end = lines.length;
}else end = pageBreaks[page];
for (int line = begin; line < end; line++){
y += lineHeight;
g.drawString(lines[line], 0, y);
}
string = deepCopy;
return PAGE_EXISTS;
How do I get rid of the stretching? It can be noted that this is based off this tutorial:
http://docs.oracle.com/javase/tutorial/2d/printing/set.html
Any advice or help is greatly appreciated.
The default DPI is normal 72 DPI (I believe), which, on printed paper, is pretty terrible. You need to prompt the print API to try and find a printer with a better DPI.
Basically you need to use the print services API.
Try something like...
public class PrintTest01 {
public static void main(String[] args) {
PrinterResolution pr = new PrinterResolution(300, 300, PrinterResolution.DPI);
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_A4);
aset.add(pr);
aset.add(OrientationRequested.PORTRAIT);
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Page());
try {
pj.print(aset);
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
public static class Page implements Printable {
#Override
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
g.setFont(new Font("Arial", Font.PLAIN, 128));
FontMetrics fm = g.getFontMetrics();
int x = (int)(pageFormat.getWidth() - fm.stringWidth("A")) / 2;
int y = (int)((pageFormat.getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString("A", x, y);
return PAGE_EXISTS;
}
}
}
You might find Working with Print Services and Attributes of some help...
I should warn you, this is going to print to the first print that it can find that meets the PrintRequestAttributeSet. You could also add in the print dialog to see what's it doing, but that's another level of complexity I can live without right now ;)
The above worked! To open a print dialog with it, use this:
PrinterJob job = PrinterJob.getPrinterJob();
TextDocumentPrinter document = new TextDocumentPrinter();
PrinterResolution pr = new PrinterResolution(300, 300, PrinterResolution.DPI);
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(MediaSizeName.ISO_A4);
aset.add(pr);
aset.add(OrientationRequested.PORTRAIT);
job.setPrintable(document);
boolean doPrint = false;
if (showDialog){
doPrint = job.printDialog(aset);
}else doPrint = true;
if (doPrint){
try{
job.print();
}catch(PrinterException e){
e.printStackTrace();
}
}
The aset variable contains all of your new default values, and by plugging it into the printDialog, those are inputted into the printJob and consequently show up on the paper! They can be changed in the dialog, as well.