Python无声打印PDF到特定打印机

Python无声打印PDF到特定打印机,python,pdf,printing,Python,Pdf,Printing,我有一个PDF文档,我想用我的python应用程序打印它 我在中尝试过该解决方案,但当我安装Ghostscript 9.15(实际版本)时,它没有gsprint.exe 我使用的工作方式是使用命令os.startfile('PDFfile.pdf',“print”),但它会打开默认查看器(我的是Adobe Reader),打印后它仍然打开,试图用os.system(“TASKKILL/F/IM AcroRD32.exe”)终止进程。终止其他打开的窗口,我不想要它 使用下一个命令,它也可以打印,但

我有一个PDF文档,我想用我的python应用程序打印它

我在中尝试过该解决方案,但当我安装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)
我也看过,但他们建议再次使用
gsprint.exe

任何人都有
gsprint.exe文件或任何其他解决方案


注意:当我使用另一个默认程序打开诸如Chrome或Windows Reader之类的PDF文件时,我总是在执行上述命令时遇到异常情况(31,“ShellExecute”,“连接到系统的设备不起作用”)
[错误1155]没有应用程序与此操作的指定文件相关联:'PDFfile.pdf'
使用
startfile
命令经过数小时的搜索,终于找到了问题的答案

您可以在中下载GSPRINT

您可以在中下载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)
在官方网页上也可以找到鬼脚本

我找到了64位的gsprint.exe


我希望这会有所帮助。

这里有一种方法,可以在与python脚本相同的目录中无需
gsprint
win32api
以静默方式打印pdf。它允许更多的重影脚本定制,如选择宽度/高度等

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

如果您想要打印特定页面和一些其他参数,您应该在
gsprint
的参数中指定它们,如下所示:

import win32print
import win32api

GHOSTSCRIPT_PATH = "C:\\path\\to\\GHOSTSCRIPT\\bin\\gswin32.exe"
GSPRINT_PATH = "C:\\path\\to\\GSPRINT\\gsprint.exe"

params = '-ghostscript "'+ GHOSTSCRIPT_PATH  +'" -printer "'+currentprinter+'" -from 1 -to 3 -landscape -copies 1 "1.pdf "'
print(params)

win32api.ShellExecute(0, 'open', GSPRINT_PATH, params, '.',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") 
打印帮助后杀死阅读器不会阻止当前任务

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 /o /t "{}" "{}"'.format(acrobat, pdf_file, name)
for i in range(10)):
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

它不会阻止当前任务并关闭其他pdf文件。

我知道这是一个老问题,但如果有人在找它,这里是我如何修复它的

我在windows 10上使用python3.8和gs9.52 64位和python3 ghostscript库,您可以使用
pip安装python3 ghostscript
安装该库。我还使用pypiwin32获取默认打印机名称,您可以使用pip
pip安装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)
这里需要注意的几点是,我使用了“#”而不是“=”,因为出于某种原因,它不能与“=”一起工作


如果这对您不起作用,请尝试将-s设备开关更改为您的打印机类型,例如,当我使用HP LaserJet时,它给了我提示,因此我将-s设备更改为LaserJet,它起作用了,您可以通过在终端中运行
gs-h
来获取设备列表,因此这并不完全是无声的,但它会自动关闭对话框并打印,而且对selenium有一种奇怪的依赖性,这是你无法想象的,但这对我来说确实有效,因为我所在的世界不允许下载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)
    

    

基于之前的回答和其他帖子,我开发了以下脚本,用于从Laravel网站打印
.pdf
.ps

我使用了
python3.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-文件“D:\my\system\path\to\file\pattern.ps”-打印机“HP1FF6CC(HP OfficeJet Pro 6970)”

将一个文件打印到虚拟打印机
Microsoft print To PDF
(通常用于文本目的,纸张很快就会很贵)


python main.py-文件“D:\my\system\path\to\file\pattern.ps”-打印机“Microsoft打印到PDF”-虚拟的“

gsprint.exe for 64位链接已失效(2017年10月),但此链接适用于32位:对于windows,它是旧链接。ubuntu或linux这个软件包不存在,这是特定于窗口的回答。它不会自动打印文件——它会打开一个窗口一秒钟左右,然后再次关闭!这不会以静默方式打印文件-它会打开一个窗口一秒钟左右,然后再次关闭@bdoubleu
gswin64c
gswin64
之间有什么区别?谢谢这对我所需要的很有效,但是,即使在关闭窗口后,我的adobe acrobat仍保持打开状态。有没有办法确保它也关闭?请尝试以下方法,cmd=“{}”/n/o/t“{}”“{}”。format(acrobat,file_path,printer_name)proc=subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)stdout,stderr=proc.communicate()proc.terminate()我似乎还是不能让它工作。它用pdf关闭文件,但adobe acrobat本身保持打开状态。尝试模仿它,我想我不会再来了,对我来说,adobe进入任务栏,不会进入打开状态。我相信,adobe在任务栏中保持打开状态,我们无法更改它。