PHP控制连接打印机
一、需求
- 使用PHP控制连接打印机
- 现场实时连续打印动态数据
二、配置
- php运行环境正确安装(Apache|Nginx + PHP)
- 下载与php版本对应的php_printer.dll扩展
- 扩展文件添加到ext目录
- 编辑php.ini 添加
extension=php_printer.dll;
三、使用
1.基本的代码结构:
<?php
$handle = printer_open('printer name');
printer_start_doc($handle, "doc name");
printer_start_page($handle);
printer_set_option($handle, PRINTER_MODE, "RAW");
//具体的打印部分
printer_end_page($handle);
printer_end_doc($handle);
printer_close($handle);
?>
以上为基本的代码结构,如果不指定printer_start_doc
与printer_start_page
,打印机是不会进行打印的。
2.具体文字与图形的打印方法介绍
- 对打印机的初始设定:
printer_set_option
,可以设定打印模式、doc标题、打印份数、纸张格式等,参考printer_set_option文档。 - 创建一个字体:
$font = printer_create_font('simsun',字体高度,字体宽度,字体粗细, 是否斜体, 是否加下划线, 是否加删除线, 方向);
具体参见。 - 在打印文字之前首先要选择字体
printer_select_font($handle, $font);
- 使用
printer_draw_text($handle,'要打印的文字',起始x,起始y);
四、遇到的坑
使用一个服务器端的弱类型的脚本语言去跟硬件打交道,本来就是一件略扯得事情,过程中磨难多多啊。
- 在windows上开始配置的服务器是Apache,在打印的时候总是无法打印出正常的尺寸,总是连续打三页。后来,在直接在命令行使用php 命令运行脚本,可以正常的打印,最终究其原因,是Apache服务运行的权限为普通用户,改为超级管理员,或者以超级管理员的身份登录即可。
- 字体,一些打印机都附带了相应的客户端软件。但是使用php去控制打印机软件这些东西就没卵用了,所以创建字体就是个坑,字体的名称,首先是在windows font 文件夹中找到相应的文字,然后右键属性查看名称,就是需要填在printer_create_font的第一个参数了。但是:
- 部分类型的字体中文是无法正常显示。至今无解,可能是打印机内存有限,无法装下全部的字体文件。
- 创建字体需要指定宽高,但是宽高的单位不知道是什么鬼,只能自己尝试
- 同样指定问题的位置需要x y的位置坐标值,方法是printer_draw_line 画一条对角线,自己根据宽高比计算。
- 打印中文乱码,原因:使用表单提交过了的数据为UTF-8编码,而打印机不一定是UTF-8编码的,需要查阅说明书,进行编码格式转换。
- 连续打印几十几百windows直接被干死,蓝屏思密达。最终是Apache进程的问题,每一次打印都会创建一个进程,但是,Apache的进程回收貌似总是不及时,最终系统直接死掉,尝试进行最大连接数等的配置更改,并无作用。最终解决办法:更换Nginx服务器,问题解决。
遗留问题:
对于宽度高度单位与标签纸的尺寸的关系和单位换算,现在没弄清楚。
对于为什么只有部分的Windows字体可以使用的原因,现在没弄清楚。
2016.11.10更新
一、遗留问题宽高尺寸单位换算
通过当前使用的打印机Godex ez1105指令文档,打印机中的单位为dot
,1mm=8dot,所以对于单位需查阅相应打印机型号的打印机文档。
二、使用printer_write打印条码
最开始打印条码的方案是使用php生成条码图片,然后使用printer_draw_bmp
来打印图片,但是这样效率比较低,通过查阅决定使用printer_write
方法直接打印指令
1.找到打印机指令文档,ez1105这款打印机使用的是EZPL指令
2.查看语法,找到条码打印指令Bt,x,y,narrow,wide,height,rotation,readable,data
3.php代码示例
$handle = printer_open('打印机名');
printer_set_option($handle, PRINTER_MODE, "RAW");//printer mode必须设定为RAW
$ZPL = "
^L
Dy2-me-dd
Th:m:s
AZ3,86,66,4,4,0,0E,{$name}
BA,42,158,2,5,50,0,3,99922959
E
"
printer_write($handle, $ZPL);
printer_close($handle);
三、遇到的新坑
1.在原有代码结构的基础上使用printer_write
会打印两份出来,一份是基本的打印名字,另一个是指令打印的,所以使用指令打印,就不到将代码放到printer_start_doc printer_start_page中,会被视为两个不同的文档。
2.打印指令不执行
//使用这种EZPL指令字符串
$ZPL = "^L".PHP_EOL;
$ZPL .= "Dy2-me-dd".PHP_EOL;
...
//这种格式生成的指令无法执行,需要把指令直接放到双引号之间
3.打印机总是延迟打印一个(第一次执行代码,打印机没有执行,好像缓存了)
最终发现问题的所在是最后一个指令后面没有换行直接跟双引号
$ZPL = "
^L
Dy2-me-dd
Th:m:s
AZ3,86,66,4,4,0,0E,{$name}
BA,42,158,2,5,50,0,3,99922959
E"//这里这样是不可以的,必须换行,同样起始位置也一样,双引号后必须换行
2017.01.18更新
对新发现的内容补充一下。
一、指令打印文字不清晰问题
由于打印机的分辨率问题,普通的打印机(如我这使用的EZ1105)直接使用打印机指令打印中文字体,会出现锯齿,但是指令打印方式与printer_draw_text
又不可以同时使用。所以既要清晰的文字还要条码信息,只能更换条码打印方式。
之前顾虑的图片打印条码方式可能产生的效率问题,其实是多虑了,经过实践,每次生成的图片就几KB,完全不影响速度。
所以使用了github上的一个开源库来生成条码的png图片,然后再将png的图片转为1位的bmp图片(因为php_printer 只提供了打印bmp格式的图片的方法)。具体可参考示例代码IMGGenerator.php
。
注:因为
printer_draw_text
方法使用的字体是通过printer_create_font
方法,所以每次就是生成要打印的文字的矢量数据,然后再传递给打印机,所以才清晰。
二、打印字体宽高数值与真实的打印字号关系
因为我们熟悉的是office中选择的一号、二号等字体打印出来的大小,但是打印机并不是一一对应,虽然知道了1mm=8dot这个公式,还是必须经过多次的尝试才能得出结论,经查文档有一个字号转换公式:
当TTF字型的宽度与高度设为相同时,印出的字型即可与Windows字型相同,TTF字型的运算公式为: TTF字型高度 = Windows字型号数 * dpi /72. dpi即打印机的分辨率。(此部分内容打印机不同可能公式不同,请查阅相关型号打印机文档)。
部分相关实例代码已更新到github!
附Github:连接打印机示例代码
原文地址博客园
PHP控制连接打印机的更多相关文章
- PHP连接打印机
<?php header("Content-type: text/html; charset=utf-8"); class Netprint{ public $host = ...
- javax.transaction.xa.XAException: java.sql.SQLException: 无法创建 XA 控制连接。(SQL 2000,SQL2005,SQL2008)
javax.transaction.xa.XAException: java.sql.SQLException:无法创建 XA 控制连接.错误: 未能找到存储过程'master..xp_sqljdbc ...
- 打印机驱动冲突和端口异常:win10更新部分补丁后,打印机本地连接(连接打印机的主机)可以打印,其他共享网络中的电脑可以连接到打印机,但不能打印——解决方案
一.问题描述: 1.A(WIN10系统)表示连接打印机的电脑,P表示打印机(型号:惠普127M),B(WIN7系统)表示局域网中的电脑 2.A升级后部分补丁后,A可以使用打印机P打印文件,B显示可以连 ...
- 计算机windows7连接打印机
计算机连接打印机 (1)查看打印机的名字. 示例,打印机名为 HP LaserJet M1522 .... (2)打开windows开始菜单,点击[设备和打印机],然后查看打印机和传真那个区域是否有打 ...
- centos7 连接打印机
centos7 连接打印机 2017-08-07 15:05:33 五岳寻仙客 阅读数 2531更多 分类专栏: Liunx的日常使用 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版 ...
- 【转】C#使用ESC指令控制POS打印机打印小票
.前言 C#打印小票可以与普通打印机一样,调用PrintDocument实现.也可以发送标注你的ESC指令实现.由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的pos ...
- C#使用ESC指令控制POS打印机打印小票
1.前言 C#打印小票可以与普通打印机一样,调用PrintDocument实现.也可以发送标注你的ESC指令实现.由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的po ...
- C# 控制连接超时
首先连接超时分为三种,TCP Connection to SQL Server -> SqlConnection.Open -> SqlCommand.Execute先说第二种超时,sql ...
- 基于 Koa平台Node.js开发的KoaHub.js连接打印机的代码
最近好多小伙伴都在做微信商城的项目,那就给大家分享一个基于 Koa.js 平台的 Node.js web 开发的框架连接微信易联云打印机接口的代码,供大家学习.koahub-yilianyun 微信易 ...
随机推荐
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS. 选择算法也就是求一个无序数组中第K大( ...
- IOS研究院之打开照相机与本地相册选择图片(六)
原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:IOS研究院之打开照相机与本地相册选择图片(六) Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈. 这篇文章主要学习 ...
- JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案
JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案 最近在开发WSS RESTful服务的时候, 碰到了这些个纠 ...
- node.js系列笔记之fs模块《二》
一:感触 最近工作比较忙,感觉也比较多,因为工作上的不顺利,再加上加班比较多,所以最近心情不是很好,再加上英语能力差到不行,所以最近半个月学习进度也比较慢, 但还是告诉自己每天都坚持学一点,即使今天心 ...
- 一步步学习Python-django开发-建立django数据库
上篇文章建立了一个空的网站.现在我们要准备正式我们的网站开发咯.那么开发的第一步是啥呢?当然是要确定做什么网站了.每个人的开发习惯可能不尽相同,有点可能是从前端开始设计,有的可能是从数据库开始设计(不 ...
- POJ 3348 Cows
题目大意: 给你n棵树,可以用这n棵树围一个圈,然后在圈里面可以养牛,每个牛需要50平方米的空间,问最多可以养多少牛? 其实就是求一个凸包,计算凸包面积,然后除以50,然后就得到答案,直接上模板了. ...
- 跨站请求伪造(Cross Site Request Forgery (CSRF))
跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Site Request Forgery (CSRF)) 跨站请求伪造(Cross Sit ...
- 谈谈new Thread的弊端及Java四种线程池的使用
1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...
- [avalon]data-repeat-rendered循环渲染完毕后的回调函数
有些时候需要在渲染完毕后,引用其他类似JQ插件的初始化工作.这时候需要使用data-repeat-rendered的回调函数. 应用场景: 在metro-start界面下,需要给每个tile引用cli ...
- OC之知识储备篇
1. Objective-C是基于C语言的. a. 在C语言的基础之上新增了面向对象的语法. b. 将C语言中复杂的.繁琐的语法封装的更为简单. 2. Objective-C程序的源文件的后缀名.m ...