※タイトルに書いておきながらタイトルにも書いてありますが、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の印刷ダイアログを表示させてから印刷させる
# 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の印刷ダイアログを表示させないで印刷させる(サイレントモード)
この方法では、プリンタ名が必要です。(ない場合のチェックはしていません。どなたかコメント下さい)
# 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を使うと、関連付けられたアプリケーションで開くopen, 印刷をするprintが使えます。
このスクリプトで動作すると思われますが、自分の環境では印刷できる時と出来ない時がありました。
参考:
# 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オプションを指定しない場合はそのまま印刷されます。
# 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側で予め指定しないとダメかも。(詳しく検証してませんがオプションを見る限りだと設定必要かな)
参考:
(多分)続きます
この他にも、Pythonで利用できるGUIツールキットを使って行う方法もあるようです。wxpythonとpyqt(pyside)でそれらしいものを見つけましたが、まだ検証していません。検証できたら続きを書こうと思います。
その他にも、良い印刷方法を知っている方、いましたらぜひともコメントに記載していただけると助かります。