ペーパーレス化の時代が来ているにも関わらず、未だ印刷することが多々ある企業をよく耳にします。メールあるのにまだFAXが現役な企業もあるくらいですからね・・・
今回はPDFを印刷することを行います。Adobe Acrobat Readerが入っていることが前提です。
RPA的にはこの普段のGUI操作をいかに自動化するかが肝になりそうなので今回紹介します。
1. Acrobat Reader exeのパスを取得する
自分の環境(Windows10 Pro 64bit)では、C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe に入っていました。これを使います。
2. コマンドで印刷
Acrobat Readerにはコマンドで印刷できます。ただ、印刷するPDFファイル名が日本語だとうまくいかなかったので、PDFファイル名はあらかじめ半角英数字にしておくと安全です。
プリンタ名も、Windowsの設定でプリンタの名前を変更できるので半角英数字にしておきます。
Runコマンドで実行、終わるのを待つのはProcessWaitClose()で。
$ACROEXE = "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" $pdfpath = "C:\test.pdf" $printername = "printername" Local $pid = Run( $ACROEXE & " /t " & $pdfpath & " " & $printername ) ;Acrobatは見た目消えても走っているようなので、ProcessWaitCloseを使う Local $ret = ProcessWaitClose($pid, 30) If @error Then EndIf
3. 普通に開いて印刷ダイアログで印刷
GUIが絡むと一気に面倒になります。AutoItの通常のGUI制御では印刷ダイアログのプリンタを選べない(うまくプリンタ名を取得できない)からです。
通常使うプリンタで印刷する場合は関係ないですが、その都度プリンタを変更する場合はプリンタ選択を画像認識で文字列認識するとかしないと厳しいです。

3.1 Acrobat Reader DCの印刷ダイアログでプリンタを選ぶには(余談)
筆者はtesseract-ocrを使って、コントロールのスクリーンショットをocrし、StringInStr()でプリンタ名探してやっています。これは長くなるし、tesseract-ocrをPCに入れないとダメになるので現実的ではありませんね。
3.2 AcrobatにPDFファイルを渡して開き、Altショートカットなどで印刷
流れは以下のようにしました。PDFのページ数が多いとAcrobatを閉じれないなどありますので、印刷プログレスダイアログも監視したほうがいいかもです。もしくは待ち時間Sleep()を長く取るとか。
- Acrobat ReaderでPDFファイルを開く Run()
- そのファイルが開かれるまで待つ WinWaitActive()
- Alt+fpでメニューの「ファイル->印刷」Send(“!fp”)
- 印刷ダイアログが出るのを待つ WinWaitActive(“印刷”,””,60)
- –(option) プリンタを選択(tesseract-ocrかUIAutomation必要)
- 「印刷ボタン」をクリック ControlClick()
- –(option)印刷プログレスを監視
- 印刷ダイアログが閉じるのを待つ(PDFファイルによって長さマチマチ) Sleep()
- PDFファイルを閉じる WinClose()
- Acrobat Reader Exeを閉じる WinClose()
Global $acroname = "Adobe Acrobat Reader DC" Local $acroexe = "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" Local $basedir = @ScriptDir Local $filename = "201910健康診断.pdf" $ret = _print_pdf($acroexe, $basedir, $filename) ;--------- ; PDFファイルを印刷する ;--------- Func _print_pdf($exepath, $basedir, $filename) Local $pid = Run($exepath & ' "' & $basedir & "\" & $filename & '"') If @error Then Return SetError(1,0, "err: couldnt open pdf") EndIf ;ウィンドウがアクティブになるのを待つ Local $hwn = WinWaitActive($filename,"",60) If $hwn = 0 Then Return SetError(1,0, "err: window isnt active") EndIf Sleep(1000) ; Alt + fp ショートカットでメニュー「ファイル->印刷」 Send("!fp") $hwn = WinWaitActive("印刷","",60) If $hwn = 0 Then ConsoleWrite("warning: print dialog isnt shown") Else Sleep(1000) ; プリンタ選択(option) ;Local $ret = _sel_printer("プリンタ名") ; 印刷する Au3Info.exeで印刷ボタンコントロールクラスを取得した Local $ret = ControlClick("印刷", "", "[CLASS:Button; INSTANCE:50]") $hwn = WinWaitActive($filename, "", 60) ; ここで印刷が終わるまで待ちたいがPDFファイルによってマチマチ Sleep(30000) ;30秒 EndIf ; PDFファイルを閉じる WinClose($filename) Sleep(3000) WinClose($acroname) Return SetError(0,0, "finish print pdf") EndFunc
サンプルコードをgithubに置いています。同じ階層に適当なpdfを置き、5行目の$filenameを変更してください。
3.2.1 GUIでやるメリットは印刷スケールや縦横など自由に設定できるところ
GUIは本当に面倒なのでコマンドでやりたかったのですが、PDFの印刷スケールを変更(窓付き封筒に合わせる為)が必要になりGUIでのやり方を調べました。
時間あればtesseract-ocrではなく、UIAutomationを使って出来るか調べてみます(これが出来ると余計なライブラリなどインストールする必要がなくなる)
4. Au3Info.exeでコントロールの情報を取得する
印刷ダイアログの「印刷ボタン」などのコントロールはAu3Info.exeを使ってクラス名などを取得しましょう。 C:Program Files (x86)\AutoIt3\Au3Info_x64.exeを開きます。
[CLASS:Button; INSTANCE:50] となります。

その他、ラジオボタン、プリンターコンボボックスも取得できるので見てみましょう。
コメント