如何将ZPL打印任务通过TCP/IP发送至带USB打印机的客户端实现打印?
实现思路与具体方案
我来帮你捋清楚怎么实现——核心就是在连了USB打印机的客户端上搭一个ZPL接收转打印服务,把你的APP发过来的ZPL指令转交给本地打印机执行。下面给你几个可行的方案,从快速上手到灵活自定义都有:
方案1:用现成的打印服务器工具(最快落地)
很多轻量工具可以直接把USB打印机转换成网络可访问的Raw打印服务,完美适配你的ZPL需求:
- 这类工具会监听你指定的端口(比如工业打印机常用的9100),收到Raw格式的ZPL数据后,直接提交给本地USB打印机,不需要额外格式转换。
- 操作步骤:
- 在客户端安装工具:Windows可以用
Raw Print Server这类专用工具,Linux/macOS可以直接用系统自带的CUPS打印服务(开启网络打印功能即可)。 - 配置工具:关联目标USB打印机,设置监听端口(和你APP要发送的端口保持一致,比如9100)。
- 在你的APP里配置客户端IP和这个端口,直接发送ZPL任务就行——工具会自动完成接收转打印的流程。
- 在客户端安装工具:Windows可以用
- 关键提醒:一定要确保工具支持Raw模式打印,ZPL是纯硬件指令,任何额外的格式转换都会导致打印乱码。
方案2:自己写个简单监听脚本(灵活可控)
如果不想依赖第三方工具,几十行代码就能搞定自定义服务,适合有基础的开发者:
Windows平台(Python实现)
- 先把USB打印机设为默认打印机,或者通过
win32print.EnumPrinters()命令获取它的准确名称。 - 编写监听+打印脚本:
import socket import win32print import win32api # 配置参数 LISTEN_PORT = 9100 PRINTER_NAME = "你的USB打印机名称" # 替换成实际打印机名 def print_zpl(zpl_content): # 连接打印机并提交Raw任务 h_printer = win32print.OpenPrinter(PRINTER_NAME) try: # 初始化打印任务 win32print.StartDocPrinter(h_printer, 1, ("ZPL打印任务", None, "RAW")) win32print.StartPagePrinter(h_printer) # 发送ZPL指令(编码根据打印机调整,一般utf-8或cp1252) win32print.WritePrinter(h_printer, zpl_content.encode('utf-8')) win32print.EndPagePrinter(h_printer) win32print.EndDocPrinter(h_printer) finally: win32print.ClosePrinter(h_printer) def main(): # 创建TCP监听socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', LISTEN_PORT)) server_socket.listen(1) print(f"已启动ZPL监听服务,端口:{LISTEN_PORT}") while True: client_conn, client_addr = server_socket.accept() print(f"收到来自 {client_addr} 的连接") # 接收完整ZPL数据 zpl_data = b"" while True: chunk = client_conn.recv(1024) if not chunk: break zpl_data += chunk client_conn.close() # 提交打印任务 print_zpl(zpl_data.decode('utf-8')) print("打印任务已提交至USB打印机") if __name__ == "__main__": main()
- 安装依赖:执行
pip install pywin32 - 运行脚本,然后在你的APP里配置客户端IP和9100端口,发送ZPL即可。
Linux/macOS平台(Python+CUPS实现)
- 确保客户端安装了CUPS服务,并且USB打印机已添加到CUPS(用
lpstat -p命令查看打印机名称)。 - 编写监听+打印脚本:
import socket import subprocess # 配置参数 LISTEN_PORT = 9100 PRINTER_NAME = "你的USB打印机名称" # 替换成实际打印机名 def print_zpl(zpl_content): # 用lp命令提交Raw打印任务 subprocess.run( ["lp", "-d", PRINTER_NAME, "-o", "raw"], input=zpl_content.encode('utf-8'), check=True ) def main(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', LISTEN_PORT)) server_socket.listen(1) print(f"已启动ZPL监听服务,端口:{LISTEN_PORT}") while True: client_conn, client_addr = server_socket.accept() print(f"收到来自 {client_addr} 的连接") zpl_data = b"" while True: chunk = client_conn.recv(1024) if not chunk: break zpl_data += chunk client_conn.close() print_zpl(zpl_data.decode('utf-8')) print("打印任务已提交至USB打印机") if __name__ == "__main__": main()
- 安装依赖:Linux先装
libcups2-dev,再执行pip install pycups(或者直接用系统的lp命令,不需要额外依赖)
必看注意事项
- 打印机兼容性:确保你的USB打印机原生支持ZPL指令(比如斑马、得力等工业条码打印机),否则会打印乱码。如果打印机不支持ZPL,需要先把ZPL转换成打印机支持的格式(比如PDF),但流程会复杂很多。
- 端口权限:如果监听1024以下的端口(比如9100),Linux/macOS需要用
sudo运行脚本,或者给程序授权端口权限。 - 防火墙设置:客户端的防火墙要允许你APP所在机器访问监听的端口,不然连接会被拦截。
内容的提问来源于stack exchange,提问作者bpoiss




