1
3

More than 1 year has passed since last update.

PADはPythonが使える人に助けてもらうと機能を追加出来て更に便利になるという実用的な使い方の紹介#2

Posted at

はじめに

今回の記事は、前回の記事の続きでもう少し汎用的に使えるようにしていきます。

先回のおさらい

Pythonが得意な方にお願いして、PythonでPDFを分割するpdfsplit.exeファイルを作成してもらい、PAD側でそれを呼び出して使うという方法を紹介しました。詳しくは、先回の記事をご覧いただけますと幸いです。

pdfsplit.exeの使い方

  1. pdffilesフォルダー直下のpdfsplit.exeと同じ階層に分割対象のPDFを保存する。
  2. PADでpdfsplit.exeを実行する。
  3. pdffilesフォルダーに分割されたPDFが連番付きで保存され、元のPDFファイルは削除される。

今回の記事でやりたい事

先回はPDF分割機能を1つだけPADに追加しましたが、今回はPAD側で3つのPDF関連の機能を追加して外部関数のように使う方法を紹介します。追加する機能は、以下の3つです。今回もPythonが得意な方に頼る前提となります。

  1. PDFのページ数取得
  2. PDFを単一ページのPDFへ連番付きで分割
  3. PDF全ページに透かし追加

Pythonが得意な人に頼む事

今回もPythonが得意な人に、複数の機能を持つpdffunctions.exeを作成して貰います。コードは以下を参考になさって下さい。

pdffunctions.rb
from pathlib import Path
from PyPDF2 import PdfReader,PdfWriter
import pyperclip

def main():
    padinput = pyperclip.paste().split(',')

    if padinput[0] == 'getpagenumbers':
        pagenumber = getpagenumbers(padinput[1])
        pyperclip.copy(pagenumber)
    
    elif padinput[0] == 'pdfsplit':
        splitpdf(padinput[1])
    
    elif padinput[0] == 'addwatermark':
        addwatermark(padinput[1],padinput[2],padinput[3])

def getpagenumbers(content_pdf: str):    
    reader = PdfReader(content_pdf)
    return len(reader.pages)

def splitpdf(content_pdf: str):
    reader = PdfReader(content_pdf)
    for i in range(len(reader.pages)):
        page=reader.pages[i] 
        writer=PdfWriter() 
        writer.add_page(page) 
        filename=str(Path(content_pdf).stem) + str(i+1) + '.pdf'
        newfilepath=Path.cwd()/filename
        with open(newfilepath,mode='wb') as f:
            writer.write(f)    

def addwatermark(
    content_pdf: str,
    stamp_pdf: str,
    pdf_result: str,
):
    reader = PdfReader(content_pdf)
    writer = PdfWriter()
    for index in range(len(reader.pages)):
        content_page = reader.pages[index]
        mediabox = content_page.mediabox

        reader_stamp = PdfReader(stamp_pdf)
        image_page = reader_stamp.pages[0]

        image_page.merge_page(content_page)
        image_page.mediabox = mediabox
        writer.add_page(image_page)

    with open(pdf_result, "wb") as fp:
        writer.write(fp)

if __name__ == '__main__':
    main()

Pythonのexe化は今回もcx_Freezeを使用しています。setup.pyも参考で載せておきます。

pdffunctions.rb
from cx_Freeze import setup, Executable

excludes = ['PyQt4','PyQt5','tkinter']

base = None

setup(
    name='pdffunctions',
    version='1.0',
    description='PDF functions for PAD',
    options={'build_exe':{'excludes':excludes}},
    executables=[Executable('pdffunctions.py', base=base)]
)

コードの解説

簡単にpdffunctions.pyの内容を説明します。

各関数の説明

