如何在Django中实现本地直连Zebra打印机的标签打印?
解决本地直连Zebra打印机的打印问题
你的现有代码基于Socket连接9100端口,仅适用于具备以太网/无线网络接口的Zebra打印机。对于USB直连本地电脑的打印机,需要根据打印机的连接方式选择不同的实现方案:
方案1:USB直连本地Windows电脑的打印机
如果Django服务运行在Windows环境,且打印机直接通过USB连接到该服务器,可以使用Windows打印后台处理程序发送RAW格式的ZPL指令,需要依赖pywin32库:
步骤1:安装依赖
pip install pywin32
步骤2:实现打印函数
import win32print import win32api def zebra_local_print(zpl_content, printer_name): try: # 打开目标打印机 hprinter = win32print.OpenPrinter(printer_name) try: # 初始化打印作业,指定RAW模式(直接传递ZPL指令) job_info = ("Zebra Label", None, "RAW") hjob = win32print.StartDocPrinter(hprinter, 1, job_info) win32print.StartPagePrinter(hprinter) # 发送ZPL指令(转成ASCII字节流) win32print.WritePrinter(hprinter, bytes(zpl_content, encoding='ascii')) win32print.EndPagePrinter(hprinter) win32print.EndDocPrinter(hprinter) finally: # 确保关闭打印机连接 win32print.ClosePrinter(hprinter) except Exception as e: print(f"本地打印失败: {str(e)}")
获取打印机名称
可以通过以下代码列出系统中所有可用的打印机:
printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL) for printer in printers: print(printer[2]) # 打印机名称
方案2:局域网共享的本地Zebra打印机
如果USB直连的打印机被共享到局域网,可以通过SMB协议发送ZPL指令,依赖pysmb库:
步骤1:安装依赖
pip install pysmb
步骤2:实现打印函数
from smb.SMBConnection import SMBConnection def zebra_shared_print(zpl_content, printer_share_path, username, password, client_name="DjangoServer"): # 解析共享路径,格式示例:\\DESKTOP-ABC123\Zebra_GK420d server_name, share_name = printer_share_path.replace("\\", "/").strip("/").split("/", 1) try: # 建立SMB连接 conn = SMBConnection(username, password, client_name, server_name, use_ntlm_v2=True) if conn.connect(server_name, 139): # 通过LPT1: 管道发送RAW指令到共享打印机 conn.sendFile(share_name, "LPT1:", bytes(zpl_content, encoding='ascii')) conn.close() return True print("无法连接到共享打印机") return False except Exception as e: print(f"共享打印失败: {str(e)}") return False
整合现有代码
扩展原有函数,根据打印机配置自动选择打印方式:
import socket # 导入上面实现的打印函数 from your_module import zebra_local_print, zebra_shared_print def zebra_print(format, printer_option): printer = printer_option printer_obj = Printers.objects.get(name=printer) if printer_obj.ip: # 网络打印机:使用原有Socket方式 mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = printer_obj.ip port = 9100 try: mysocket.connect((host, port)) mysocket.send(bytes(format, encoding='ascii')) mysocket.close() except Exception as e: print(f"网络打印失败: {str(e)}") elif printer_obj.path: printer_path = printer_obj.path if printer_path.startswith("\\\\") or printer_path.startswith("//"): # 共享打印机:调用SMB打印函数 # 建议从配置文件或数据库读取共享账号信息 share_username = "your_share_user" share_password = "your_share_pwd" zebra_shared_print(format, printer_path, share_username, share_password) else: # 本地打印机:调用Windows打印函数 zebra_local_print(format, printer_path)
注意事项
- 如果Django部署在Linux服务器,访问Windows共享打印机需要安装Samba客户端工具(如
smbclient),并确保服务器防火墙允许139/445端口的出站访问。 - 所有场景下都必须使用RAW打印模式,避免系统对ZPL指令进行格式转换。
- 共享打印机需要确保访问账号具备打印权限,且目标电脑的防火墙允许SMB连接。
内容的提问来源于stack exchange,提问作者Antonio Amo Sánchez
相关产品推荐
相关产品推荐

