PowerPointファイルの拡張子を
.zipに変えて解凍すると、中にはXMLファイルがずらりと並んでいる。
テキストも図形も画像も、すべてが 構造化されたデータ として格納されている。
python-pptx はこの構造を Python オブジェクトとして操作するライブラリだ。
前編では、PPTXの内部構造を探検し、python-pptx の基本操作、そして テンプレートという絶対に外せない概念 を押さえる。
先に要点
-
.pptxは ZIP 内に XML が詰まった構造化ファイル - 中身は Slide → Shape → TextFrame → Paragraph → Run の5層構造
- python-pptx はこの階層を Python オブジェクトとして読み書きできる
- テンプレートがないと、デザイン情報がゼロになる ── これが最大の落とし穴
この記事で分かること
- PPTXファイルの内部構造と、python-pptx がそれをどう扱うか
- スライドを走査して情報を抽出する実際のコード
- 「テンプレートなし」だと何が起きるのか、なぜテンプレートが必須なのか
- 後編(JSON変換+LLM連携)に向けた前提知識
今回使う Mermaid 図の種類
| 図の種類 | 用途 |
|---|---|
| flowchart | PPTXの内部構成、テンプレート有無の分岐 |
| classDiagram | PPTXの5層オブジェクト構造 |
| sequenceDiagram | python-pptx の読み取り処理フロー |
| stateDiagram-v2 | テンプレート内のデザイン継承 |
| mindmap | python-pptx の機能全体像 |
1. PPTXファイルの正体 ── ZIP の中の XML 群
PowerPointファイルは、見た目はひとつの塊だが、実態は XMLファイルの集合体をZIPで圧縮したもの だ。
スライド本体(slide*.xml)とは別に、デザインを司る「マスター」「レイアウト」「テーマ」が独立したファイルとして存在している。この分離が、後述するテンプレートの概念に直結する。
python-pptx は、このZIP内のXML群を Python の Presentation オブジェクトに変換してくれる。開発者は XML を意識せずに、Python のオブジェクト操作だけでスライドを読み書きできる。
2. PPTXの5層構造 ── コードで辿る入れ子の箱
PPTXの中身は、マトリョーシカのような入れ子構造を持っている。python-pptx はこれを忠実にオブジェクトモデルとして表現する。
文字の装飾(太字・色・サイズ)は最下層の Run 単位で管理される。1段落の中で「ここだけ赤太字」にしたい場合、その部分が別の Run として分離される。
実際に走査するコード
この5層構造を、python-pptx で辿るコードはこうなる。
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
prs = Presentation("sample.pptx")
for slide in prs.slides: # レイヤー1: Slide
for shape in slide.shapes: # レイヤー2: Shape
print(f"シェイプ: {shape.name}, 種類: {shape.shape_type}")
if shape.has_text_frame:
tf = shape.text_frame # レイヤー3: TextFrame
for para in tf.paragraphs: # レイヤー4: Paragraph
for run in para.runs: # レイヤー5: Run
print(f" テキスト: {run.text}")
print(f" 太字: {run.font.bold}, サイズ: {run.font.size}")
prs.slides → slide.shapes → shape.text_frame → tf.paragraphs → para.runs と、5層を順にネストして辿る。python-pptx のオブジェクトモデルがPPTXの内部構造とそのまま対応しているため、直感的に読める。
ここで重要なのが、Shape にはテキスト以外にも画像・図形・グラフなどがある という点だ。shape.shape_type で種類を判別し、MSO_SHAPE_TYPE.PICTURE なら画像処理、AUTO_SHAPE なら図形処理、というように分岐させる。
3. Shape の多様性 ── テキストだけではない
1枚のスライドに載っている「部品」は、すべて Shape として管理されている。
for shape in slide.shapes:
shape_data = {
"name": shape.name,
"left": shape.left.pt, "top": shape.top.pt,
"width": shape.width.pt, "height": shape.height.pt,
"shape_type": shape.shape_type.name,
"is_placeholder": shape.is_placeholder,
}
# 画像の場合
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
image_bytes = shape.image.blob # バイナリ画像データ
# オートシェイプ(四角形、角丸など)の場合
if shape.shape_type == MSO_SHAPE_TYPE.AUTO_SHAPE:
shape_data["auto_shape_type"] = shape.auto_shape_type.name
# プレースホルダーの場合
if shape.is_placeholder:
ph = shape.placeholder_format
shape_data["placeholder"] = {"type": ph.type.name, "idx": ph.idx}
このコードは3つのことをしている。
- すべての Shape に共通する情報(名前、位置、サイズ、種類)を辞書に格納
- Shape の種類に応じた分岐 で、画像データやオートシェイプの形状を追加取得
- プレースホルダーかどうか を判定し、タイプとインデックスを記録
is_placeholder は特に重要だ。プレースホルダーとは、レイアウトで「ここにタイトルを入れてね」と予約された領域のこと。idx でどのプレースホルダーかを特定し、テキストを流し込む際の宛先になる。
4. テンプレートの3層構造 ── デザインの設計図
python-pptx を使ううえで 最も理解が必要な概念 がテンプレートだ。テンプレートの中には、3つの設計図が階層的に格納されている。
デザインは「テーマ → マスター → レイアウト → プレースホルダー」と段階的に継承される。レイアウトを選ぶだけで、テーマの配色やマスターのデザインルールが自動的に適用される。
テンプレートの構造を読み取るコード
後編で使う analyze_pptx() 関数は、このテンプレート構造も解析する。マスターとレイアウトの走査部分を抜粋する。
for master in prs.slide_masters:
master_data = {"layouts": []}
for layout in master.slide_layouts:
layout_data = {"name": layout.name, "shapes": []}
for shape in layout.shapes:
shape_data = {
"name": shape.name,
"type": shape.shape_type.name,
"is_placeholder": shape.is_placeholder
}
if shape.is_placeholder:
ph_format = shape.placeholder_format
shape_data["placeholder_type"] = PP_PLACEHOLDER(ph_format.type).name
layout_data["shapes"].append(shape_data)
master_data["layouts"].append(layout_data)
このコードは slide_masters → slide_layouts → shapes と辿り、各レイアウトがどんなプレースホルダーを持っているかを記録する。この情報があれば、「どのレイアウトを使い、どの idx にテキストを入れるか」をプログラム的に判断できる。
5. テンプレートなしだと何が起きるか
テンプレートなしだと、配色テーマ・フォント定義・カスタムレイアウトがすべて消える。プロが作ったPowerPointを再現するのは、テンプレートなしではほぼ不可能。
具体的に失われるもの:
| 要素 | テンプレートあり | テンプレートなし |
|---|---|---|
| フォント | 游ゴシック、メイリオなど指定通り | Calibri(日本語で文字化けリスク) |
| 配色テーマ | ACCENT_1〜6 が企業カラーに設定 | Office 標準の地味な配色 |
| レイアウト | プロ設計のカスタムレイアウト多数 | 最低限の4種類のみ |
| 装飾 | 背景画像、ロゴ、ヘッダー/フッター | 一切なし |
だから python-pptx でスライドを生成する際は 「テンプレートとなる .pptx を渡し、そのレイアウトに中身を流し込む」 のが鉄則になる。
6. python-pptx の全体像
python-pptx は「読み取り」「書き込み」「テンプレート活用」の3軸で整理できる。読み取りで得た情報を辞書に変換すれば、後編で扱うJSON化の土台になる。
一言で言うと何者か
python-pptx は、PowerPoint内部の5層構造を Python オブジェクトとして読み書きするライブラリ だ。ただし見た目の再現には テンプレートという設計図 が不可欠であり、テンプレートがなければ「中身はあるが見た目のない」骨だけのスライドしか作れない。
まとめ
- PPTXの正体は ZIP内のXML群。python-pptx はそれを Python オブジェクトに変換する
- 中身は Slide → Shape → TextFrame → Paragraph → Run の5層構造
- Shape には画像・図形・プレースホルダーなど多様な種類があり、
shape_typeとis_placeholderで分岐する - テンプレートは「テーマ → マスター → レイアウト → プレースホルダー」の3層設計図。なしだとデザイン情報がゼロになる
- テンプレートのレイアウトとプレースホルダーの
idxを理解すれば、デザインを維持したまま中身を流し込める
後編では、この5層構造をまるごと JSON に変換する analyze_pptx() 関数のコードを読み解き、LLM にスライドを読ませて編集させるアプローチを実装レベルで解説する。
GitHub リポジトリ
この記事で解説しているコードの全体は、以下のリポジトリで公開しています。
pptx_processor.py、llm_handler.py、Streamlit アプリ、CLI 実行スクリプトなど、すべてのソースコードを参照できます。
後編はこちら → PowerPointをJSONに変換してLLMに読ませる ── 実装コードで理解するAIスライド編集【後編】