蓝牙热敏打印机:php+ios+android
github地址:https://github.com/mike42/escpos-php 这个非常全,各种打印,想怎么打怎么打。网友封装的php 打印类
// 字体大小
const JsonLi_FontSizeSmall = "\x00";
const JsonLi_FontSizeMiddle = "\x11";
const JsonLi_FontSizeBig = "\x22";
// 对齐方式
const JsonLi_Left = "\x00";
const JsonLi_Center = "\x01";
const JsonLi_Right = "\x02";
const JsonLi_WIDTH_PIXEL = 384;
const JsonLi_IMAGE_SIZE = 320;
class PrintDeviceUtil
{
public $printWhiteString;
function __construct() {
$this->initPrintDevice();
}
/**
* 初始化打印机
*/
protected function initPrintDevice(){
// $this->printWhiteString = "\x1b\x40\x1b\x32\x1b\x4d\x00";
$this->printWhiteString = "\x1b\x40";
}
/**
* 设置字体大小
*/
protected function setTextFont($size) {
$this->printWhiteString .= "\x1d" . "\x21" . $size;
}
/**
* 设置对齐方式
*/
protected function setAlignment($alignment) {
$this->printWhiteString .= "\x1b" . "\x61" . $alignment;
}
/**
* 换一行
*/
protected function addNewLine() {
$this->addMuiltNewLine(1);
}
/**
* 换多行
*/
protected function addMuiltNewLine($linenum) {
for ($i = 0; $i < $linenum; $i++) {
$this->printWhiteString .= "\x0A";
}
}
/*
* 添加分割线
*/
protected function addDividingLine ()
{
$this->setAlignment(JsonLi_Center);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->printWhiteString .= "- - - - - - - - - - - - - - - -";
$this->addNewLine();
}
/**
* 设置文本
*/
protected function setText($text) {
$this->printWhiteString .= iconv("UTF-8","GB2312//IGNORE",$text);
}
/*
* 获取偏移量
*/
protected function getOffset($str) {
return JsonLi_WIDTH_PIXEL - mb_strwidth($str);
}
/*
* 设置偏移量
*/
protected function setOffset($str) {
$offset = $this->getOffset($str);
$remainder = $offset % 256; // 低位
$consult = $offset >> 8; // 高位
$offsetBytes = "\x1B\x24" . chr($remainder) . chr($consult);
$this->printWhiteString .= $offsetBytes;
}
public function testPrint(){
$this->setAlignment(JsonLi_Center);
$this->setTextFont(JsonLi_FontSizeBig);
$this->setText("泛客云商");
$this->addNewLine();
$this->addDividingLine();
$this->setAlignment(JsonLi_Left);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->setText("时间:");
$value = "2018-01-01";
$this->setOffset($value);
$this->setText($value);
$this->addNewLine();
$this->setAlignment(JsonLi_Left);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->setText("订单号:");
$this->setAlignment(JsonLi_Right);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->setText("XXXXXXXXXXX");
$this->addNewLine();
$this->setAlignment(JsonLi_Left);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->setText("付款人:");
$this->setAlignment(JsonLi_Right);
$this->setTextFont(JsonLi_FontSizeSmall);
$this->setText("XXXXXXXXXXX");
$this->addNewLine();
$this->addDividingLine();
$this->addMuiltNewLine(3);
// $result = $this->printWhiteString . iconv("UTF-8","GB2312//IGNORE","泛客云商") ;
// $printWhiteString = $printWhiteString . "测试测试";
//return $this->printWhiteString;
return base64_encode($this->printWhiteString);
// return strlen("我爱上海");
// $hex = '';
// for ($i = 0; $i < strlen($this->printWhiteString); $i++) {
// $hex .= sprintf("%02x", ord($this->printWhiteString[$i]));
// }
//
// $hex .= PHP_EOL;
//
// return $hex;
// return $this->printWhiteString;
}
}
$p = new PrintDeviceUtil;
echo $p->testPrint();
使用第三方封装的:
<?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测试打印比较长的地址会怎样!.
!&------------订单结束------------.
*/
$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?yizuotu.net ';
$printer->setJustification(Printer::JUSTIFY_CENTER);
$printer->textChinese($line, true);
//恢复默认
$printer->setTextSize();
$printer->setJustification();
//Section: 表尾
$printer->separator('-', '订单结束');
$printer->feed(2);
// 切纸(多数大打印机不支持)
$printer->cut();
echo $printer->flushBase64();