Python業務自動化 Invoice Maker 第1回
はじめに:PythonでExcelから請求書を作りPDFに変換する
こんにちは、VBA・Python業務自動化ラボ(py-vbalab.com)のニンジンです🥕
この記事では、openpyxl と pywin32(win32com) を使って、Excelの「受注管理表」からデータを読み取り、「請求書の雛形」に書き込んでPDFに変換するPythonスクリプトの作り方を、初心者向けに解説します。全3回シリーズの第1回で、まずは1枚の請求書を自動作成してPDF化する基本ロジックを作ります。
毎月末、「受注一覧のExcelから会社名や金額をコピーして、請求書の雛形に貼り付けて、PDFで保存する」——数件ならまだしも、数十件・数百件になると完全に苦行です。コピペミスによる作り直しなどのヒューマンエラーも増えます。VBAでも自動化できますが、ここではより拡張性の高いPythonで進めます。
この記事で分かること
- openpyxl と pywin32(win32com)のインストール方法と、それぞれの役割
- Excelのセルの値を読み取り、別のExcel(雛形)に書き込むPythonコード
- openpyxlだけではできない「PDFへの変換」を、win32comで実現する手順
data_only=Trueで数式ではなく「計算結果の数値」を読み込む理由- 一時ファイル(temp.xlsx)を経由して、雛形のレイアウトを崩さずPDF化する仕組み
「Pythonの環境構築が面倒」「コードを書かずに今すぐ業務で使える完成品が欲しい」という方向けに、本シリーズで作るツールの完成版(設定不要のフルパッケージ)【Invoice Maker (NINJIN EDITION)】をnoteで頒布しています。
👉 noteでチェックするPythonでExcelをPDFに変換するための事前準備
準備1:openpyxl と pywin32 のインストール
Excelの読み書きとPDF化のために、2つのライブラリを使います。コマンドプロンプト(またはターミナル)で以下を実行します。
pip install openpyxl
pip install pywin32- openpyxl:Excelファイル(.xlsx)のデータを読み書きする定番ライブラリ
- pywin32(win32com):PythonからExcel本体を裏側で直接操作するためのライブラリ。PDF化はこれが担当します
2つとも「Successfully installed」と表示されればOKです。うまくいかない場合は python -m pip install ... を試してください。
準備2:サンプルExcelファイル(受注管理表・請求書雛形)のダウンロード
お手持ちの管理表と書類フォーマットを使うか、下記のサンプルをダウンロードしてください。
1枚の請求書を自動作成する完成コード(openpyxl+win32comでExcel→PDF)
今回作成する「1枚の請求書を自動作成する」Pythonスクリプトの全体です。受注管理表の4行目のデータを読み取り、請求書の雛形の所定のセルに書き込んでPDF化します。テストコードとExcel2ファイルを同じフォルダに置いて実行してください。
⬇ テストコード一式をダウンロード(Invoice_Maker_test01.zip)
VS Codeでフォルダを開き、invoice_maker_test01.py・受注管理表・請求書雛形を同じ階層に置きます。こうするとコード内のパス指定がファイル名だけで済みます。
# 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のターミナルに
作成完了: ...請求書_出力.pdfと表示されれば成功です - Pythonコードと同じフォルダにPDFが生成されています
openpyxl・pywin32初心者がハマりやすい2つの罠と対策
一見シンプルなコードですが、実務で使ううえで知っておくべき「工夫」が2つ隠れています。
① data_only=True で数式ではなく「計算結果の数値」を読み込む
Excelを読み込むとき、ただ load_workbook を使うと、金額などの計算式が入ったセルは "=SUM(H2:H3)" のような文字列の数式として取得されてしまいます。これを別のExcelに転記すると値が合いません。
openpyxl.load_workbook(KANRI_PATH, data_only=True) と指定すると、Excelが計算したあとの結果の値(数値)だけをクリーンに取り出せます。データ自動化の前処理では必須のテクニックです(対象のExcelが一度も保存・再計算されていないと None が返る点には注意)。
② 一時ファイル(temp.xlsx)に一度保存する理由:雛形のレイアウトを崩さない
openpyxlは高速にExcelを編集できますが、「PDFとして書き出す」機能は持っていません。PDF化は、パソコンにインストールされた本物のExcelに任せる必要があります(これが win32com の役割です)。
そこでこのコードでは、
- openpyxlでデータを書き込んだ後、
temp.xlsxという仮の名前で保存する - win32comでExcelアプリを起動し、その
temp.xlsxを開いてPDFとして書き出す - 用済みの
temp.xlsxをos.removeで削除する
という手順を踏んでいます。これにより、元の雛形のレイアウト(罫線・書式)を一切崩さずにPDFを生成できます。
まとめ:1枚の自動化ができれば大量処理まであと一歩
数十行のコードを実行するだけで、指定フォルダに請求書のPDFが生成されました。手作業のコピペから解放された瞬間です。
ただ、勘のいい方はこう思うはずです。「コードで C4 や H4 を直接指定しているけれど、100社分あったらどうするの?」——その通りで、今のままでは1枚しか作れません。次回は for文(ループ処理) を組み込み、フォルダ内に大量の請求書を一気に出力するスクリプトへ発展させます。途中でエラーが起きても止まらない書き方も解説します。
PR
「次回の解説まで待てない」「自分でコードを組む時間がない」という方は、noteで完成版のGUIアプリ【Invoice Maker (NINJIN EDITION)】を頒布中です。Python環境がないパソコンでも、ダウンロード後すぐに起動して使えます。
👉 noteで確認するよくある質問(openpyxl・pywin32でのExcel→PDF)
QExportAsFixedFormat でエラーが出る/PDFが作られません
Awin32com(pywin32)は、パソコンにインストールされた「本物のExcel」を操作してPDF化します。そのため、Excelが入っていない環境では動きません。pip install pywin32 が済んでいるか、import win32com.client が通るかも確認してください。
Qdata_only=True にしたのにセルの値が None になります
Adata_only=True は「Excelが最後に計算して保存した結果」を返します。openpyxlで作った直後のファイルや、数式が再計算されていないファイルでは None になることがあります。対象のExcelを一度手動で開いて上書き保存すると、計算結果が保存されて値が取れるようになります。
QModuleNotFoundError: No module named ‘openpyxl’(または win32com)が出ます
Aライブラリが未インストールです。pip install openpyxl と pip install pywin32 を実行します。パソコンに複数のPythonが入っている場合は、python -m pip install … の形で、実行に使うPythonへ確実にインストールしてください。
Q出力したPDFで、請求書の雛形のレイアウト(罫線・書式)が崩れます
Aopenpyxlで雛形に直接書き込んでPDF化しようとすると起きがちです。この記事の手順(openpyxlで値を書き込む → temp.xlsxに保存 → win32comでそのファイルを開いてPDF化 → temp.xlsxを削除)にすると、元の雛形ファイル自体は触らないため、レイアウトを保ったままPDFになります。
Q出力されるPDFの保存先(フォルダ)を変えたいです
Aコードの OUTPUT_PATH を書き換えます。os.path.abspath(“請求書_出力.pdf”) の部分を、r”C:\\Users\\…\\請求書.pdf” のようにフルパスで指定すれば、任意の場所に保存できます。
Follow me on X
本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕
@ninjin_py_vba をフォローシリーズ記事一覧
電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。
-
FILE.01 — IoT
Raspberry Pi Pico W × GASラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
「外出中のペットの室温が心配…」そんな思いからスタートしたIoT自作プロジェクトの総集編。温湿度監視からエアコン遠隔操作まで、仕組みをゼロから作りたい方のための全5回の開発記録です。
シリーズを読む -
FILE.02 — CNC
Arduino × レーザー刻印CNCCNC自作シリーズ
高精度な加工を目指し、本格的な自作CNC製作に挑戦中。現在は基幹パーツであるオリエンタルモーターの納品を待つ「設計・準備編」を公開。ハードとソフトの両面から、理想のマシンを形にする過程をリアルタイムにお届けします。
シリーズを読む -
FILE.03 — XY軸制御
Raspberry Pi × ステッピングモーターXYテーブルシリーズ
Raspberry Piとステッパモーターを使い、ゼロから2軸制御に挑む記録。OS設定から回路設計、多軸制御のPythonコードまで、躓きやすいポイントを徹底図解。電子工作初心者が「動く感動」を味わうための実戦ガイドです。
シリーズを読む -
FILE.04 — 業務自動化
Python × Excel × CustomTkinter【Python開発記】NINJIN Mail制作記
PythonとExcelを連携させ、実務で即戦力となるメール送信ツールを開発。CustomTkinterによるUI構築や、ミスを防ぐテンプレート活用術など、現場の「痒い所に手が届く」自動化ノウハウを細部まで丁寧に解説します。
シリーズを読む -
FILE.05 — 業務自動化
Python × Excel × GUIアプリ化Invoice Maker(請求書・見積書自動作成)
手作業の請求書作成から卒業!PythonでExcelデータを読み込み一括PDF化する「Invoice_Maker」の作り方を全3回で解説。基本ロジックからGUIアプリ化まで、実務で役立つ自動化ノウハウが満載です。
シリーズを読む







コメント