ここでは、4つの関数を作成しています。

  1. main():クリップボードの値(PADからの入力)をリスト形式で取得し、リストの最初の値に応じてgetpagenumbers(), splitpdf(), addwatermark()のいずれかの関数を実行。
  2. getpagenumbers():PDFのページ数を取得する関数。PDFのページ数は、クリップボードにコピーされる。
  3. splitpdf():PDFを単一ページののPDFへ連番付きで分割する関数。分割されたPDFは、分割対象と同じフォルダーに保存される。元のファイルはそのまま残す。
  4. addwatermark():PDF全ページに透かしを追加する関数。透かしのみを入れたPDFファイルを透かしを入れる対象PDFと同一フォルダーに保存。watermarkは、透かしという意味です。

※addwatermark()関数は、PyPDF2の公式ドキュメントに掲載されているwatermark()関数をほぼそのまま使用しています。

PADとの入出力

PADとPythonでデータの入出力は、クリップボードを介して行います。このため、PythonではPyperclipを使用しています。Pyperclipについては、以下を参照ください。

PADからカンマ区切りで①関数名, ②操作対象のPDFファイルの絶対パス, ③透かし画像のPDFファイルの絶対パス, ④透かしを入れた後のPDFの絶対パスをPythonに渡します。ここで、3番目と4番目の文字列はaddwatermark()関数の時のみ必要になります。

PADでPythonとの入出力で使用するアクションは、以下の2つです。

  1. クリップボードテキストを取得
  2. クリップボードテキストを設定

pdffunctions.exeの使い方

cx_Freezeでexe化が完了すると、exe.win-amd64-3.xのようなフォルダーが作成されます。この中に、画像のようなpdfsplit.exeファイルと関連ファイルが保存されています。このフォルダーをご使用のPCに保存します(配布して貰います)。今回は、フォルダー名をexe.win-amd64-3.x→pdffunctionsと変更しました。使い方と動作は非常にシンプルです。
pdffunctions最初.PNG

  1. pdffunctionsフォルダー直下のpdffunctions.exeと同じ階層に、分割対象のPDFと透かしが保存されたwatermark.pdfを置く(addwatermark()関数を使用しないのであれば、watermark.pdfは必要ありません)。
  2. PADでpdfsplit.exeを実行する。この時、リスト形式で必要な情報を渡し、使用する関数を選択する。
  3. 選択した関数に応じて、以下のように動作する。
    getpagenumber()関数: 対象PDFのページ数をクリップボードにコピーし、メッセージボックスにページ数を表示。
    pdfsplit()関数: pdffunctionssフォルダーに分割されたPDFが連番付きで保存され、元のPDFファイルはそのまま残る。処理の完了を知らせるメッセージボックスを表示。
    addwatermark()関数: 指定した絶対パスに透かしが追加されたPDFが保存される。処理の完了を知らせるメッセージボックスを表示。

PAD側の操作

準備

pdffunctionsフォルダーに操作対象のPDF(世界一やさしいPython RPA_抜粋.pdf)と透かしが入ったPDFファイル(watermark.pdf)を保存します。

pdffunctionsフォルダー.PNG

世界一やさしいPython RPA_抜粋.pdfは、7ページあります。
watermark.pdfは、以下の通り透かしの画像を保存しています。
watermarkファイル.PNG

PADの全体フローと各フローの説明

PADの全体フローは、。エラー処理等は含んでいませんので16行とシンプルです。画像で示すように4つのブロックに分けて説明します。
フロー全体.PNG

①変数の設定

ここでは、1行目〜4行目で4つの変数を設定します。使う変数は、functionname、pdfpath、watermarkpath、resultpathです。それぞれの変数の説明は、以下の通りです。

1行目

functionname:関数名を格納
今回は、addwatermark()関数を選択するので、addwatermarkを値としています。PDFのページ数を取得したい場合は、getpagenumbers、PDFを分割したい場合はpdfsplitを値として設定します。
変数の設定1.PNG

2行目

pdfpath: 操作対象のPDFファイルの絶対パスを格納
変数の設定2.PNG

