如何在Python中实现二维码的静默打印(POS系统场景)
问题解决与替代方案
一、修复当前win32api.ShellExecute的打印问题
你不需要把PNG转成文档文件,问题出在generate_qr函数的返回值和ShellExecute的参数不匹配:ShellExecute需要的是文件路径,但你的函数返回的是打开的文件对象和类型。
修改generate_qr函数
让它直接返回临时PNG文件的路径:
def generate_qr(qr_input): with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as tmpfile: qr = qrcode.make(qr_input) qr.save(tmpfile, qr.format, quality=100) # 返回临时文件的路径,而非打开的文件对象 return tmpfile.name
修改do_POST中的打印逻辑
传入文件路径,并在打印完成后清理临时文件:
def do_POST(self): print(self.headers) content_len = int(self.headers.get('content-length', 0)) post_body = self.rfile.read(content_len).decode('utf-8') print(post_body) print_qr_path = generate_qr(post_body) # 调用ShellExecute打印PNG win32api.ShellExecute( 0, 'print', print_qr_path, f'"{win32print.GetDefaultPrinter()}"', '.', 0 # 0表示静默执行,不弹出窗口 ) # 延迟删除临时文件(确保打印完成) import os import time time.sleep(1) os.unlink(print_qr_path)
二、其他静默打印实现思路
1. 用win32print底层API直接打印(更可控)
不依赖系统图片查看器,直接通过Windows API绘制并打印图片,避免关联程序的兼容性问题:
import win32print import win32ui from PIL import Image, ImageWin import os def print_image_silent(image_path): printer_name = win32print.GetDefaultPrinter() hprinter = win32print.OpenPrinter(printer_name) try: devmode = win32print.GetPrinter(hprinter, 2)['pDevMode'] hdc = win32ui.CreateDC() hdc.CreatePrinterDC(printer_name, devmode) # 初始化打印作业 hdc.StartDoc("QR Code Print Job") hdc.StartPage() # 加载并调整图片尺寸以适应打印区域 img = Image.open(image_path) print_width, print_height = hdc.GetDeviceCaps(8), hdc.GetDeviceCaps(10) scale = min(print_width/img.width, print_height/img.height) new_size = (int(img.width*scale), int(img.height*scale)) # 居中绘制 x = (print_width - new_size[0])//2 y = (print_height - new_size[1])//2 dib = ImageWin.Dib(img) dib.draw(hdc.GetHandleOutput(), (x, y, x+new_size[0], y+new_size[1])) hdc.EndPage() hdc.EndDoc() finally: win32print.ClosePrinter(hprinter) os.unlink(image_path) # 打印完成后删除临时文件
在do_POST中调用:
print_qr_path = generate_qr(post_body) print_image_silent(print_qr_path)
2. 用subprocess调用系统命令打印
Windows下可以用mspaint /p命令静默打印图片,无需额外库:
import subprocess import os import time def print_image_subprocess(image_path): # 调用画图工具静默打印 subprocess.run( ["mspaint", "/p", image_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True ) time.sleep(1) os.unlink(image_path)
3. 跨平台方案:pycups
如果项目需要支持多平台(Windows/Linux/macOS),可以使用pycups库调用CUPS打印系统:
import cups import os def print_image_cups(image_path): conn = cups.Connection() printer_name = conn.getDefault() # 提交PNG打印作业 conn.printFile(printer_name, image_path, "QR Code Print Job", {"document-format": "image/png"}) os.unlink(image_path)
需要先安装依赖:pip install pycups(Windows下可能需要额外配置CUPS环境)
内容的提问来源于stack exchange,提问作者Greekatos
相关产品推荐
相关产品推荐

