どんな記事?
ExcelなどでまとめたデータをPowerPointに自動で移行してくれるツールの作成.
PowerPointで作成するレイアウトが既に決まっていて大量にスライド生産するっていう場合に便利.
今回作成したもの
とある大会の作品ごとのポスターをパワーポイントで自動作成.
ポスターに入れた情報は以下のもの.
- 作品名
- チーム名
- 作品の画像(今回はjpgだがpngでも良い)
- 作品概要(日本語と英語)
実行環境
- Python 3.6.3
- 当初はPython 3.7でやろうとしたがpptxライブラリが使えなかったのでバージョンダウンして3.6に
- macOS High Sierra.ver10.13.6
用意するもの
作品情報が入ったエクセルファイル
各種情報とシート名を記入.今回は画像をパスで指定.(多分もっといいやり方ある)
テンプレート用のPowerPointファイル
スライドマスターで作成.自動生成する際のテキストの位置やフォントもこのスライドマスターに依存される.
導入
Pythonでパワーポイントファイルとエクセルファイルを扱うため,pipでpython-pptx
, openpyxl
をインストール.
pip install python-pptx
pip install openpyxl
ライブラリのインポート
pipでインストールしたpython-pptx
, openpyxl
をインポート.
また,センチメートルをPowerPoint上の距離に変換するためにInches
もインポート
from pptx import Presentation
from pptx.util import Inches
import openpyxl
読み込み部分
Pythonファイルと同じ階層にあるエクセルファイルとテンプレートファイルの読み込みを行う.
テンプレートファイルのパワーポイントを格納した変数.slide_layouts[0]
の引数の部分は引用したいスライドのページを書く.(0は1枚目)
# ブックを取得
Book = openpyxl.load_workbook(Book_File)
# シートを取得
Sheet = Book[Book_Sheet]
lastRow = Sheet.max_row # 作品数の格納
# テンプートファイルの取得
prs = Presentation(Template_File)
blank_slide_layout = prs.slide_layouts[0] # page layout
書き込み部分
今回は作品の数だけスライドを生成したかったのでfor文
で作品数分だけ回す.
シートを格納した変数.cell(row = ✖, column = △).value
でエクセルファイルからデータを持って来る.
slide.placeholders[引数]
はテンプレートファイルのテキストボックスなどを取得するための処理.引数の確認の仕方はトラブルを参照
# 全ての作品を書き出すまでループ
for i in range(lastRow - 1):
# 白紙のスライドの追加
slide = prs.slides.add_slide(blank_slide_layout)
shapes = slide.shapes
# 作品タイトル
title_shape = shapes.title
title_shape.text = str(Sheet.cell(row = i + 2, column = 2).value)
# チーム名
team_shape = slide.placeholders[14]
team_shape.text = 'チーム;' + str(Sheet.cell(row = i + 2, column = 3).value)
# 画像
pic = slide.shapes.add_picture(Sheet.cell(row = i + 2, column = 7).value, Centis(9.7), Centis(9), height = Centis(10))
# 作品概要(日本語)
abst_jp_shape = slide.placeholders[1]
abst_jp_shape.text = ' ' + str(Sheet.cell(row = i + 2, column = 5).value)
# 作品概要(英語)
abst_en_shape = slide.placeholders[15]
abst_en_shape.text = str(Sheet.cell(row = i + 2, column = 6).value)
出来上がったコード
from pptx import Presentation
from pptx.util import Inches
import openpyxl
# 入力部分
Template_File = 'Template.pptx'; # テンプレート元のパワポファイル
Book_File = 'Poster_template.xlsx' # 作品のデータが入ったエクセルファイル
Book_Sheet = 'Template_List' # エクセルファイル内の作品のデータが書いてあるシート名
Output_File = 'OutputPoster.pptx' # 出力するパワポファイル
# センチメートルをPowerPoint上の距離に変換する関数
def Centis(length):
centi = Inches(length / 2.54)
return centi
if __name__ == '__main__':
# ブックを取得
Book = openpyxl.load_workbook(Book_File)
# シートを取得
Sheet = Book[Book_Sheet]
lastRow = Sheet.max_row
# テンプートファイルの取得
prs = Presentation(Template_File)
blank_slide_layout = prs.slide_layouts[0] # page layout
# 全ての作品を書き出すまでループ
for i in range(lastRow - 1):
# 白紙のスライドの追加
slide = prs.slides.add_slide(blank_slide_layout)
shapes = slide.shapes
# 作品タイトル
title_shape = shapes.title
title_shape.text = str(Sheet.cell(row = i + 2, column = 2).value)
# チーム名
team_shape = slide.placeholders[14]
team_shape.text = 'チーム;' + str(Sheet.cell(row = i + 2, column = 3).value)
# 画像
pic = slide.shapes.add_picture(Sheet.cell(row = i + 2, column = 7).value,Centis(9.7),Centis(9),height = Centis(10))
# 作品概要(日本語)
abst_jp_shape = slide.placeholders[1]
abst_jp_shape.text = ' ' + str(Sheet.cell(row = i + 2, column = 5).value)
# 作品概要(英語)
abst_en_shape = slide.placeholders[15]
abst_en_shape.text = str(Sheet.cell(row = i + 2, column = 6).value)
# ファイルの書き出し
prs.save(Output_File)
上記のコードを走らせるとOutputPoster.pptx
が生成される.
トラブル
-
スライド変数.placeholder[引数]
を使うときに引数に何を入れたらいいのか分からなかった- レイアウト中のどのテキストボックスがどのid(引数)に対応しているか分からないので
Template.pptx
に対して下のスクリプトでidをチェックした
- レイアウト中のどのテキストボックスがどのid(引数)に対応しているか分からないので
# スライドレイアウトの要素を確かめるスクリプト
slide = prs.slides.add_slide(prs.slide_layouts[0])
for shape in slide.placeholders:
print('%d %s' % (shape.placeholder_format.idx, shape.name))
- 画像を
スライド変数.placeholder[引数]
でinsert_pictureメソッドを使って挿入しようとしたがうまく行かなかった- 調べたがよく分からなかったので
add_picture
メソッドを使って指定した座標に画像を挿入した
- 調べたがよく分からなかったので
参考にしたサイト
- Pythonでパワポの説明資料(報告書)を生成する
- 全体的な流れについて書いてある
- テンプレートの取り扱いも書いてあった
- Pythonで画像ファイルをパワポに貼る
- 画像ファイルを取り扱うサイト
- python-pptx