PR

PythonでExcel請求書を自動PDF化するツールの作り方|openpyxl・pywin32・CustomTkinter【全3回まとめ】

Python

Python業務自動化 Invoice Maker 総集編

スポンサーリンク

PythonでExcel請求書を自動PDF化するツールの作り方|openpyxl・pywin32・CustomTkinter【全3回まとめ】

こんにちは、VBA・Python業務自動化ラボ(py-vbalab.com)のニンジンです🥕

全3回でお届けした「Invoice Maker」制作シリーズが完結しました。この記事は、3回分の内容をダイジェストでおさらいしながら、受注一覧のExcelから請求書を1枚ずつ自動でPDF化するツールを、どう組み立てたかを一気に確認できる総集編です。

毎月末、受注一覧から会社名や金額をコピーして請求書テンプレに貼り付け、1枚ずつPDF保存する——この作業は件数が増えるほど手作業では回らなくなり、コピペミスのリスクも高まります。openpyxl(Excel読み取り)・pywin32(Excelを裏で操作してPDF化)・CustomTkinter(操作画面)の3つで、これをクリック1つに置き換えます。

この記事で分かること

  • openpyxl でExcelの値を読み取るときの data_only=True の役割
  • pywin32 でExcelを操作してPDF保存する流れと、temp.xlsx を経由する理由
  • for 文で複数件を一括PDF化するときの try...finally によるゴーストプロセス対策
  • CustomTkinter と filedialog、class 設計でGUIアプリに仕上げる考え方
  • 各回で「ハマりやすいポイント」と、実務で使うための注意点(FAQ 15問)

シリーズ全記事


スポンサーリンク

【第1回】Excelデータの読み取りとPDF変換の基本ロジック

第1回の解説記事のサムネイル。openpyxlとpywin32で1枚の請求書をPDF化する

最初のステップは、基盤となる「1枚のExcelデータを取得し、レイアウトを保持したままPDFへ変換する」プログラムです。受注管理表の指定セルから会社名・金額などを読み取り、請求書テンプレートに書き込んでPDF保存します。

詳細解説:PythonでExcelをPDFに変換する方法|openpyxlとpywin32で請求書を自動作成【第1回】 >

仕様上の注意点と対策

data_only=True の指定

通常の読み込みでは、合計セルから =SUM(H2:H3) のような数式の文字列がそのまま取得されます。load_workbook(path, data_only=True) とすることで、Excelが計算した後の数値結果を取得できます。読み取りには必ず付けます。

一時ファイル(temp.xlsx)の経由

openpyxl 単体ではPDF出力ができません。そのため「データを書き込んだ temp.xlsx をいったん保存 → pywin32(COM)でExcel本体を操作してPDF保存 → temp.xlsx を削除」という処理フローを採用しています。元テンプレートのレイアウトを崩さずにPDF化できるのが利点です。

スポンサーリンク

【第2回】for文による連続一括PDF化とエラーハンドリング

第2回の解説記事のサムネイル。for文で複数件の請求書を一括PDF化する

1枚の処理ロジックを、複数データの連続処理へ拡張します。for 文による繰り返しに加え、実務運用で必須となる例外処理を組み込みます。

詳細解説:【第2回】Pythonのfor文でExcelデータを連続PDF化!重複回避とエラー対策(例外処理)のやり方 >

実務運用に耐えうるコード設計

⚠️ Excelの未終了プロセス(ゴーストプロセス)の防止
PythonでバックグラウンドのExcelを操作中にエラーが起きると、タスクマネージャー上でExcelプロセスが起動したまま残ります。これが累積するとPCのリソースを圧迫します。

対策として、コード内に try...finally ブロックを導入します。メイン処理で予期せぬエラーが発生しても、finally: excel.Quit() が確実に呼ばれ、バックグラウンドのExcelを安全にクローズできます。エラー発生前に作成済みのPDFはそのまま残り、エラー行番号はターミナルに表示されます。

スポンサーリンク

【第3回】CustomTkinterによるGUI操作画面の実装

第3回で完成したInvoice MakerのGUI画面。ファイル選択ボタンと開始行・終了行の入力欄がある

自動化ロジックの完成後、非エンジニアの担当者でもソースコードに触れず使えるよう、操作画面(GUI)を開発します。現場で「for i in range(15, 50): を書き換えてください」と頼むのは非現実的だからです。

