thiennguyenenv / jzebra

Automatically exported from code.google.com/p/jzebra
0 stars 1 forks source link

Print at the bottom of receipt. #203

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
I amd trying to print an image at the bottom of the receipt. But I can't. It 
always prints on the top of the page. When I place the apendImage to the bottom 
of the javascript code, it first cuts the paper and then prints the logo at the 
next receipt at the top! What am I doing wrong, or don't understand?

Here is my code.
applet.setEncoding("CP869"); //For greek chars
applet.appendHex("x1Bx61x01"); // Centering

//The following is the correct WAY TO PRINT A BARCODE CODE39
applet.appendHex("x1Dx68x60");//Barcode height to 70 dots default is 165. The 
value must not ralate to other actions              
applet.appendHex("x1Dx6Bx04");
applet.append("1000000345");
applet.appendHex("x00");                
applet.appendHex(ResetStyles());

applet.appendHex("x1Bx61x01"); // Centering
applet.append("*********************************************** \r\n");
applet.append("Info: 42972\r\n");
applet.appendHex(MakeStyle(false, true, false, false, false));
applet.appendHex(MakeStyle(false, false, false, true, false));
applet.append("Info: Kommm\r\n");
applet.appendHex(ResetStyles());
applet.append("Date: 14:00 01/02\r\n");
applet.append("----------------------------------------------- \r\n");
applet.appendHex("x1Bx61x00");
applet.append("Info: 42972\r\n");
applet.append("Info: Kommm\r\n"); 
//applet.appendHex(MakeStyle(false, false, false, false, false)); //This can be 
used only with one value true at a time
applet.appendHex(MakeStyle(false, false, false, false, false));
applet.appendHex(MakeStyle(false, true, false, false, false));
applet.append("Datum: 14:00 01/02\r\n");
applet.appendHex(ResetStyles());                                    
applet.append("----------------------------------------------- \r\n");

//Printing Image. Grabs an image from a url
applet.appendImage("http://example.com/example/images/image_sample_bw.png", 
"ESCP", "single");

applet.append("\x1D\x56\x41"); // cuts paper                        

applet.append("\x1B\x40"); // reset printer to default settings it is good to 
exist in the end of each printing.

applet.print();

setTimeout(function(){
   applet.appendFile(window.location.href + "./printFiles/"+escMethod+".txt");
},1000);

function ResetStyles() {
    return 'x1Bx21x00';
}

function MakeStyle(font, boldStyle, underline, double_width, double_height) {

    var hex = 0;
    if (font) {
    hex += font; //This only works with 10 or 20 which means double height or width. It doesn't work for font=7 for Greek only with English
    }
    if (boldStyle) {
        hex += 8;
    }
    if (underline) { //doesn't work
        hex += 80;
    }
    if (double_width) {
        hex += 20;
    }
    if (double_height) {
       hex += 10;
    }
    if (hex < 10) {
       hex = "0" + hex; 
    }
var temp = 'x1Bx21x';
return temp + hex;
}

What version of the product are you using? On what operating system?
The printer is connected on windows 7 PC.

Original issue reported on code.google.com by adomv...@gmail.com on 12 Jan 2014 at 7:43

GoogleCodeExporter commented 9 years ago
By the way I am using 1.8 version of qz.
Looks like the problem is due to the fact that appendImage is still asychronous 
function. That is whay it bypasses this commands and goes to the next command 
which is the cut paper command.
So I will have to find a way to wait for the image fetching and then cut the 
paper.
I also found out a related issue.
https://groups.google.com/forum/#!topic/jzebra-users/C6Mivu9lAhY

Any idea when and if the appendImage will become synchronous function?
Thank  you

Original comment by adomv...@gmail.com on 12 Jan 2014 at 8:02

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
This is how I solved it.

//Printing Image.
applet.appendImage("http://example.com/example/images/image_sample_bw.png", 
"ESCP", "single");

applet.append("\x1B\x40"); // reset printer to default settings it is good to 
exist in the end of each printing.

//This is used to create a timeout in order to give time to append the Image 
from the url. Most likely 1sec is enough.
//This way if the image doesn't load, for example due to failure in the network 
then the browser will not freeze.
//The problem though with this is the fact that if the http request for the png 
makes more that 1sec to load and append, then 
//the printer will cut the paper and the image will appear on the top of the 
next receipt and this is not good.                      
setTimeout(function(){
    applet.print();
    applet.append("\x1B\x40");
    applet.append("\x1D\x56\x41");
    applet.append("\x1B\x40");
    applet.print();

},1000);

Original comment by adomv...@gmail.com on 12 Jan 2014 at 9:18

GoogleCodeExporter commented 9 years ago
Although I appreciate the detailed bug report, you have removed the 
qzDoneAppending() callback from 1.8.0 sample.html which addresses the 
asynchronous image handling.  Here is a direct quote from printESCP example in 
1.8.0:

