You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:01:07