詳細解説:CustomTkinterでPythonツールをGUIアプリ化する方法|filedialogでファイル選択・クラスで設計【第3回】 >

操作性向上とアプリケーション設計のポイント

filedialog によるファイルパス取得

パスの手入力を排除し、Windows標準の「ファイルを開く」ダイアログからExcelを視覚的に選択させることで、入力ミスを防ぎます。

.get() による実行範囲の制御

画面の入力欄(Entry)から「開始行」「終了行」を .get() で動的に取得。ソースコードを書き換えずに対象範囲を変更できます。

class を用いた構造化

画面部品の管理と自動化ロジックの連携が煩雑にならないよう、class InvoiceApp(ctk.CTk): によるオブジェクト指向設計を導入し、保守性を高めています。


スポンサーリンク

よくある質問(FAQ)

環境・準備について

QWindowsとMacどちらでも動きますか?

A

Windowsのみ対応しています。PDF化に使う pywin32 が、WindowsのExcelを裏側から直接操作する仕組みのためです。MacやLinuxでは動作しません。

Macで同様の処理をしたい場合は、PDF化の部分を reportlab や pdfkit など別のライブラリに置き換える必要があります。

QPythonはどのバージョンを使えばいいですか?

A

Python 3.8以上を推奨します。第3回で使うCustomTkinterの推奨環境が3.8以上のためです。python --version でインストール済みのバージョンを確認できます。

QExcelはどのバージョンが必要ですか?

A

Microsoft Excel(有償版)がインストールされている必要があります。PDF化でExcel本体を裏側から起動しているためです。GoogleスプレッドシートやLibreOfficeでは代替できません。

Qpip install でエラーが出ます。どうすればいいですか?

A

よくある原因は3つです。

  • Pythonが正しく入っていない:python --version でバージョンが表示されるか確認
  • pipが古い:python -m pip install --upgrade pip で更新してから再試行
  • 社内ネットワークの制限:セキュリティ設定で接続が制限されている場合があります。IT担当者に確認を

コード・処理の内容について

Qdata_only=True を付け忘れるとどうなりますか?

A

計算式の文字列がそのまま取得されます。合計金額のセルに =SUM(H2:H3) が入っていると、数値ではなくこの式の文字列が請求書に転記されてしまいます。読み取りには必ず data_only=True を指定します。

Qなぜ一時ファイル(temp.xlsx)を経由する必要があるのですか?

A

openpyxlにPDF書き出しの機能がないためです。流れは次のとおりです。

  • openpyxlでデータを書き込み、temp.xlsx として保存
  • 裏側でExcelを起動して temp.xlsx を開き、PDF形式で保存
  • 用済みの temp.xlsx を os.remove() で削除

この手順で、元テンプレートのレイアウトを崩さずPDF化できます。

Q特定の行だけを処理することはできますか?

A

はい、range() の数値を変えるだけです。「4行目から10行目まで」なら range(4, 11)、「20行目から25行目まで」なら range(20, 26) です。第3回のGUIアプリなら、この開始行・終了行を画面から変更できます。

Q会社名にスラッシュなど使えない文字が含まれている場合はどうなりますか?

A

エラーが発生して処理が止まります。Windowsではファイル名に / \\ : * ? " < > | が使えません。会社名を取得した後に str.replace() や re.sub() で使用不可の文字を除去する処理を入れておくのがおすすめです。

Q途中でエラーが出た場合、それ以前に作成したPDFは残りますか?

A

はい、エラー発生前に完了したPDFはそのまま残ります。第2回で解説した try...finally により、エラーが起きてもExcelプロセスは確実に終了します。エラー行番号はターミナルに出るので、その行を確認して再実行できます。

GUIアプリ(第3回)について

QCustomTkinterと通常のTkinterはどう違うのですか?

A

主に見た目が異なります。通常のTkinterは古いWindowsアプリ風、CustomTkinterはフラットでモダンな見た目です。

項目Tkinter(標準)CustomTkinter
デザイン古いWindowsアプリ風フラットでモダン
ダークモード非対応対応
インストールPython標準搭載pip installが必要
書き方—ほぼ同じ(移行しやすい)

QGUIアプリを他のPCで動かすにはどうすればいいですか?

A

PyInstallerで .exe ファイル化するのが現実的です。そのままでは相手のPCにもPythonと各ライブラリが必要になります。PyInstallerで実行ファイル化すれば、Pythonが入っていないPCでもダブルクリックで起動できます。

