opposite of/n? - ESC/POS and PHP right/ left justify on the same line

David picture David · Mar 19, 2013 · Viewed 8k times · Source

so I am printing to a networked thermal printer in the office from our webserver (also in the office) so clients can place orders on the website and they pop out on the sales dept desk. Here is the code I use and it works very well. However when it comes to printing the items on the slip I want the item text align center and the price text align right, but it wont let me do it (cos its the same line I think) so how can I say new line (\n) but then reverse it. I tried \033F and \F already but no luck. any advise?

$texttoprint = "";
//center,bold,underline - close underline, close bold
$texttoprint .= "\x1b\x61\x01\x1b\x45\x01\x1b\x2d\x02\x1b\x21\x10\x1b\x21\x20 Company name \x1b\x2d\x00\x1b\x45\x00";
$texttoprint .= "\n";
//normal text
$texttoprint .= "\x1b\x21\x00 Address";
$texttoprint .= "\n"; 
//normal text
$texttoprint .= "\x1b\x21\x00 Adress2";
$texttoprint .= "\n";
//normal text
$texttoprint .= "\x1b\x21\x00 Tel : ...";
$texttoprint .= "\n";
$texttoprint .= "\n";
//normal text
$texttoprint .= "\x1b\x21\x00 Website order";
$texttoprint .= "\n";
$texttoprint .= "\n";
//center,bold,underline - close underline, close bold
$texttoprint .= "\x1b\x61\x01\x1b\x45\x01\x1b\x2d\x02\x1b\x21\x10\x1b\x21\x20 Tax Invoice \x1b\x2d\x00\x1b\x45\x00";
$texttoprint .= "\n";
$texttoprint .= "\n";
//align center, normal text
$texttoprint .= "\x1b\x61\x01\x1b\x21\x00 1x product";
//align right, normal text
$texttoprint .= "\x1b\x61\x02\x1b\x21\x00 $200";
...

As you can see here the last 2 are on the same line and I am trying to justify the product center and price right. they both end up center, if I put a /n between then they justify correctly just on the wrong lines.

$texttoprint = stripslashes($texttoprint);

$fp = fsockopen("192.168.0.168", 9100, $errno, $errstr, 10);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "\033\100");
$out = $texttoprint . "\r\n";
fwrite($fp, $out);
fwrite($fp, "\012\012\012\012\012\012\012\012\012\033\151\010\004\001");
fclose($fp);
}

Answer

Sven picture Sven · Mar 19, 2013

You can let the printer do all the stuff, but I think it is a better idea to implement some knowledge about the printer characteristics into the output routine. You should know how many characters per line can be printed.

You could then use sprintf() to format the entire line, with the product info aligned to the left and with a maximum field size, and the price aligned to the right.

$texttoprint .= sprintf('%s %f', $article, $price); // very basic start: A string and a float
$texttoprint .= sprintf('%-30.30s %8.2f', $article, $price); 
// 30 chars for the string, will not exceed this length, and 8 chars for the price, with decimal dot and 2 decimal digits.

Please note that you shouldn't use stripslashes() on the final result. If you have an issue with slashes being present, they are introduced by "magic quotes" and should be eliminated right at the start, not at the end.

A different solution would be to switch the printer to "Windows" mode and make him need CR/LF for a complete line printout. This way you could print the whole line without moving the paper by printing CR only, which moves the printer head to the start of the line again. You can then print on top of the already printed line again, until you print a LF. Note that if there is an actual printer head involved, this might make things worse, as it might trigger additional head movement just for printing one single line. Printers usually are able to optimize head movement for one single line after another.