> function printESCP() {
>   if (notReady()) { return; }
>   
>   // Append a png in ESCP format with single pixel density
>   qz.appendImage(getPath() + "img/image_sample_bw.png", "ESCP", "double");
>           
>   // Automatically gets called when "qz.appendImage()" is finished.
>   window["qzDoneAppending"] = function() {
>       // Append the rest of our commands
>       qz.append('\nPrinted using qz-print plugin.\n\n\n\n\n\n');
>       
>       // Tell the apple to print.
>       qz.print();
>       
>       // Remove any reference to this function
>       window['qzDoneAppending'] = null;
>   };
> }

The purpose of defining qzDoneAppending() on the fly like that is to ensure it 
does not conflict with other uses of the function.

P.S. Version 2.0.0 -- expected in February -- will synchronize all calls and 
eliminate the need for these callbacks.

Original comment by tres.fin...@gmail.com on 13 Jan 2014 at 3:23

GoogleCodeExporter commented 9 years ago
You are right it is much better with the window["qzDoneAppending"] = function()
It works fine, without any delay now.
It is good to know that the next version will be simpler with new features.

About another issue I faced.
About the differences in the ESC/P code to initiate, print, cut etc between the 
different brands of POS printers. Like EPSON, Star, Zebra.
How does the plugin handle these differences?
I mean is there a way for the qz plugin to know that the printer used is Star 
so that the special commands for Star to be used?
Thank you!

Original comment by adomv...@gmail.com on 13 Jan 2014 at 6:46

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
> is there a way for the qz plugin to know that the printer used is Star so 
that the special commands for Star to be used

Unfortunately, no.  Generic print spoolers are mostly uni-directional 
communication.  Printer make and model would require bi-directional 
communication that just isn't present via print spooler.

There are two ways to handle this.

1.  Bypass the spooler and talk to the printer directly.  This is likely 
possible via Serial Communication, but Java doesn't provide native Serial 
Libraries, so you'd be stuck using the jssc package inside qz-print.  This is 
experimental and tends to lock-up the serial port on refresh.  In addition, 
most printers no longer have serial interfaces, so you'd be stuck searching for 
a USB-Serial or Ethernet-Serial driver/emulator.  The drivers exist for many 
printer models, but they install Virtual COM ports which would add further 
variables to your configuration.

2. This is a much easier way.... Assume a printer named "Star" is a Star 
printer.  Assume a printer named "Citizen" is named Citizen, Epson, etc.

Instead of using "alert" below, you could set a variable, change your append 
commands, etc.  Hope this helps.

> window["qzDoneFinding"] = function() {
>    var printers = qz.getPrinters().split(",");
>       for (i in printers) {
>          if (printers[i].toLowerCase().indexOf("star") != -1) {
>             alert("I think it's a Star printer!");
>             qz.setPrinter(i);
>          } else if (printers[i].toLowerCase().indexOf("epson") != -1) {
>             alert("Pretty sure it's an Epson printer!");
>             qz.setPrinter(i);
>          } else if (printers[i].toLowerCase().indexOf("citizen") != -1) {
>             alert("Bet my money it's a Citizen printer!");
>             qz.setPrinter(i);
>          }
>       }           
>    window['qzDoneFinding'] = null;
> }

Original comment by tres.fin...@gmail.com on 13 Jan 2014 at 7:16

GoogleCodeExporter commented 9 years ago
When a printer is connected on a POS system, the user of the printer knows what 
brand it is. So the automatic finding of the brand of the printer is not 
something that I really need to tell you the truth and as you said it is not so 
simple or even possible in every situation.

But let's say that we know the brand of the printer. For example, it is Star.
What I would like to know is if I can set to the qz plugin, that I am going to 
communicate with a Star printer, and then the qz plugin will be able to use the 
special commands of the Star printers to do the basic jobs for example, 
initiate, print, cut, finish printing, etc
I am asking this, because as far as I know there are differences in the ESCP 
code between the EPSON and STAR printers.

Thank you!

Original comment by adomv...@gmail.com on 13 Jan 2014 at 8:21

GoogleCodeExporter commented 9 years ago
What you are describing is syntax-aware dynamic code translation, and no, this 
is not available.

Star advertises their printers as being compatible with ESC/POS and are usually 
advertised as less expensive alternatives to the Epson line of printers.  It 
would be a question for the Star team whether or not their hardware allows the 
use of the Epson cut command.

If there is a demand to do code replacement, that feature can be included in a 
future build, but it still wouldn't be syntax aware.

The qz-print plugin is a very small and lightweight jar because it has very few 
static bindings.  If it was hard-coded with ESC/POS commands, it would also 
need to be hard-coded with EPL, EPCL, CPCL, FGL, ZPL, DPL, DTPL, etc.

In the end, I would be creating a comprehensive raw printing language and 
translation layers and would have to own a version of each language, from each 
vendor.  It would be a nightmare.

For basic replacement support (i.e. replace XYZ hex/characters with ABC 
hex/characters), feel free to put in an enhancement request in the bug tracker 
and I can incorporate into a future build.

-Tres  

Original comment by tres.fin...@gmail.com on 13 Jan 2014 at 2:51