蓝牙热敏打印机

先直接上结果图:
请添加图片描述

<?php


require __DIR__ . '/vendor/autoload.php';

use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;

class BTPrinter extends Mike42\Escpos\Printer
{
    const kPageWidth = 32;

    protected $textWidth;
    protected $bufferFile;

    public function __construct()
    {
        //创建临时文件
        $this->bufferFile = tempnam('/tmp', 'Printer');
        $this->textWidth = static::kPageWidth;

        //连接临时文件作为打印缓存
        $connector = new FilePrintConnector($this->bufferFile);
        parent::__construct($connector);

        //程序结束后删除临时文件
        register_shutdown_function(function () {
            unlink($this->bufferFile);
        });
    }


    /**
     * @return int
     */
    public function getTextWidth()
    {
        return $this->textWidth;
    }

    public function initialize()
    {
        parent::initialize();
        $this->textWidth = static::kPageWidth;
    }


    public function setTextSize($widthMultiplier = 1, $heightMultiplier = 0)
    {
        if ($heightMultiplier === 0) {
            $heightMultiplier = $widthMultiplier;
        }

        $this->textWidth = floor(static::kPageWidth / $widthMultiplier);
        parent::setTextSize($widthMultiplier, $heightMultiplier);
    }

    public function text($str = "", $newline = false)
    {
        parent::text($str);
        if ($newline) {
            $this->newline();
        }
    }

    public function textChinese($str = "", $newline = false)
    {
        parent::textChinese($str);
        if ($newline) {
            $this->newline();
        }
    }

    public function textLabel($label, $text)
    {
        $space = $this->textWidth - mb_strwidth($label);
        $this->textChinese($label);
        if (mb_strwidth($text) > $space) {
            $this->newline();
        } else {
            $text = mb_str_pad($text, $space, ' ', STR_PAD_LEFT);
        }
        $this->textChinese($text, true);
    }

    public function writeRaw($text)
    {
        $this->connector->write($text);
    }

    public function separator($sep = '-', $text = '')
    {
        $this->textChinese(mb_str_pad($text, $this->textWidth, $sep, STR_PAD_BOTH), true);
    }

    public function newline()
    {
        $this->text("\n");
    }

    public function flush()
    {
        $this->close();
        return file_get_contents($this->bufferFile);
    }

    public function flushBase64()
    {
        return base64_encode($this->flush());
    }

    public function flushHex()
    {
        return bin2hex($this->flush());
    }


}

if (!function_exists('mb_sprintf')) {
    function mb_sprintf($format)
    {
        $argv = func_get_args() ;
        array_shift($argv) ;
        return mb_vsprintf($format, $argv) ;
    }
}

if (!function_exists('mb_vsprintf')) {
    /**
     * Works with all encodings in format and arguments.
     * Supported: Sign, padding, alignment, width and precision.
     * Not supported: Argument swapping.
     */
    function mb_vsprintf($format, $argv, $encoding=null)
    {
        if (is_null($encoding))
            $encoding = mb_internal_encoding();

        // Use UTF-8 in the format so we can use the u flag in preg_split
        $format = mb_convert_encoding($format, 'UTF-8', $encoding);

        $newformat = ""; // build a new format in UTF-8
        $newargv = array(); // unhandled args in unchanged encoding

        while ($format !== "") {

            // Split the format in two parts: $pre and $post by the first %-directive
            // We get also the matched groups
            list ($pre, $sign, $filler, $align, $size, $precision, $type, $post) =
                preg_split("!\%(\+?)('.|[0 ]|)(-?)([1-9][0-9]*|)(\.[1-9][0-9]*|)([%a-zA-Z])!u",
                    $format, 2, PREG_SPLIT_DELIM_CAPTURE) ;

            $newformat .= mb_convert_encoding($pre, $encoding, 'UTF-8');

            if ($type == '') {
                // didn't match. do nothing. this is the last iteration.
            }
            elseif ($type == '%') {
                // an escaped %
                $newformat .= '%%';
            }
            elseif ($type == 's') {
                $arg = array_shift($argv);
                $arg = mb_convert_encoding($arg, 'UTF-8', $encoding);
                $padding_pre = '';
                $padding_post = '';

                // truncate $arg
                if ($precision !== '') {
                    $precision = intval(substr($precision,1));
                    if ($precision > 0 && mb_strwidth($arg, $encoding) > $precision)
                        $arg = mb_substr($precision,0,$precision,$encoding);
                }

                // define padding
                if ($size > 0) {
                    $arglen = mb_strwidth($arg, $encoding);
                    if ($arglen < $size) {
                        if($filler==='')
                            $filler = ' ';
                        if ($align == '-')
                            $padding_post = str_repeat($filler, $size - $arglen);
                        else
                            $padding_pre = str_repeat($filler, $size - $arglen);
                    }
                }

                // escape % and pass it forward
                $newformat .= $padding_pre . str_replace('%', '%%', $arg) . $padding_post;
            }
            else {
                // another type, pass forward
                $newformat .= "%$sign$filler$align$size$precision$type";
                $newargv[] = array_shift($argv);
            }
            $format = strval($post);
        }
        // Convert new format back from UTF-8 to the original encoding
        $newformat = mb_convert_encoding($newformat, $encoding, 'UTF-8');
        return vsprintf($newformat, $newargv);
    }
}


