我有一台点阵打印机LX-300通过网络连接到我的电脑上。如何在Python中直接发送带有ESCP字符的原始字符串到我的打印机?
计算机通过另一台计算机连接到打印机。我需要发送一个原始字符串,因为LX-300图像打印结果是模糊的。
问题
通过此路由发送数据:
客户端计算机->服务器(Windows机器)->打印机(点阵)
…并且而不是让Windows干扰数据;而是直接从客户端计算机发送原始数据,包括打印机控制代码。
我的解决方案下面是我如何解决一个小型内部数据库应用程序中几乎相同的问题:步骤1)使打印机网络可访问,而不让Windows染指路由给它的数据。我通过使用"通用/纯文本"驱动程序安装打印机,然后安装连接到打印机的Windows机器上的RawPrintServer。
步骤2)将原始数据通过网络发送到设置RawPrintServer时指定的TCP/IP端口(默认为9100)。有很多方法可以做到这一点,下面是我所做的:
data = b"x1B@A String To Printx1B@" # be sure to use the right codes for your printer
ip_addr = 123.123.123.123 # address of the machine with the printer
port = 9100 # or whatever you set it to
s = socket.socket()
try:
s.connect((ip_addr, port))
s.send(data)
except:
# deal with the error
finally:
s.close()
的背景我从两方面考虑了这个问题:
- 客户端机器:从Python中输出我需要的数据,并为我的打印机提供正确的格式/控制代码,并通过网络发送
- 打印服务器:将数据传输到本地连接的打印机
第一个是简单的部分。实际上,PyPI中有一些库可以帮助处理所有的打印机代码,但我发现它们中的大多数都是针对小型销售点标签打印机的,对我来说用处有限。所以我只是把我需要的东西硬编码到我的Python程序中。
当然,您选择解决第2个问题的方式将影响您从Python发送数据的方式。我选择TCP/IP路由是为了避免处理Samba和Windows打印问题。
正如你可能发现的那样,Windows通常会非常努力地将你想要打印的东西转换为位图,并在图形模式下运行打印机。为了防止这种情况,我们可以使用通用驱动程序并将数据直接转储到(本地)打印机端口。
那么,缺失的链接是从网络到连接到打印机的机器上的本地打印机端口。同样,有很多方法可以解决这个问题。您可以尝试以某种方式访问Windows打印机共享。如果你像我一样走TCP/IP路线,你可以用Python编写自己的打印服务器。在我的例子中,RawPrintServer程序"只是工作",所以我没有进一步研究。显然,它所做的就是从TCP端口9100获取传入数据,并将其推入本地打印机端口。显然,您必须确保防火墙没有阻止打印服务器机器上的传入连接。就Windows而言,这种方法不需要打印机被"共享"。
根据您的情况(如果您使用DHCP),您可能需要做一些额外的工作才能在Python中获得服务器的IP地址。在我的例子中,由于我的应用程序的特殊性,我免费获得了IP。
这个解决方案似乎对我很有效。我有一台运行在爱普生ESC/P兼容模式下的旧松下打印机,它连接到一台Windows 7电脑上,我可以在本地网络上的任何一台电脑上打印。顺便说一下,无论客户端计算机运行的是什么操作系统,这个一般的想法都应该工作。
最终,您将需要并希望编写自己的包装器/脚本来完成此操作。由于您使用的是Linux的发行版,所以这相对容易。
在Linux操作系统上,发出打印作业的最简单方法是打开lpr的子进程。一般来说,使用lpr
可以让您访问打印机而不需要以root身份登录(作为超级用户),考虑到以"超级用户"登录时可能造成的损坏数量,这是可取的。
代码如下:
import subprocess
lpr = subprocess.Popen("/usr/bin/lpr", stdin=subprocess.PIPE)
lpr.stdin.write(data_to_send_to_printer)
应该是一个很好的起点。从本质上讲,这段代码应该允许您完成所需的内容。
小心;根据您的权限级别,调用打开子进程可能需要root级别/超级用户权限。
子进程一般由执行该命令的用户继承User id和访问权限。例如,如果子进程是由根用户创建的,那么您将需要根用户/超级用户权限来访问该子进程。
要了解更多信息,请查看我在帖子中包含的超链接。
祝你好运!