我有一个PDF文档,我想用我的python应用程序打印它。
我在here (Print PDF document with python's win32print module?)尝试了解决方案,但是当我安装Ghostscript 9.15时,它是实际版本,它没有gsprint.exe
我使用它的方式是使用命令os.startfile('PDFfile.pdf', "print")
,但它打开默认查看器(我的是Adobe Reader),打印后它仍然打开,试图用os.system("TASKKILL /F /IM AcroRD32.exe")
杀死其他进程杀死其他打开窗户,我不想要它。
使用下一个命令,它也会打印,但它也会打开Adobe Reader
currentprinter = win32print.GetDefaultPrinter()
win32api.ShellExecute(0, "print", 'PDFfile.pdf', '/d:"%s"' % currentprinter, ".", 0)
我也见过this answer,但他们建议再次使用gsprint.exe
是否有人拥有gsprint.exe
文件或任何其他解决方案?
注意:当我使用其他默认程序打开Chrome或Windows Reader等PDF文件时,我总是在执行'(31, 'ShellExecute', 'A device attached to the system is not functioning.')'
或{{1}上面的命令时遇到异常使用[Error 1155] No application is associated with the specified file for this operation: 'PDFfile.pdf'
命令
答案 0 :(得分:12)
最后,经过几个小时的搜索正确的文件后,我找到了问题的答案。
您可以在HERE
下载GSPRINT您可以在HERE
下载Ghostscript GPL使用PC(Windows)中提取的文件,您可以使用此命令打印PDF
GHOSTSCRIPT_PATH = "C:\\path\\to\\GHOSTSCRIPT\\bin\\gswin32.exe"
GSPRINT_PATH = "C:\\path\\to\\GSPRINT\\gsprint.exe"
# YOU CAN PUT HERE THE NAME OF YOUR SPECIFIC PRINTER INSTEAD OF DEFAULT
currentprinter = win32print.GetDefaultPrinter()
win32api.ShellExecute(0, 'open', GSPRINT_PATH, '-ghostscript "'+GHOSTSCRIPT_PATH+'" -printer "'+currentprinter+'" "PDFFile.pdf"', '.', 0)
GhostScript也可以在官方页面HERE
中找到我找到了64位HERE
的gsprint.exe我希望这会有所帮助。
答案 1 :(得分:1)
我知道这是一个古老的问题,但是如果有人在找,这是我如何解决它。
我在Windows 10 64位和python3-ghostscript库上使用python 3.8和gs9.52,可以使用pip install python3-ghostscript
安装。我也在使用pypiwin32获取默认打印机名称,可以使用点pip install pypiwin32
这是工作脚本
import tempfile
import win32print
import locale
import ghostscript
import render_to_pdf
pdf = render_to_pdf('print/slip.html', context)
temp1 = tempfile.mktemp('.pdf')
f1 = open(temp1, 'ab')
f1.write(pdf)
f1.close()
args = [
"-dPrinted", "-dBATCH", "-dNOSAFER", "-dNOPAUSE", "-dNOPROMPT"
"-q",
"-dNumCopies#1",
"-sDEVICE#mswinpr2",
f'-sOutputFile#"%printer%{win32print.GetDefaultPrinter()}"',
f'"{temp1}"'
]
encoding = locale.getpreferredencoding()
args = [a.encode(encoding) for a in args]
ghostscript.Ghostscript(*args)
这里没有什么要注意的,我使用的是'#'而不是'=',因为某些原因它不能与'='一起使用。
如果这不适用于您,请尝试将-sDEVICE开关更改为您的打印机类型,例如,当我使用 HP LaserJet 时,它提示我,因此我将-sDEVICE更改为Laserjet并成功了,您可以通过在终端上运行gs -h
来获取设备列表
答案 2 :(得分:0)
这是一种在没有gsprint
和win32api
的情况下,在与python脚本相同的目录中静默打印pdf的方法。它允许更多的GhostScript自定义,例如选择宽度/高度等。
import os
import subprocess
import sys
if sys.platform == 'win32':
args = '"C:\\\\Program Files\\\\gs\\\\gs9.23\\\\bin\\\\gswin64c" ' \
'-sDEVICE=mswinpr2 ' \
'-dBATCH ' \
'-dNOPAUSE ' \
'-dFitPage ' \
'-sOutputFile="%printer%myPrinterName" '
ghostscript = args + os.path.join(os.getcwd(), 'myFile.pdf').replace('\\', '\\\\')
subprocess.call(ghostscript, shell=True)
如果您使用的是32位版本的GhostScript,则应使用gswin32c
答案 3 :(得分:0)
如果要打印特定的页面和其他一些参数,则应在CMD
的参数中指定它们,如下所示:
gsprint
答案 4 :(得分:0)
以下代码将阻止当前任务
for i in range(10):
currentprinter = win32print.GetDefaultPrinter()
win32api.ShellExecute(0, "print", 'PDFfile.pdf', '/d:"%s"' % currentprinter, ".", 0)
在打印帮助后杀死阅读器不会阻止当前任务
os.system("TASKKILL /F /IM AcroRD32.exe")
但是它也会关闭其他pdf文件。
如果不能使用gsprint,请使用acrobat命令
import win32print
import subprocess
import time
pdf_file = 'D:\d1\d1.pdf'
acrobat = 'C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe'
name = win32print.GetDefaultPrinter()
cmd = '"{}" /n /h /s /o /t "{}" "{}"'.format(acrobat, pdf_file, name)
for i in range(10)):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
它不会阻止当前任务并关闭其他pdf文件。
答案 5 :(得分:0)
所以这不是完全无声的,但它会自动关闭对话框并无论如何打印,而且对硒有一种奇怪的依赖,你本身不会期望,但这实际上对我有用,因为我在世界上不允许我下载 ghostscript 也不能下载 adobe 的 pdf 阅读器。我认为它可能会帮助其他人,某个地方,某个地方,某个时间......
from selenium import webdriver
import win32com.client
import win32print
import time
def printpdf(pdf,printer):
current_printer = win32print.GetDefaultPrinter()
win32print.SetDefaultPrinter(printer)
driver = webdriver.Chrome()
driver.get(pdf)
time.sleep(1) #Adjust as necessary
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys('^p')
time.sleep(1) #Adjust as necessary
shell.SendKeys('{ENTER}') #dismiss the print dialog box
driver.close()
win32print.SetDefaultPrinter(current_printer)
答案 6 :(得分:0)
根据之前的回答和其他帖子,我开发了以下脚本来从 Laravel 网站打印 .pdf
和 .ps
。
我使用了 python 3.9
和 Ghostscript 9.54
(64 位)。 pywin32
和 python3-ghostscript
库也是必需的。
import os
import sys
import win32print
import win32api
import ghostscript
import locale
USELESS_PRINTER = ['OneNote for Windows 10', 'OneNote (Desktop)', 'Microsoft XPS Document Writer',
'Microsoft Print to PDF', 'Fax']
HELP = """pyPrinter - Author: Arthur SICARD - Date: 19/05/2021
\n-help
\tDisplay this message.
\n-list [-virtual]
\tReturn list of available printer (excepted: """ + ", ".join(USELESS_PRINTER) + """)
\n-file filepath [-printer printer_name] [-virtual]
\tPrint specified file on default system printer. Use -printer to specify printer to use. Printer name must be available un -list response.
\n-batch filepath [-printer printer_name] [-virtual]
\tPrint each document specified un batch file on default system printer. Batch file must be a .txt. Each file to print must be write on its own line.
\tUse -printer to specify printer to use. Printer name must be available un -list response.
\n-virtual
\tUse this option after all other arguments to enable printing on virtual printer 'Microsoft Print to PDF'
"""
# Safe accessor to argv. Return None if index is not set
def getArgv(index):
try:
return (sys.argv[1:])[index]
except:
return None
# Return list of local printer available without "virtual printer" define in USELESS_PRINTER list.
def getAvailablePrinters():
printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL)
printer_list = []
for x in range(len(printers)):
if printers[x][2] not in USELESS_PRINTER:
printer_list.append(printers[x][2])
return printer_list
# Return printer name to use. If -printer is set it will return this value only if value match with available
# printers list. Return a error if -printer not in list. If no printer specified, retrieve default printer and return
# its name. Sometime default printer is on USELESS_PRINTER list so first printer return by getAvailablePrinters() is
# return. If no printer is return display an error.
def getPrinter():
default_printer = win32print.GetDefaultPrinter()
if default_printer in USELESS_PRINTER:
if len(getAvailablePrinters()) == 0:
print("No printer available, unable to print. Use -virtual if you want enable virtual printer.")
sys.exit(1801)
default_printer = getAvailablePrinters()[0]
if getArgv(2) is not None:
if getArgv(2) == "-printer":
printer = getArgv(3)
if printer in getAvailablePrinters():
return printer
else:
if printer is not None:
print("Given printer not found. Defaut printer configured: ", default_printer)
return default_printer
# Use GhostScript API to silent print .pdf and .ps. Use win32api to print .txt. Return a error if printing failed or
# file ext doesn't match.
def printFile(filepath):
try:
if os.path.splitext(filepath)[1] in [".pdf", ".ps"]:
args = [
"-dPrinted", "-dBATCH", "-dNOSAFER", "-dNOPAUSE", "-dNOPROMPT"
"-q",
"-dNumCopies#1",
"-sDEVICE#mswinpr2",
f'-sOutputFile#"%printer%{getPrinter()}"',
f'"{filepath}"'
]
encoding = locale.getpreferredencoding()
args = [a.encode(encoding) for a in args]
ghostscript.Ghostscript(*args)
elif os.path.splitext(filepath)[1] in [".txt"]:
# '"%s"' % enable to encapsulate string with quote
win32api.ShellExecute(0, "printto", '"%s"' % filepath, '"%s"' % getPrinter(), ".", 0)
return True
except:
print("Printing error for file: ", '"%s"' % filepath, "| Printer: ", '"%s"' % getPrinter())
return False
def main(argv):
if len(argv) in [1, 2, 4, 5]:
cmd1 = getArgv(0)
filepath = getArgv(1)
if argv[-1] == "-virtual":
USELESS_PRINTER.remove('Microsoft Print to PDF')
# Batch printing mode
if cmd1 == "-batch" and len(argv) in [2, 4, 5]:
if not os.path.isfile(filepath) and not os.path.exists(filepath):
print("Path provide for batch file is not a valid file path or doesn't exist.")
sys.exit(2)
if os.path.splitext(filepath)[1] in [".txt"]:
with open(filepath) as fp:
line = fp.readline().strip('\n')
while line:
if not os.path.isfile(line) and not os.path.exists(line):
print("Path provide is not a valid file path or doesn't exist: ", line)
else:
printFile(line)
line = fp.readline().strip('\n')
fp.close()
else:
print("Not supported file format for batch printing.")
sys.exit(50)
# Single file printing mode
elif cmd1 == "-file" and len(argv) in [2, 4, 5]:
if not os.path.isfile(filepath) and not os.path.exists(filepath):
print("Path provide is not a file path.")
sys.exit(2)
if not printFile(filepath):
sys.exit(1)
# Get printers list
elif cmd1 == "-list" and len(argv) in [1, 2]:
for printer in getAvailablePrinters():
print(printer)
# Display help
elif cmd1 == "-help" and len(argv) in [1]:
print(HELP)
sys.exit(0)
else:
print("Unknow option. Use -help to obtain more informations about supported options.")
sys.exit(50)
else:
print("Wrong arguments number. Use -help to obtain more informations about supported options.")
sys.exit(50)
exit(0)
if __name__ == '__main__':
main(sys.argv[1:])
以下命令解释如何使用它:
python main.py -help
pyPrinter - Author: Arthur - Date: 19/05/2021
-help
Display this message.
-list [-virtual]
Return list of available printer (excepted: OneNote for Windows 10, OneNote (Desktop), Microsoft XPS Document Writer, Microsoft Print to PDF, Fax)
-file filepath [-printer printer_name] [-virtual]
Print specified file on default system printer. Use -printer to specify printer to use. Printer name must be available un -list response.
-batch filepath [-printer printer_name] [-virtual]
Print each document specified un batch file on default system printer. Batch file must be a .txt. Each file to print must be write on its own line.
Use -printer to specify printer to use. Printer name must be available un -list response.
-virtual
Use this option after all other arguments to enable printing on virtual printer 'Microsoft Print to PDF'
将一个文件打印到打印机 HP1FF6CC (HP OfficeJet Pro 6970)
python main.py -file "D:\my\system\path\to\file\pattern.ps" -printer "HP1FF6CC (HP OfficeJet Pro 6970)"
将一个文件打印到虚拟打印机 Microsoft Print to PDF
(通常用于文本用途,纸张很快就很贵)
python main.py -file "D:\my\system\path\to\file\pattern.ps" -printer "Microsoft Print to PDF" -virtual