PR

【第1回】Excel手作業の限界突破!Pythonで請求書を自動PDF化する第一歩

スポンサーリンク
Python
スポンサーリンク

はじめに

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

毎月末、こんな作業に時間を奪われていませんか? 「受注一覧のExcelから、会社名や金額をコピーして……請求書の雛形に貼り付けて……PDF形式で名前を付けて保存する」

数件ならまだしも、これが数十件、数百件となると完全に苦行です。コピペミスによる請求書の作り直しなど、ヒューマンエラーのリスクも跳ね上がります。

VBAを使って自動化することももちろん可能ですが、今回はよりモダンで拡張性の高いPythonを使って、この退屈な作業を一瞬で終わらせるツールを作っていきます。

本シリーズ(全3回)を通して、最終的には「誰でもクリック一つで大量の請求書を発行できる専用アプリ(GUIツール)」を完成させます。第1回となる今回は、自動化の心臓部となる**「1枚の請求書をPythonで自動作成し、PDF化する基本ロジック」**を解説します。

【PR:今すぐ完成版ツールを使いたい方へ】

「Pythonの環境構築とか面倒くさい!」 「コードを書かずに、今すぐ自社の業務で使える完成品が欲しい!」

という方に向けて、本シリーズで作成するツールの完成版(面倒な設定不要のフルパッケージ)である**【Invoice Maker (NINJIN EDITION)】**をnoteにて先行公開しています。
👉 Invoice Maker (NINJIN EDITION) をnoteでチェックする

準備1:openpyxl と pywin32 のインストール

今回、Excelの読み書きとPDF化を行うために、2つの強力なライブラリを使用します。
コマンドプロンプト(またはターミナル)で以下のコマンドを実行し、インストールしておきましょう。

pip install openpyxl

openpyxl: Excelファイル(.xlsx)のデータを読み書きするための定番ライブラリ。

pip install pywin32

pywin32: PythonからWindowsのアプリケーション(今回はExcel本体)を裏側で直接操作するためのライブラリ。

準備2:テストに必要なExcelファイルを準備

お手持ちの管理表と書類フォーマットを準備いただくか、下記のサンプルをご使用下さい。

ベースとなるPythonコード

さっそくですが、今回作成した「1枚の請求書を自動作成する」Pythonスクリプトの全貌です。
「受注管理表」の4行目にあるデータを読み取り、「請求書の雛形」の所定のセルに書き込んでPDF化します。

同一フォルダ内に必要なファイルを格納します

  • テストコード(本記事のコード)
  • 受注管理表(Excel)
  • 請求書(Excel)

下記のPythonコードをVS CODE等のテキストエディターにコピー&ペーストして実行して下さい。

# invoice_maker_test01.py
# 受注管理表のExcelファイルからデータを読み込み、請求書の雛形となるExcelファイルに書き込んでPDF化するサンプルコード
# 基本的なコードで、1行目のデータを処理するだけの例です

import openpyxl #Excelファイルを操作するためのライブラリopenpyxlをインポート
import win32com.client #WindowsのCOMオブジェクトを操作するためのライブラリwin32com.clientをインポート
import os #ファイルやパスを操作するための標準ライブラリosをインポート

# 1. 設定
KANRI_PATH = "受注管理表_Sample.xlsx" #変数KANRI_PATHに受注管理表のExcelファイルのパスを指定
HINAGATA_PATH = "請求書_Sample.xlsx" #変数HINAGATA_PATHに請求書の雛形となるExcelファイルのパスを指定
OUTPUT_PATH = os.path.abspath("請求書_出力.pdf") #変数OUTPUT_PATHに出力するPDFファイルのパスを指定。abspathで絶対パスを取得

# 2. データの読み込み openpyxlを使用してExcelファイルを読み込み
wb_kanri = openpyxl.load_workbook(KANRI_PATH, data_only=True) #data_only=Trueで数式の結果を値で取得
ws_kanri = wb_kanri["Sheet1"] # シート名を指定してシートを取得
company_name = ws_kanri["C4"].value # 会社名 KANRI_PATHのC列4行目を取得
amount = ws_kanri["H4"].value # 金額 KANRI_PATHのH列4行目を取得
count = ws_kanri["G4"].value # 数量 KANRI_PATHのG列4行目を取得
s_name = ws_kanri["F4"].value # 商品名 KANRI_PATHのF列4行目を取得

# 3. 雛形へ書き込み opnepyxlを使用して請求書の雛形となるExcelファイルにデータを書き込み
wb_hina = openpyxl.load_workbook(HINAGATA_PATH) #雛形のExcelファイルを読み込み
ws_hina = wb_hina["Sheet1"] # シート名を指定してシートを取得
ws_hina["A5"] = company_name #HINAGATA_PATHのA列5行目に会社名を書き込み
ws_hina["B18"] = s_name #HINAGATA_PATHのB列18行目に商品名を書き込み
ws_hina["L18"] = amount #HINAGATA_PATHのL列18行目に金額を書き込み
ws_hina["J18"] = count #HINAGATA_PATHのJ列18行目に数量を書き込み

