LoginSignup
2
7

More than 3 years have passed since last update.

【python-pptx】pythonでPowerPoint のフォント情報をcsvに出力

Posted at

背景

PowerPoint の資料Reviewで一部のフォントが間違っていると指摘をいただきました。
100ページ以上のスライドのどこのフォントが違っているかを、一つずつチェックして修正…。
目検でやりたくなかったですし、これから先も同様の作業をする可能性があるので効率的にできないか…と思いました。

python-pptx

今の時代 python でできないことなんてないやろ!
調べてみると、python-pptx で python から PowerPoint のファイルが操作できることがわかりました。
公式ページ:python-pptx

オブジェクトのイメージ

Qiitaの偉大な先駆者様達の記事を参考に、公式の Getting Start を少し触りました。
なんとなくイメージがついたので、下記にDumpします。
(間違っていたらご指摘をお願いいたします…)

全体の俯瞰図

Presentation > slides[] > shapes[] > text_frame.paragraphs[] > runs[]
スライド4.PNG

shapes[] とスライドの対応

slide はそのスライド内のオブジェクトを shapes[] に配列の形で持っている。
スライド5.PNG

text_frame.paragraphs[] とスライドの対応

shape の中で、文字を持てるもの(?)は text_frame.paragraphs[] を持てる。
よく shapes[n].paragraphs[m] でアクセスしようとしてエラーになってました…。
スライド6.PNG

runs[] とスライドの対応

1文字毎にフォントを変えられますが、どうやって持っているんだろう…と、前々から疑問でした。
run という単位で持っているようで、それぞれにフォントが設定できます。
スライド7.PNG

作ったもの

全スライドの全 paragraphs と runs を csv に dump。
TARGET_FILE_PATH には対象の powerpoint ファイルへのパスを、OUTPUT_FILE_PATH には出力の csv のファイルへのパスを設定。

python-pptx.py
from pptx import Presentation
from pptx.util import Pt
import csv

TARGET_FILE_PATH = './targetFile/targetFile.pptx'
OUTPUT_FILE_PATH = './output.csv'
FONT_SIZE_DIVESER = 12700
# ["pptxFile名","slide番号","object番号","run番号","オブジェクトタイプ"," font.name"," font.size"," text"]
def export_slide_fonts_and_text():
  outputArray = []
  outputArray.append(["pptxFile名","slide番号","object番号","paragraph番号","run番号","オブジェクトタイプ"," font.name"," font.size"," text"])

  # ppt file の読み込み
  prs = Presentation(TARGET_FILE_PATH)

  slide_number = 0
  # スライドの読み込み
  for slide in prs.slides:
    shape_number = 0
    # shape ごとに処理
    for shape in slide.shapes:
      if not shape.has_text_frame:
        shape_number = shape_number + 1
        continue

      paragraph_number = 0
      # paragraph の段階で一旦出力
      for paragraph in shape.text_frame.paragraphs:
        if(paragraph.font.size != None):
          fontSize = paragraph.font.size/FONT_SIZE_DIVESER
        else:
          fontSize = None
        outputArray.append([TARGET_FILE_PATH, slide_number, shape_number,paragraph_number, "-","paragraph", str(paragraph.font.name), str(fontSize), paragraph.text])

        run_number = 0
        # runを各々出力
        for run in paragraph.runs:
          if(run.font.size != None):
            fontSize = run.font.size/FONT_SIZE_DIVESER
          else:
            fontSize = None
          outputArray.append([TARGET_FILE_PATH, slide_number, shape_number,paragraph_number, run_number, "run", str(run.font.name), str(fontSize), run.text])

          run_number = run_number + 1
        paragraph_number = paragraph_number + 1
      shape_number = shape_number + 1
    slide_number = slide_number +1

  # 書き込み
  with open(OUTPUT_FILE_PATH, 'w', encoding="shift-jis") as f:
    wirter = csv.writer(f, lineterminator='\n', quoting=csv.QUOTE_ALL)
    wirter.writerows(outputArray)

if __name__ == "__main__":
  export_slide_fonts_and_text()

出力されたものを少し加工

csv で出力されたものを、Excel に貼って色を付けて見たものが下記です。
大体ですが、やりたいことができていそうな感じです!
image.png

ToBe

デフォルトの値を取ってくる

上記のExcelにある通り、フォント名やフォントサイズが「None」となっているところが多くあります。
値が設定されていない場合デフォルトの値を参照するそうです。
placeholder にアクセスすることで取得できそうなのですが…もう少し調べてみたいと思います。

参考にさせていただいた先駆者様

ありがとうございます…。
圧倒的感謝…!
python-pptxまとめ
python-pptxでレポーティングを自動化する
[Python]爆速で報告パワポを生成する!
Pythonを使ったレポートの自動作成【PowerPoint】【python-pptx】
https://qiita.com/code_440/items/22e8539da465686496d3

2
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7