Python静默打印PDF到特定的打印机

时间:2014-11-28 20:38:13

标签: python pdf printing

我有一个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'命令

7 个答案:

答案 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)

这是一种在没有gsprintwin32api的情况下,在与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.9Ghostscript 9.54(64 位)。 pywin32python3-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