# 4.雛形への書き込みが完了したら、一時的なExcelファイルとして保存する必要があるため、以下のコードで保存します。
temp_excel = os.path.abspath("temp.xlsx") #abspathで絶対パス(temp.xlsxという名前で)を取得
wb_hina.save(temp_excel) #保存してからPDF化する必要があるため、一時的なExcelファイルを保存

# 5. PDF化 (pywin32を使用)
excel = win32com.client.Dispatch("Excel.Application") #DispatchでExcelアプリケーションを起動
excel.Visible = False #Excelのウィンドウを表示しないように設定
try: #エラー発生時もExcelを確実に終了させるためにtryブロックを使用
doc = excel.Workbooks.Open(temp_excel) #Openで先ほど保存した一時的なExcelファイル(temp.xlsx)を開く
doc.RefreshAll() #Excelのデータを更新(数式がある場合に必要)
doc.ExportAsFixedFormat(0, OUTPUT_PATH) #ExportAsFixedFormatでPDF形式で保存。第1引数は0でPDF、第2引数は保存先のパス
doc.Close(False) #Closeでtemp.xlsxを閉じる。引数は変更を保存するかどうか(Falseで保存しない)
except Exception as e:
print(f"エラーが発生しました: {e}")
finally: #必ずExcelを終了させるためのfinallyブロック
excel.Quit() #QuitでExcelアプリケーションを終了

if os.path.exists(temp_excel): #念のため、一時的なExcelファイルが存在するかチェックしてから削除
os.remove(temp_excel) #一時的なExcelファイルを削除

print(f"作成完了: {OUTPUT_PATH}") #ターミナルに作成完了のメッセージを表示
テスト結果

VS Codeのターミナルに
「作成完了:D:\請求書_出力.pdf」と表示されれば成功です。

Pythonコードと同一フォルダ内にPDFデータが出来ていると思います。

ここがポイント!初心者がハマりやすい2つの罠

一見シンプルなコードですが、実務で使う上で絶対に知っておくべき「工夫」が2つ隠されています。

data_only=True の魔法

Excelデータを読み込む際、ただ load_workbook を使うと、金額などの計算式が入ったセルは "=SUM(H2:H3)" のような文字列の数式として取得されてしまいます。これでは別のExcelに転記した際におかしくなってしまいます。

そこで data_only=True を指定することで、Excelが計算したあとの**「結果の値(数値)」**だけをクリーンに抜き出すことができます。データ分析や自動化の前処理において必須のテクニックです。

② 一度「一時ファイル(temp.xlsx)」として保存する理由

openpyxl は非常に高速でExcelを編集できますが、「PDFとして書き出す」機能を持っていません。PDF化は、パソコンに入っている「本物のExcel」にやってもらう必要があります(これが win32com の役割です)。

そのため、

  • openpyxl でデータを書き込んだ後、一度 temp.xlsx という仮の名前で保存する。
  • 裏側でExcelアプリを起動し、その temp.xlsx を開いてPDFとして「名前を付けて保存」させる。
  • 最後に用済みの temp.xlsx をゴミ箱に捨てる(os.remove)。

という、忍者のようなスマートな処理を行っています。これにより、元の美しい雛形のレイアウトを一切崩すことなく、完璧なPDFが生成されるのです。

スポンサーリンク

まとめ:1枚できれば、100枚できるのがプログラム

いかがだったでしょうか? たった数十行のコードを実行するだけで、指定したフォルダに見事なPDFの請求書が出現したはずです。手作業によるコピペの呪縛から解放された瞬間です。

しかし、感の良い方ならこう思うはずです。 「コードの『C4』とか『H4』を直接指定してるけど、100社分あったらどうするの?」

その通りです。今のままでは1枚しか作れません。 そこで次回は、Pythonの真骨頂である**「ループ(繰り返し)処理」**を組み込み、フォルダ内に100枚の請求書を一瞬でバラ撒く怒涛の自動化スクリプトへと進化させます。途中でエラーが起きても止まらない、プロ仕様の書き方も伝授しますのでお楽しみに!

【次回の記事はこちら】
【第2回】もう手作業には戻れない。大量のデータを一気にPDF化する「ループ処理」の魔法

💡 業務ですぐにツールを使いたい方へ

「次回の解説まで待てない」「自分でコードを組む時間がない」という方は、noteにて完成版のGUIアプリ【Invoice Maker (NINJIN EDITION)】を頒布中です。 Python環境がないパソコンでも、ダウンロード後すぐに起動して使える完全版となっています。ぜひチェックしてみてください! 👉 Invoice Maker (NINJIN EDITION) をnoteで確認する

スポンサーリンク

他のシリーズ



コメント