我需要编写一个解决方案,在上面写入数据,然后大量打印RFID标签,每个标签都是从模板python脚本生成的.png图像,以及从数据库或excel文件中获取的数据。
要打印该程序,只需使用subprocess.check_call(print_cmd)
调用相关的系统实用程序( unix系统上的CUPS),传递映像文件(保存在内存挂载的文件系统中,以减少磁盘使用量)。
现在,它也需要运行在Windows系统上,但实际上没有一个不错的系统实用程序,而且在类似问题下的解决方案command line tool for print picture?不考虑打印作业的完成,或者如果作业导致错误,所有的边距都会被扭曲,图像总是因为某种原因旋转90度。
如何在Windows中使用命令或脚本明智地打印图像,并等待它成功完成,或者在作业导致错误时返回错误?可能没有依赖关系
发布于 2022-04-16 15:18:45
如果您可以安装依赖项,那么有许多程序提供了现成的解决方案.
用(无依赖项)解决这个问题的唯一正确方法是创建一个powershell脚本来解释这个问题。
[CmdletBinding()]
param (
[string] $file = $(throw "parameter is mandatory"),
[string] $printer = "EXACT PRINTER NAME HERE"
)
$ERR = "UserIntervention|Error|Jammed"
$status = (Get-Printer -Name $printer).PrinterStatus.ToString()
if ($status -match $ERR){ exit 1 }
# https://stackoverflow.com/a/20402656/17350905
# only sends the print job to the printer
rundll32 C:\Windows\System32\shimgvw.dll,ImageView_PrintTo $file $printer
# wait until printer is in printing status
do {
$status = (Get-Printer -Name $printer).PrinterStatus.ToString()
if ($status -match $ERR){ exit 1 }
Start-Sleep -Milliseconds 100
} until ( $status -eq "Printing" )
# wait until printing is done
do {
$status = (Get-Printer -Name $printer).PrinterStatus.ToString()
if ($status -match $ERR){ exit 1 }
Start-Sleep -Milliseconds 100
} until ( $status -eq "Normal" )
然后,我需要稍微修改打印子进程调用
powershell -File "path\to\print.ps1" "C:\absolute\path\to\file.png"
然后有几个必要的设置步骤:
(discaimer,我不使用英语窗口,所以我不知道英文窃听器应该怎么称呼。我会用草书写的)
”
- from the print dialog that opens then set up all the default options you want, like orientation, margins, paper type, etc etc for the specific printer you're gonna use.
- edit _monitoring frequency_ to _"only during print jobs"_. it should be _disabled_ by default
- in the next tab, modify _polling frequency_ to the minimum available, 100ms during print jobs (you can use a lower one for the _while not printing_ option
假设如下:
只有您的程序运行此script
。
此小黑客将允许从命令中打印图像,并通过错误管理等待作业完成;并且只使用windows预装软件。
进一步的优化可以通过保持powershell子进程活动,并且只以& "path\to\print.ps1" "C:\absolute\path\to\file.png"
格式传递脚本来完成,等待标准输出报告OK或KO,但只在需要大规模打印的情况下。
发布于 2022-11-19 15:52:48
由于不得不再次处理此问题,因此只想使用pywin32
包在“纯”python中添加一个更简单的解决方案。
import time
import subprocess
from typing import List
try:
import win32print as wprint
PRINTERS: List[str] = [p[2] for p in wprint.EnumPrinters(wprint.PRINTER_ENUM_LOCAL)]
PRINTER_DEFAULT = wprint.GetDefaultPrinter()
WIN32_SUPPORTED = True
except:
print("[!!] an error occured while retrieving printers")
# you could throw an exception or whatever
# bla bla do other stuff
if "WIN32_SUPPORTED" in globals():
__printImg_win32(file, printer_name)
def __printImg_win32(file: str, printer: str = ""):
if not printer:
printer = PRINTER_DEFAULT
# verify prerequisites here
# i still do prefer to print calling rundll32 directly,
# because of the default printer settings shenaningans
# and also because i've reliably used it to spool millions of jobs
subprocess.check_call(
[
"C:\\Windows\\System32\\rundll32",
"C:\\Windows\\System32\\shimgvw.dll,ImageView_PrintTo",
file,
printer,
]
)
__monitorJob_win32(printer)
pass
def __monitorJob_win32(printer: str, timeout=16.0):
p = wprint.OpenPrinter(printer)
# wait for job to be sheduled
t0 = time.time()
while (time.time()-t0) < timeout:
ptrr = wprint.GetPrinter(p, 2)
# unsure about those flags, but definitively not errors.
# it seems they are "moving paper forward"
if ptrr["Status"] != 0 and ptrr["Status"] not in [1024,1048576]:
raise Error("Printer is in error (status %d)!" % ptrr["Status"])
if ptrr["cJobs"] > 0:
break
time.sleep(0.1)
else:
raise Error("Printer timeout sheduling job!")
# await job completion
t0 = time.time()
while (time.time()-t0) < timeout:
ptrr = wprint.GetPrinter(p, 2)
if ptrr["Status"] != 0 and ptrr["Status"] not in [1024,1048576]:
raise Error("Printer is in error (status %d)!" % ptrr["Status"])
if ptrr["cJobs"] == 0 and ptrr["Status"] == 0:
break
time.sleep(0.1)
else:
raise Error("Printer timeout waiting for completion!")
wprint.ClosePrinter(p)
return
有用的额外资源
https://stackoverflow.com/questions/71895109
复制相似问题