web-dev-qa-db-ja.com

PHPからPOSプリンターへの印刷

Apacheが実行されている場所に接続されたPOSプリンターへの印刷を検討しています。アプリケーションの設計と展開のために、サーバーから印刷を実行する必要があります(注文を検出し、さまざまなプリンターや印刷のさまざまな形式...請求書、キッチンの注文などに送信する必要があります)。この理由およびその他の理由(たとえば、iPadからのアプリケーションへのアクセスなど)のために、QZ-Printアプレットなどのオプションを破棄し、サーバー側で直接印刷する必要はありません。

私たちは多くのことを検索し、php-printerと呼ばれる拡張機能がありますが、時代遅れのようであり、WINDOWSでのみ動作することを発見しました。

このコードに従いました:( http://mocopat.wordpress.com/2012/01/18/php-direct-printing-printer-dot-matrix-lx-300/

$tmpdir = sys_get_temp_dir();   # ambil direktori temporary untuk simpan file.
$file =  tempnam($tmpdir, 'ctk');  # nama file temporary yang akan dicetak
$handle = fopen($file, 'w');
$condensed = Chr(27) . Chr(33) . Chr(4);
$bold1 = Chr(27) . Chr(69);
$bold0 = Chr(27) . Chr(70);
$initialized = chr(27).chr(64);
$condensed1 = chr(15);
$condensed0 = chr(18);
$corte = Chr(27) . Chr(109);
$Data  = $initialized;
$Data .= $condensed1;
$Data .= "==========================\n";
$Data .= "|     ".$bold1."OFIDZ MAJEZTY".$bold0."      |\n";
$Data .= "==========================\n";
$Data .= "Ofidz Majezty is here\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "--------------------------\n";
$Data .= $corte;
fwrite($handle, $Data);
fclose($handle);
copy($file, "//localhost/KoTickets");  # Lakukan cetak
unlink($file);

それは機能しますが、これはプレーンテキストを送信し、画像(ロゴ)を送信し、よりかわいい請求書をフォーマットする必要があります。 PDFを作成し、同じ方法でプリンターに「送信」することを試みましたが、空白を印刷するだけです。

ネットワークプリンター(githubのescpos-php)で動作するライブラリを見つけましたが、顧客がハードウェアを変更するのを避けるために、USBプリンターでも動作する必要があります。

これを達成する方法はありますか?

前もって感謝します。

17
Giu

escpos-php の著者。

プリンターがESC/POSをサポートしている場合(ほとんどのサーマルレシートプリンターはそのサブセットを使用しているようです)、ドライバーはユースケース(USBまたはネットワーク印刷、ロゴ、フォーマットなど)に対応すると思います。これらのいくつかはごく最近の追加です。

USB印刷

escpos-phpはファイルポインターに出力します。 Linuxでは、usblpドライバーを使用してUSBプリンターをaaファイルとして表示し、fopen() it( SBレシートの例LinuxへのUSBプリンターのインストールに関するブログ投稿 )。

したがって、USBプリンターでの「Hello world」の印刷は、ネットワークプリンターでの印刷とわずかに異なります。

_<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\Printer;
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

$printer -> text("Hello World!\n");
$printer -> cut();

$printer -> close();
_

または、現在使用しているコードのように、一時ファイルに書き込んでコピーすることもできます。

_<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\Printer;

/* Open file */
$tmpdir = sys_get_temp_dir();
$file =  tempnam($tmpdir, 'ctk');

/* Do some printing */
$connector = new FilePrintConnector($file);
$printer = new Printer($connector);
$printer -> text("Hello World!\n");
$printer -> cut();

$printer -> close();

/* Copy it over to the printer */
copy($file, "//localhost/KoTickets");
unlink($file);
_

したがって、POSシステムでは、顧客の構成と優先宛先に基づいてファイルポインターを返す関数が必要になります。レシートプリンターは非常に迅速に応答しますが、注文するiPadが数台ある場合は、同時実行関連の問題を回避するために、ファイルロック( flock() )で各プリンターに操作をラップする必要があります。

また、WindowsでのUSBサポートはテストされていないことに注意してください。

ロゴとフォーマット

プリンタと通信する方法を理解したら、フォーマットと画像コマンドの完全なスイートを使用できます。

ロゴは、PNGファイルから次のように印刷できます。

_use Mike42\Escpos\EscposImage;
$logo = EscposImage::load("foo.png");
$printer -> graphics($logo);
_

また、フォーマットについては、 README.md と以下の例で開始できます。ほとんどの領収書では、本当に必要なのは次のもののみです。

  • selectPrintMode()はフォントサイズを変更します。
  • setEmphasis()は太字に切り替えます。
  • setJustification()は、一部のテキストまたは画像を左揃えまたは中央揃えにします。
  • cut()は受信ごとに。

また、現在次のようなボックスを描画する例を使用していることをお勧めします。

_=========
|       |
=========
_

IBMの文字を利用できます コードページ437 これは、多くのプリンターでサポートされている描画ボックス用に設計されており、出力に文字0xB3から0xDAを含めるだけです。それらは完璧ではありませんが、「テキスト」-yには見えません。

_$box = "\xda".str_repeat("\xc4", 10)."\xbf\n";
$box .= "\xb3".str_repeat(" ", 10)."\xb3\n";
$box .= "\xc0".str_repeat("\xc4", 10)."\xd9\n";
$printer -> textRaw($box);
_

完全な例

以下の例は、ドライバーで 現在も含まれています です。それはかなり典型的な店の領収書のように見え、フォーマットに関しては簡単で、キッチンのシナリオに簡単に適応できると思います。

スキャン出力:

Example formatted receipt including logo

生成するPHPソースコード:

_<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

/* Open the printer; this will change depending on how it is connected */
$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

/* Information for the receipt */
$items = array(
    new item("Example item #1", "4.00"),
    new item("Another thing", "3.50"),
    new item("Something else", "1.00"),
    new item("A final item", "4.45"),
);
$subtotal = new item('Subtotal', '12.95');
$tax = new item('A local tax', '1.30');
$total = new item('Total', '14.25', true);
/* Date is kept the same for testing */
// $date = date('l jS \of F Y h:i:s A');
$date = "Monday 6th of April 2015 02:56:25 PM";

/* Start the printer */
$logo = EscposImage::load("resources/escpos-php.png", false);
$printer = new Printer($connector);

/* Print top logo */
$printer -> setJustification(Printer::JUSTIFY_CENTER);
$printer -> graphics($logo);

/* Name of shop */
$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
$printer -> text("ExampleMart Ltd.\n");
$printer -> selectPrintMode();
$printer -> text("Shop No. 42.\n");
$printer -> feed();

/* Title of receipt */
$printer -> setEmphasis(true);
$printer -> text("SALES INVOICE\n");
$printer -> setEmphasis(false);

/* Items */
$printer -> setJustification(Printer::JUSTIFY_LEFT);
$printer -> setEmphasis(true);
$printer -> text(new item('', '$'));
$printer -> setEmphasis(false);
foreach ($items as $item) {
    $printer -> text($item);
}
$printer -> setEmphasis(true);
$printer -> text($subtotal);
$printer -> setEmphasis(false);
$printer -> feed();

/* Tax and total */
$printer -> text($tax);
$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
$printer -> text($total);
$printer -> selectPrintMode();

/* Footer */
$printer -> feed(2);
$printer -> setJustification(Printer::JUSTIFY_CENTER);
$printer -> text("Thank you for shopping at ExampleMart\n");
$printer -> text("For trading hours, please visit example.com\n");
$printer -> feed(2);
$printer -> text($date . "\n");

/* Cut the receipt and open the cash drawer */
$printer -> cut();
$printer -> Pulse();

$printer -> close();

/* A wrapper to do organise item names & prices into columns */
class item
{
    private $name;
    private $price;
    private $dollarSign;

    public function __construct($name = '', $price = '', $dollarSign = false)
    {
        $this -> name = $name;
        $this -> price = $price;
        $this -> dollarSign = $dollarSign;
    }

    public function __toString()
    {
        $rightCols = 10;
        $leftCols = 38;
        if ($this -> dollarSign) {
            $leftCols = $leftCols / 2 - $rightCols / 2;
        }
        $left = str_pad($this -> name, $leftCols) ;

        $sign = ($this -> dollarSign ? '$ ' : '');
        $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT);
        return "$left$right\n";
    }
}
_
48
mike42