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

如何实现列表中每个元素对应打印一张票据?

票据打印重复最后一个元素问题的解决方案

核心原因

问题根源是文件写入的缓冲区未及时同步到磁盘,或者打印操作在内容真正落地前就执行了。Python文件写入默认采用缓冲机制,循环内的write操作可能只是把内容存在内存里,没立刻写到磁盘,导致打印程序读取的始终是旧内容;等循环结束后缓冲区一次性刷新,所有打印任务最终读取的都是最后一次写入的内容。

可行解决方法

方法1:强制刷新缓冲区并确保文件关闭

每次写入后立刻刷新缓冲区并关闭文件,保证内容写入磁盘后再触发打印。示例代码:

import win32api
import win32print

ticket_contents = ["票据A内容", "票据B内容", "票据C内容"]
temp_file = "ticket_temp.txt"

for content in ticket_contents:
    # 覆盖写入文件,使用with语句自动处理关闭
    with open(temp_file, "w", encoding="utf-8") as f:
        f.write(content)
        f.flush()  # 强制把内存内容刷到磁盘
    # 执行打印
    win32api.ShellExecute(
        0,
        "print",
        temp_file,
        f'/d:"{win32print.GetDefaultPrinter()}"',
        ".",
        0
    )

方法2:使用临时文件避免覆盖冲突

给每个票据生成独立的临时文件,打印完成后删除,彻底避免文件覆盖的竞态问题:

import win32api
import win32print
import tempfile
import os
import time

ticket_contents = ["票据A内容", "票据B内容", "票据C内容"]

for content in ticket_contents:
    # 创建不自动删除的临时文件
    with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as f:
        f.write(content)
        temp_path = f.name
    # 执行打印
    win32api.ShellExecute(
        0,
        "print",
        temp_path,
        f'/d:"{win32print.GetDefaultPrinter()}"',
        ".",
        0
    )
    # 短暂延迟确保打印进程读取完文件再删除
    time.sleep(0.5)
    os.unlink(temp_path)

方法3:改用同步打印方式

ShellExecute是异步执行的,可能打印还没读取文件,下一次循环就覆盖了内容。可以使用win32print的同步打印接口,确保打印完成后再进行下一次写入:

import win32print
import win32api

ticket_contents = ["票据A内容", "票据B内容", "票据C内容"]

printer_name = win32print.GetDefaultPrinter()
h_printer = win32print.OpenPrinter(printer_name)

try:
    for content in ticket_contents:
        # 创建打印作业
        job_info = win32print.StartDocPrinter(h_printer, 1, ("Ticket", None, "TEXT"))
        win32print.StartPagePrinter(h_printer)
        # 写入打印内容
        win32print.WritePrinter(h_printer, content.encode("utf-8"))
        win32print.EndPagePrinter(h_printer)
        win32print.EndDocPrinter(h_printer)
finally:
    win32print.ClosePrinter(h_printer)

之前尝试无效的原因

  • 把close()移到循环外:整个循环结束才关闭文件,所有写入都积压在缓冲区,打印时读取的始终是未更新的文件内容,直到最后一次写入才刷新到磁盘。
  • 删除close()语句:Python会在文件对象被垃圾回收时自动关闭,但循环内的文件对象可能未被及时回收,缓冲区未刷新,导致打印读取的还是旧内容。

内容的提问来源于stack exchange,提问作者MR.GOBBO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:36:15