if (!function_exists('mb_str_pad')) {
    function mb_str_pad($str, $pad_length, $pad_string, $pad_type = STR_PAD_RIGHT, $encoding = null)
    {
        if ($encoding === null) {
            $encoding = mb_internal_encoding();
        }

        $w = mb_strwidth($str, $encoding);
        $len = strlen($str);
        $pad_length += $len - $w;
        return str_pad($str, $pad_length, $pad_string, $pad_type);
    }
}


/**
 * 服务端以下代码放到 Ctroller 里面。
 * 初始化BTPrinter得到$printer对象,排版填充数据后调用$printer->flushBase64()方法得到 base64数据,api返回给客户端即可。
 * (注(服务端不用关心这句):$printer->flush 返回的是byte 数据,客户端经过Base64.decode即是该数据,通过bluesocket 发送打印机执行打印)
 * json_li 2018-1-10 12:01
 */

/*
 * 附录:下面的代码如下打印样式:
 * &----------泛客云商订单----------.
&窗边小豆豆的奶茶铺子.
!&【外卖】.
!&--------------------------------.
&下单时间:.&    2018-01-10 12:00:06.
&订单编号:.&         BU20171829UUKL.
&付款人:.&                    cfgxy.
&--------------------------------.
&商品            数量        单价.
&苹果            2          10.02.
&香蕉            3           9.03.
&商品名称比较长比较长比较长比较长长比较长长比较长长比较长长比较长长长长长长长长长.
&                1          10.00.
&--------------------------------.
&名称1:.&                    value1.
&--------------------------------.
&名称2:.&                    value2.
&--------------------------------.
&名称3:.&                    value3.
&--------------------------------.
!&地址:合肥市蜀山区怀宁路888号天睿大厦万家热线菜鸟级工程师json_li测试打印比较长的地址会怎样 so?fucking you!.
!&------------订单结束------------.
 */

$printer = new BTPrinter();
$printer->initialize();//打印机初始化

//Section: 表头
$printer->separator('-', '商品订单');

//Section: 店铺名
$line = '窗边小豆豆的奶茶铺子';
$printer->setJustification(Printer::JUSTIFY_CENTER);
$printer->textChinese($line, true);

//大字
$printer->setTextSize(2);

//Section: 外卖 / 自提
$line = '【外卖】';
$printer->textChinese($line, true);

//恢复默认
$printer->setTextSize();
$printer->setJustification();

$printer->separator('-');

//Section: 下单时间
$printer->textLabel('下单时间:', date('Y-m-d H:i:s'));

//Section: 订单编号
$printer->textLabel('订单编号:', "BU20171829UUKL");

//Section: 付款人
$printer->textLabel('付款人:', " cfgxy");

$printer->separator('-');


//Section: 表头
$printer->textChinese(mb_sprintf("%-16s%-6s%10s", "商品", "数量", "单价"), true);

//Section: 商品列表
$list = [
    [
        'name'      => '苹果',
        'amount'    => 2,
        'price'     => number_format(10.023, 2)
    ],
    [
        'name'      => '香蕉',
        'amount'    => 3,
        'price'     => number_format(9.026, 2)
    ],
    [
        'name'      => '商品名称比较长比较长比较长比较长长比较长长比较长长比较长长比较长长长长长长长长长',
        'amount'    => 1,
        'price'     => number_format(10, 2)
    ]
];

foreach ($list as $item) {
    if (mb_strwidth($item['name']) > 16) {
        $printer->textChinese($item['name'], true);
        $printer->textChinese(mb_sprintf("%-16s%-6d%10s", "", $item['amount'], $item['price']), true);
    } else {
        $printer->textChinese(mb_sprintf("%-16s%-6d%10s", $item['name'], $item['amount'], $item['price']), true);
    }
}

$printer->separator('-');

//Section: 两列
$printer->textLabel('名称1:', "value1");
$printer->separator('-');

//Section: 两列
$printer->textLabel('名称2:', "value2");
$printer->separator('-');

//Section: 两列
$printer->textLabel('名称3:', "value3");
$printer->separator('-');

//Section: 地址
$printer->setTextSize(2);//大字
$line = '地址:合肥市菜鸟级工程师Jason测试打印比较长的地址会怎样长长长长长长长长长长长长长长长长长长长长长长长长 so?fucking you!';
$printer->setJustification(Printer::JUSTIFY_CENTER);
$printer->textChinese($line, true);
//恢复默认
$printer->setTextSize();
$printer->setJustification();

//Section: 表尾
$printer->separator('-', '订单结束');


$printer->feed(2);
// 切纸(多数大打印机不支持)
$printer->cut();

echo $printer->flushBase64();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值