QGUIの入力欄に数字以外を入れるとエラーになりますか?

A

はい、基本のコードではエラーになります。入力値を int() で数値変換する際に文字列が渡されるためです。実務では try...except ValueError で「数字以外なら警告を出す」処理を足しておくと安心です。

運用・実務について

Q受注管理表のフォーマットを変えた場合、コードも修正が必要ですか?

A

はい、セルの位置が変わった場合は修正が必要です。コード内の ws_kanri["C4"] のような記述が参照セルを指定しています。列や行の位置を変えたら、その箇所を対応するセル番地に書き換えてください。

Q月ごとに出力先フォルダを分けることはできますか?

A

はい、os と datetime の組み合わせで対応できます。処理の冒頭で年月を取得してフォルダ名に使い、os.makedirs() と組み合わせればフォルダが無い場合も自動作成されます。例:datetime.now().strftime("請求書_%Y%m") → 「請求書_202507」。

Q処理件数が多いとパソコンが重くなりますか?

A

処理時間は件数に比例しますが、Excelプロセスが溜まるトラブルは防げます。1件あたり数秒が目安です(PCスペックやファイルの複雑さで変動)。第2回の try...finally を正しく実装すれば、エラー時にExcelプロセスが残ってPCが重くなる現象を防げます。

スポンサーリンク

まとめ:3回でたどった自動化の道のり

本シリーズでは、次のステップでExcel請求書の自動化ツールを作り上げました。

📄
1枚をPDF化
第1回
→
🔁
大量を一括PDF化
第2回
→
🖥️
GUIアプリ化
第3回

これで「クリック一つで大量の請求書を発行できるツール」という当初の目標は達成できました。ただ、このツールを他のパソコンで動かすには「Pythonとライブラリのインストール」という壁が残ります。

PYTHON環境構築 不要・実行ファイル化済み

Invoice Maker (NINJIN EDITION)

「自分で環境を作るのは大変」「社内のPCにそのまま展開したい」という方には、ダブルクリックで起動できる実行ファイル(.exe)の完全版パッケージを用意しています。

noteで詳しく見る →

各回の詳細記事

最後までお読みいただき、ありがとうございました。py-vbalab.com では、これからも業務を楽にするVBA&Pythonの技術を発信していきます🥕


ニンジン🥕アイコン

Follow me on X

本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕

@ninjin_py_vba をフォロー

この記事が役に立ったら、シェアしてもらえると嬉しいです🥕

Xでポスト はてブ LINE Pocket

PROJECT LOG — SERIES INDEX
スポンサーリンク

シリーズ記事一覧

電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。


GPSロガーのCSVを地図に表示する方法|Pico 2 WでGT-502MGG-NとATGM336Hを車に積んで走行・トンネル比較【Python・folium】
GPSロガーで記録したCSVを、Pythonのfoliumと地理院タイルで地図に表示する方法。GT-502MGG-NとATGM336Hを車に積んで4回走り、再起動の原因やトンネルでの違いも比べました。
今週の注目ガジェット〜10/19週〜|電子工作・自作向け新製品まとめ(Romu/W1700K SDR ほか)
大手が拾わないニッチな新製品を毎週チェック。今週はe-Paper開発キット、超小型USBボード、自作SDRなど5本立て。
GT-502MGG-NとATGM336Hの使い方|Raspberry Pi Pico 2 WとMicroPythonでGPSを受信して2台を比較
GT-502MGG-NとATGM336Hの使い方を、Pico 2 W×MicroPythonで解説。北斗で衛星数が多いATGM336H、信号が強いGT-502MGG-N。単精度floatで緯度経度が約1.4m刻みになる落とし穴も紹介します。
今週の注目ガジェット〜10/12週〜|電子工作・自作向け新製品まとめ(Q8botOne/Sipeed SLogic32U3 ほか)
大手が拾わないニッチな新製品を毎週チェック。今週は四足歩行ロボット、ロジックアナライザー、広告ブロッカーなど5本立て。
MOSFETはPicoの3.3Vで足りる?DCソレノイド駆動でゲート電圧不足を実測【Pico 2 W】
Pico 2 WとMOSFET(IRLU3410)で12VのDCソレノイドを駆動。ゲート3.3Vでは発振し、オン抵抗も約2.4倍に。レベル変換で5V駆動にした比較と、電流が8割止まりだった本当の原因を実測で紹介します。

まとめハブ
Python
スポンサーリンク

コメント