3行目

watermarkpath:透かし画像のPDFファイルの絶対パスを格納
変数の設定3.PNG

4行目

resultpath:透かしを入れた後のPDFの絶対パスを格納
透かしを入れた後のPDFは、pdffunctionsフォルダー内にresult.pdfという名前で保存します。
変数の設定4.PNG

②Pythonへの入力準備

PAD→Pythonへ情報をそのまま渡すためのアクションがありませんので、クリップボードテキストを設定のアクションを使用します。1行目〜4行目で設定した変数をカンマで区切ってクリップボードへコピーします。Pythonのプログラム内でカンマ区切りの入力をリスト形式に変換しています。
クリップボードの設定.PNG

③Pythonの関数実行

Pythonの関数を「アプリケーションの実行」のアクションで実行します。「アプリケーションパス:」には、pdffunctions.exeの絶対パスを指定します。「作業フォルダー:」は、pdffunctionsフォルダーを指定します。10行目で「wait」アクションを使って、Pythonのプログラムが実行完了するまでの間の2秒待機させます。今回は、2秒にしていますがPDFのページ数が多い場合にはもう少し時間がかかるかもしれません。
アプリケーションの実行設定.PNG

④実行結果の表示

「Switch - Case」アクションで 変数functionnameの値によって、アクションを変えます。

9行目〜11行目:

pagenumbersが選択された場合のアクションです。Pythonのプログラムを実行すると、指定したPDFのページ数がクリップボードに保存されますので、10行目で「クリップボードテキストを取得」アクションで変数ClipboardTextにページ数を格納します。

クリップボードテキストを取得設定.PNG
「メッセージを表示」アクションで、取得したページ数をメッセージボックスで表示させるようにします。
クリップボードテキストのメッセージを表示設定.PNG

12行目〜13行目:

pdfsplitが選択された場合のアクションです。Pythonのプログラムを実行すると、操作対応のPDFが同じフォルダー内に1ページ毎に連番付きで分割保存されます。13行目の「メッセージを表示」アクションで、PDF分割が完了したことを知らせるメッセージボックスを表示させます。

pdfsplitメッセージ表示の設定.PNG

14行目〜15行目:

addwatermarkが選択された場合のアクションです。Pythonのプログラムを実行すると、操作対応のPDFにwatermark.pdfの透かしが追加され、result.pdfとして保存されます。15行目の「メッセージを表示」アクションで、透かしの追加処理が完了したことを知らせるメッセージボックスを表示させます。
addwatermarkのメッセージ表示設定.PNG

PADの実行結果

それぞれの関数を実行した結果と全ての関数を実行した後のpdffunctionsフォルダーを示します。

pagenumbers関数を実行した結果

以下のメッセージが表示されます。
getpagenumbersの実行結果1.PNG

pdfsplit関数を実行した結果

以下のメッセージが表示されます。
splitpdfの実行結果1.PNG

addwatermark関数を実行した結果

以下のメッセージが表示されます。
addwatermarkの実行結果1.PNG
result.pdfは、以下のように透かしが追加されます。
addwatermarkの実行結果2.PNG

全ての関数を実行した後のpdffunctionsフォルダー

addwatermark()関数、getpagenumbers()関数、pdfsplit()関数の全てを実行した後は、pdffunctionsフォルダーは以下のようになります。
全ての実行結果.PNG

おわりに

今回はPDF関連の機能を1まとめにして、PADから外部関数のように使う方法を紹介させていただきました。
Pythonで実装できる機能は多岐に渡ります。たとえば、データの揺れを一括で修正するデータクレンジングの機能をython x Pandasで作成する等の使い方もあるかと思います。PADで見つからないアクションがあればPythonが得意な人に相談してみて下さい。そして、今回のようにPADに機能を追加して更に便利に使いこなしましょう。

この記事がどなたかのお役に立てれば幸いです。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3