【Python】パワポ自動化:「表」を検出しデータを挿入する方法
Pythonを用いてPowerPointファイルを操作するライブラリ「python-pptx」を活用し、スライド内に配置された特定の「表(Table)」をプログラム側から自動検出し、任意のデータを動的に書き換える方法について解説します。既存の表のデザインやフォント、中央揃えといった細かなレイアウトの体裁を維持したまま、テキストだけを安全に上書き・更新する処理です。
こちらが実行イメージです。既存の表にデータが挿入されていることがわかると思います。実際のPythonコードは以下。
from pathlib import Path
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.enum.text import PP_ALIGN
from pptx.oxml.ns import qn
# ==========================================
# 準備:ファイルの読み込みと住所録データの定義
# ==========================================
# ※ 実行する際は、スクリプトと同じフォルダに「format2.pptx」を用意してください。
template_path = Path("format.pptx")
if not template_path.exists():
raise FileNotFoundError(f"テンプレートファイルが見つかりません: {template_path}")
prs = Presentation(str(template_path))
# 誰もがわかりやすい住所録データ(CSVから1行読み込んだ状態を想定)
csv_row = {
"EmployeeID": "EMP-00125",
"Name": "山田 太郎",
"Department": "開発部",
"Position": "課長",
"Phone": "090-1234-5678",
"Email": "yamada@example.com",
"Emergency": "03-9876-5432"
}
# 操作対象のスライドを指定(例として3ページ目:index=1 を操作)
slide = prs.slides[1]
# 適用するフォントの定義
FONT_NAME = "BIZ UDPゴシック"
# ==========================================
# 1. スライド内の「表(テーブル)」を探索
# ==========================================
# スライド上のすべてのオブジェクト(図形、テキストボックス、表など)をループで調べます。
for shape in slide.shapes:
# オブジェクトの種類が「表(TABLE)」であるか判定
if shape.shape_type == MSO_SHAPE_TYPE.TABLE:
tbl = shape.table
# ------------------------------------------
# 2. [0行、1列目] のセルに「社員ID」を書き込み
# ------------------------------------------
cell_id = tbl.cell(0, 0)
tf_id = cell_id.text_frame
# セル内の段落を処理(中央揃えとフォント固定の適用)
for p in tf_id.paragraphs:
p.alignment = PP_ALIGN.CENTER # 横方向を「中央揃え」に設定
# 段落内に文字の塊(Run)がない場合は新規作成
if len(p.runs) == 0:
r = p.add_run()
r.text = csv_row["EmployeeID"]
r.font.name = FONT_NAME
# XML要素に直接アクセスし、フォント名を設定(文字化けや装飾消失を防ぐバグ対策)
r._r.get_or_add_rPr().set(qn("a:ea"), FONT_NAME)
r._r.get_or_add_rPr().set(qn("a:latin"), FONT_NAME)
r._r.get_or_add_rPr().set(qn("a:cs"), FONT_NAME)
else:
# 既にRunがある場合は最初のRunを書き換え、残りをクリア
p.runs[0].text = csv_row["EmployeeID"]
p.runs[0].font.name = FONT_NAME
rPr = p.runs[0]._r.get_or_add_rPr()
rPr.set(qn("a:ea"), FONT_NAME)
rPr.set(qn("a:latin"), FONT_NAME)
rPr.set(qn("a:cs"), FONT_NAME)
for r in p.runs[1:]:
r.text = ""
# ------------------------------------------
# 3. マッピング定義に基づいて他のセル(住所録データ)を書き換え
# ------------------------------------------
# 書き換えたいセルの位置(行, 列)と、対応するデータのキー(列名)
mapping = {
(1, 0): "Name", # 1行目の0列目 ➔ 氏名
(1, 1): "Department", # 1行目の1列目 ➔ 部署
(1, 2): "Position", # 1行目の2列目 ➔ 役職
(2, 0): "Phone", # 2行目の0列目 ➔ 電話番号
(2, 1): "Email", # 2行目の1列目 ➔ メールアドレス
(2, 2): "Emergency" # 2行目の2列目 ➔ 緊急連絡先
}
# マッピングをループ処理して各セルにデータを流し込む
for (r, c), col in mapping.items():
val = csv_row.get(col, "")
text_to_insert = "" if val is None else str(val)
# 対象のセルを取得してテキストフレーム(文字枠)にアクセス
target_cell = tbl.cell(r, c)
tf_target = target_cell.text_frame
# 各セルの段落に対して中央揃えとフォントの適用処理を実施
for p in tf_target.paragraphs:
p.alignment = PP_ALIGN.CENTER # 中央揃え
if len(p.runs) == 0:
r_new = p.add_run()
r_new.text = text_to_insert
r_new.font.name = FONT_NAME
r_new._r.get_or_add_rPr().set(qn("a:ea"), FONT_NAME)
r_new._r.get_or_add_rPr().set(qn("a:latin"), FONT_NAME)
r_new._r.get_or_add_rPr().set(qn("a:cs"), FONT_NAME)
else:
p.runs[0].text = text_to_insert
p.runs[0].font.name = FONT_NAME
rPr = p.runs[0]._r.get_or_add_rPr()
rPr.set(qn("a:ea"), FONT_NAME)
rPr.set(qn("a:latin"), FONT_NAME)
rPr.set(qn("a:cs"), FONT_NAME)
# 2つ目以降の余分な文字の塊があれば削除
for remaining_run in p.runs[1:]:
remaining_run.text = ""
# スライド内の目的の表を1つ処理できたら、他の図形の探索(ループ)は終了
break
# ==========================================
# 完了:別名で保存
# ==========================================
output_path = Path("address_replaced_output.pptx")
prs.save(str(output_path))
print(f"住所録表の検出およびテキスト置換が完了しました。保存先: {output_path}")
スポンサーリンク
