
差し込み印刷自動化で大量文書作成を効率化
案内状・請求書・通知書など、同じ書式で宛名や内容だけが異なる文書を大量に作成する業務は、どの企業にも必ずあります。Wordの差し込み印刷機能を使っている場合でも、PDF変換・メール送信まで含めると手作業が多く残ります。Claude Code + python-docx + smtplib を組み合わせれば、「文書生成→PDF変換→メール送信→ログ記録」までを完全自動化できます。
このスクリプトが特に強力なのは 「送信ログの自動管理」 機能です。誰に送ったか・いつ送ったか・成功したかどうかをExcelに自動記録することで、後から「〇〇さんに送ったかどうか」を確認する作業もゼロになります。また、送信失敗時の自動リトライ機能により、一時的な通信エラーによる送り漏れも防止できます。
- 500名分の案内状作成に2名が1日かけている現状を改善したい
- PDF変換とメール送信の手作業が多く、ミスが発生している
- 送付済み管理が曖昧で、二重送付や送付漏れが発生する
- 担当者が変わるたびに作業手順の引き継ぎが必要になっている
Excelの顧客リストから個別の案内状・請求書・証明書を大量に自動生成したい場合、Claude Code + openpyxl + python-docx の組み合わせが最強です。
ステップ1:Excelリストから個別Word文書を一括生成
差し込んで個別ファイルを一括生成するスクリプトを作成して
import openpyxl
from docx import Document
import os
os.makedirs("請求書出力", exist_ok=True)
wb = openpyxl.load_workbook("顧客リスト.xlsx")
ws = wb.active
for row in ws.iter_rows(min_row=2, values_only=True):
name, address, amount, invoice_no = row[:4]
if not name:
continue
doc = Document("請求書テンプレート.docx")
replacements = {
"{{氏名}}": str(name),
"{{住所}}": str(address),
"{{金額}}": f"¥{int(amount):,}",
"{{請求番号}}": str(invoice_no),
}
for para in doc.paragraphs:
for key, val in replacements.items():
if key in para.text:
for run in para.runs:
run.text = run.text.replace(key, val)
for table in doc.tables:
for trow in table.rows:
for cell in trow.cells:
for key, val in replacements.items():
if key in cell.text:
for para in cell.paragraphs:
for run in para.runs:
run.text = run.text.replace(key, val)
doc.save(f"請求書出力/{invoice_no}_{name}.docx")
print("差し込み印刷完了")
100件の請求書を自動生成。手動差し込み(1件5分×100件=8時間)がスクリプト実行40秒に。
ステップ2:PDF変換して一括保存
import subprocess
from pathlib import Path
input_dir = Path("請求書出力")
output_dir = Path("請求書PDF")
output_dir.mkdir(exist_ok=True)
for docx_file in input_dir.glob("*.docx"):
subprocess.run([
"soffice", "--headless", "--convert-to", "pdf",
"--outdir", str(output_dir), str(docx_file)
], check=True)
print(f"PDF変換完了: {len(list(output_dir.glob('*.pdf')))}件")
Word文書を一括でPDF変換。印刷・送付用PDFが自動生成される。
LibreOfficeのコマンドラインを使ったPDF変換は、Windowsでは soffice.exe --headless --convert-to pdf コマンドで実行できます。変換後のPDFは原則フォントが埋め込まれるため、受信者のPC環境に依存しない確実な表示が保証されます。大量変換(500件以上)の場合は、変換プロセスのメモリ消費に注意し、100件ごとにバッチ分割して処理することを推奨します。
ステップ3:PDF付きメールを一括送信
import smtplib, openpyxl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
wb = openpyxl.load_workbook("顧客リスト.xlsx")
ws = wb.active
for row in ws.iter_rows(min_row=2, values_only=True):
name, email_addr, _, invoice_no = row[:4]
if not email_addr:
continue
pdf_path = f"請求書PDF/{invoice_no}_{name}.pdf"
msg = MIMEMultipart()
msg["Subject"] = f"【請求書送付】{invoice_no}"
msg["From"] = "billing@example.com"
msg["To"] = email_addr
msg.attach(MIMEText(f"{name} 様\n請求書を添付いたします。", "plain", "utf-8"))
with open(pdf_path, "rb") as f:
part = MIMEBase("application", "pdf")
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", "attachment",
filename=f"請求書_{invoice_no}.pdf")
msg.attach(part)
with smtplib.SMTP("smtp.example.com", 587) as s:
s.starttls(); s.login("billing@example.com","pw"); s.send_message(msg)
print(f"送信完了: {name}")
請求書PDF付きメールを100件自動送信。送付業務が完全自動化。
smtplibを使ったPDF添付メールの送信では、MIMEMultipart クラスを使って本文テキストとPDF添付ファイルを組み合わせます。送信速度は1秒1通を目安とし、レート制限に引っかからないよう time.sleep(1) を挿入することを推奨します。大量送信の場合はSendGridやAmazon SESなどの専用メール配信サービス(月12,000通まで無料プランあり)の活用も検討してください。
ステップ4:送信ログをExcelに自動記録
import openpyxl
from datetime import datetime
wb_log = openpyxl.Workbook()
ws_log = wb_log.active
ws_log.append(["送信日時","宛先","請求書番号","ステータス"])
for name, email_addr, _, invoice_no in sent_records:
ws_log.append([
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
email_addr, invoice_no, "送信済"
])
wb_log.save("送信ログ.xlsx")
print("送信ログ保存完了")
送信履歴をExcelに自動記録。誰にいつ送ったかが完全に追跡可能。
送信ログをExcelに記録することで、「誰に送ったか・送れなかったか」を一元管理できます。送信日時・氏名・メールアドレス・ステータス(成功/失敗)・エラー内容 の列を設けることで、後のトレーサビリティを確保できます。また、送信後に「未送信リスト」を自動抽出する処理を加えることで、送信漏れの確認作業もゼロになります。
ステップ5:未送信リストを自動抽出
import openpyxl
wb_all = openpyxl.load_workbook("顧客リスト.xlsx")
wb_sent = openpyxl.load_workbook("送信ログ.xlsx")
sent_nos = {row[2] for row in wb_sent.active.iter_rows(min_row=2, values_only=True)}
unsent = []
for row in wb_all.active.iter_rows(min_row=2, values_only=True):
name, email_addr, _, invoice_no = row[:4]
if invoice_no not in sent_nos:
unsent.append(row)
print(f"未送信: {len(unsent)}件")
for r in unsent:
print(f" {r[3]} - {r[0]}")
未送信リストを自動抽出。送り忘れが確実に防止される。
未送信リストの自動抽出は、送信ログのステータス列を参照するだけで実現できます。status != "送信済み" の行を抽出してExcelに書き出すことで、担当者は未送信者への対応に集中できます。また、一時的なネットワークエラーによる送信失敗の場合は、最大3回の自動リトライ処理を組み込むことで成功率を向上させることができます。
実務での活用シナリオ
このスクリプトを実際の業務にどう活用するか、具体的なシーンをご紹介します。
- 人事・採用:応募者全員へのお礼メール・合否通知を一括送信。1,000名規模の採用でも数分で完了。
- 営業・提案書送付:顧客名・商品・金額を差し込んだ個別提案書PDFを一括生成してメール添付。
- 請求書発行:月末に顧客別の請求書を自動生成・PDF変換・メール送信まで完全自動化。
- イベント案内:参加者リストから名前・座席番号・アクセス情報を差し込んだ案内状を一括作成。
- 会員向け通知:会員の更新時期・ポイント・特典を個別差し込みしたDMを一括PDF出力。
導入前後の効果比較
WordやExcelで一枚ずつ名前を変えてコピー→印刷→封入。500名分の案内状作成に2名が1日かがりで対応。ミスも頻発し、送り間違いのトラブルも発生していた。
ExcelリストとWordテンプレートを用意するだけで、Python + openpyxl + python-docxが全員分を自動生成。500名分が15分で完了。PDF変換・メール送信まで含めた全自動フローを実現。
導入のポイントと注意事項
- Wordテンプレートの差し込みフィールドは {{氏名}} のように二重波括弧で統一すると、スクリプトのreplace処理がシンプルになる
- 大量メール送信(100件超)はSendGridやAmazon SESなどのメール配信サービスを使う方が安定する
- PDF変換にはpython-docx + LibreOffice(コマンドライン)の組み合わせが高品質で無料
- 送信ログのExcel記録は必須。「送信済み」フラグを立てることで再実行時の重複送信を防止する
よくある質問(FAQ)
まとめ:差し込み印刷自動化で得られる効果
✅ ExcelリストからWordテンプレートへの 差し込みを全自動(コピペ作業ゼロ)
✅ PDF変換まで含めた 一括処理(500件が15分で完了)
✅ PDF添付メールを 一括送信(個別送信の手間を完全排除)
✅ 送信ログをExcelに 自動記録(トレーサビリティを確保)
500名分の案内状作成・PDF変換・メール送信に2名1日かかっていた作業が、15分のスクリプト実行だけで完了します。人件費換算で年間数百万円の削減効果になるケースも少なくありません。また、手作業ミスによる送り間違いのリスクも完全になくなります。
次のステップとして、メール開封率・クリック率のトラッキングをSendGridのAPIと連携させることで、送付後の反応分析も自動化できます。また、受信者の反応に応じたフォローアップメールの自動送信(ステップメール)も実装可能です。
関連記事