Help us understand the problem. What is going on with this article?

WindowsのPythonでPDFの印刷をする:外部アプリケーションを使う

More than 5 years have passed since last update.

※タイトルに書いておきながらタイトルにも書いてありますが、Pythonはいうほど関係ありません。

Windows上でPythonを使ってPDFを印刷させる方法を探してみました。

今回は、外部のアプリケーションを呼び印刷させます。

追記:2015-07-03:
サンプルのコードは、python [filename] で出来るようになってます。一部違いますし、例外等何も入れてません。詳しくはコードを確認下さい。

Adobe Reader, Adobe Acrobatのコマンドラインを利用する

Acrobat および Adobe Reader のコマンドラインオプション

Adobe ReaderやAdobe Acrobatは、コマンドラインオプションがあります。別のプロセス(インスタンス)で起動したり、印刷をそのまま実行させたり出来ます。

ここでの例では、Adobe Acrobatを利用しています。(Acrobat.exe) Adobe Readerは AcroRd32.exe を利用します。インストール時のパスもバージョンによって異なります。デメリットはその判定が面倒なところかな?

参考: Print PDFs with Python? | GeoNet

Adobe Readerの印刷ダイアログを表示させてから印刷させる

https://gist.github.com/hrsano645/ddd5c111204338576404

# coding: utf-8
from __future__ import division, print_function, absolute_import, unicode_literals

import subprocess
import sys

# ref: https://geonet.esri.com/thread/59446
# ref: https://helpx.adobe.com/jp/acrobat/kb/510705.html

def main(pdffile):
    # acroread = r'C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe'
    acrobat = r'C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe'

    # '"%s"'is to wrap double quotes around paths
    # as subprocess will use list2cmdline internally if we pass it a list
    # which escapes double quotes and Adobe Reader doesn't like that

    cmd = '"{}" /P "{}"'.format(acrobat, pdffile)

    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    exit_code = proc.wait()


if __name__ == '__main__':
    pdffile = sys.argv[1]
    main(pdffile)

Adobe Acrobatの印刷ダイアログを表示させないで印刷させる(サイレントモード)

この方法では、プリンタ名が必要です。(ない場合のチェックはしていません。どなたかコメント下さい)

https://gist.github.com/hrsano645/a16c3f35deac04b2b4d9

# coding: utf-8
from __future__ import division, print_function, absolute_import, unicode_literals

import subprocess
import sys

# ref: https://geonet.esri.com/thread/59446
# ref: https://helpx.adobe.com/jp/acrobat/kb/510705.html


def main(pdffile, printer_name):
    # acroread = r'C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe'
    acrobat = r'C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe'

    # '"%s"'is to wrap double quotes around paths
    # as subprocess will use list2cmdline internally if we pass it a list
    # which escapes double quotes and Adobe Reader doesn't like that

    cmd = '"{}" /N /T "{}" "{}"'.format(acrobat, pdffile, printer_name)

    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    exit_code = proc.wait()


if __name__ == '__main__':
    pdffile = sys.argv[1]
    printer_name = sys.argv[2]
    main(pdffile, printer_name)

Pywin32:Win32API.ShellExecuteを利用する

Pywin32で利用できるWindows APIにある、ShellExecuteを利用します。

ShellExecute 関数

ShellExecuteを使うと、関連付けられたアプリケーションで開くopen, 印刷をするprintが使えます。

このスクリプトで動作すると思われますが、自分の環境では印刷できる時と出来ない時がありました。

参考:
- Tim Golden's Python Stuff: Print
- win32api.ShellExecute

https://gist.github.com/hrsano645/b69b071de4b8cb59cbe9

# coding: utf-8
from __future__ import division, print_function, absolute_import, unicode_literals

# ref: http://timgolden.me.uk/python/win32_how_do_i/print.html
# ref: http://docs.activestate.com/activepython/2.7/pywin32/win32api__ShellExecute_meth.html

import win32api
import sys


if __name__ == '__main__':
    pdf_file_name = sys.argv[1]
    win32api.ShellExecute(0, "print", pdf_file_name, None, ".", 0)

GSPrintを利用する

Ghostscriptを利用するGSPrint(GSViewに付属)というコマンドラインアプリケーションを利用して印刷します。

まずは、GhostscriptとGSViewをインストールします。(検証時に利用したものは、本家のバージョンですが日本語版も多分同じかと思います)

Ghostscript 9.16 and GSview 5.0 J (Official Site)

後は、subprocessモジュールを使ってコマンドを実行します。

-queryオプションを指定しない場合はそのまま印刷されます。

https://gist.github.com/hrsano645/fe73570d0d5d8df4863a

# coding: utf-8
from __future__ import division, print_function, absolute_import, unicode_literals

import subprocess
import sys


# ref: http://stackoverflow.com/questions/4498099/silent-printing-of-a-pdf-in-python
# ref: http://stackoverflow.com/questions/1462842/print-pdf-document-with-pythons-win32print-module

def main(pdffile):
    gsprint = r"C:\Program Files\Ghostgum\gsview\gsprint.exe"

    # -quertオプションでプリンタ一覧を呼び出す
    cmd = '"{}" -query "{}"'.format(gsprint, pdffile)

    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    exit_code = proc.wait()


if __name__ == '__main__':
    pdffile = sys.argv[1]
    main(pdffile)

大事なお知らせとして、印刷時の用紙サイズの設定が操作できないので、-queryで印刷ダイアログを出した上で、プリンタ側で拡大縮小の設定をするしかないらしいです。しかし利用しているPX-1700Fは拡大印刷しても何故かしてくれないです。これはプリンタ側の問題かな。

(あとで試したのですが、プリンタの用紙サイズとファイルの設定された用紙サイズが一致してれば綺麗に印刷してくれました。)

印刷時、色がモノクロだったので、GSPrint側で予め指定しないとダメかも。(詳しく検証してませんがオプションを見る限りだと設定必要かな)

参考:
- Ghostscript, Ghostview and GSview

(多分)続きます

この他にも、Pythonで利用できるGUIツールキットを使って行う方法もあるようです。wxpythonとpyqt(pyside)でそれらしいものを見つけましたが、まだ検証していません。検証できたら続きを書こうと思います。

その他にも、良い印刷方法を知っている方、いましたらぜひともコメントに記載していただけると助かります。

iotlt
IoT縛りの勉強会です。 毎月イベントを実施しているので是非遊びに来てください! 登壇者を中心にQiitaでも情報発信していきます。 https://iotlt.connpass.com
https://iotlt.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away