【PythonでPowerPointを操る】python-pptxの段落・テキスト編集を徹底的にこだわる

スポンサーリンク
Python外部ライブラリ(python-pptx)テキスト編集 Python

今回も引き続き、Pythonから「PowerPoint」を操作する機能を供する「python-pptx」ライブラリを紹介していきます。

前回の記事では「pytnon-pptxの導入~ファイル作成」「スライドを追加する」「プレースフォルダ

にコンテンツを挿入する」といった基本操作について解説してきました。

前回の記事はこちらになります、重複する内容は割愛していますので一読して頂くことをお勧めします。

また、その他連載記事へのリンクは以下の通りです。

< 連載目次 >
  • 【連載1回目】ライブラリの導入とファイルとスライドの作成方法について ->>
  • 【連載2回目】段落にドキュメントを挿入しやフォントなどを設定する方法 ->>
  • 【連載3回目】スライドにグラフ(散布図や折れ線グラフ)を挿入する ->>
  • 【連載4回目】スライドにテーブル (表)を挿入する ->>
  • 【連載5回目】スライドに図形(オートシェイプ・画像・ボックス)を挿入する ->>


さて、連載2回目となる今回の記事では、タイトル」「見出し」「本文・箇条書きのテキストを設定や編集にこだわって解説します。

プレゼンテーション資料を作るうえ「テキスト」の存在はやはり重要で、「理解しやすさ」「訴求性」に関係します。

前回の記事でもプレースフォルダ(コンテンツの雛形)にテキストを設定する方法について触れましたが、「フォント」「段落」「インデント」などさらに細かく編集・設定することもできます。

それには「TextFrameオブジェクト」やそれに関連するオブジェクト・メソッド(プロパティ)の概要を知る必要があります。今回は、このTextFrameオブジェクトに関して深堀りしてテキスト編集にこだわります。

この記事を読むことで次のことがわかるようになりますので最後までお付き合い下さい。

この記事で学べること
  • テキストを管理するTextFrameオブジェクトと配下の関連オブジェクトの関係について理解する
  • Paragraphオブジェクトにより段落分けをして複数行の文字列を設定する
  • Runオブジェクトにより文字色や字下げなど高度な設定をする

それでは、次節より各オブジェクトの詳細について解説をしていきます。

なお、本記事内で紹介する各種クラスや関数などの使い方は一例です。省略可能なオプション引数などについては割愛していますので、詳細や不明点などは必要に応じて下記「公式ドキュメント」を参照してください。

python-pptx 公式ドキュメント(API Document)

https://openpyxl.readthedocs.io/en/stable/
スポンサーリンク

1.スライドのテキストを管理するTextFrameオブジェクト

本節では、プレゼンテーションにpython-pptxを使ってテキストを設定するうえで、欠かすことのできない「TextFrame」というクラスについて解説してます。

「TextFrame」とは何なのか?という概要から、オブジェクトの取得・テキストの設定までを取り上げていきます。

1.1 TextFrame(テキストフレーム)とは

先にも触れましたが、python-pptxでは、テキスト(文字列)を「TextFrame」というフレームワーク(枠組み)の中に配置していくことになります。

PowerPointには図1のように、プレースフォルダ(TITLE, BODY、、等)<内部リンク>、図形(AutoShape)、グラフ、テーブル(表)などといったさまざまな要素(※)によって構成されています。(※ 正確にはShapeオブジェクトとして扱います)

Python_PowerPointの構成要素_rev0.2
図1 PowerPointを構成する要素(再掲)

これら、一つ一つの要素にはテキストを挿入することができる領域が用意されていて、この領域が「TextFrame」ということになります。

普段はあまり意識することなく、これらの要素にテキストを入力していると思いますが、プログラムで操作する際には必ずこのTextFrame(オブジェクト)を経由することになります。

Python_TextFrameの説明_rev0.2
図2 スライドの構成要素がもつTextFrame領域

さらに、このTextFrameの中身について掘り下げていきます。

TextFrameがテキストを格納するフレームであるならば、その中には段落があり文字(単語)がありといったぐあいに、関連する配下のオブジェクトの集合体で構成されています。

それによって、インデント(字下げ)やフォントの書式など、細かいテキスト設定に対応することが可能となっているのです。

たとえば、次の3つスタイルをもつテキストを設定したいとします。

  1. 1行分(1つの段落)の文字列を設定するだけの場合
  2. 段落分けをして複数行(複数段落)の文字列を設定する場合
  3. 文字色や字下げなど高度な設定をしたい場合

➀②➂のすべてを、TextFrameオブジェクトだけで対応できるわけではなく、さらに配下の関連オブジェクトを繋ぎ合わせる必要があります。(図3)

Python_テキスト設定に必要なオブジェクト
図3 テキストの編集スタイルにおけるオブジェクトの使い分け

実際のスライド上での各オブジェクトの相対関係を図示したのが図4となります。テキストボックス(Shapeオブジェクト)の中に、文字列を設定している例です。

図のように、各Shapeオブジェクトごとに、独立したTextFrameオブジェクトを一つずつ持ち、その中に必要分の段落(Paragraphオブジェクト)が配置され、さらに各文字単位にはRunオブジェクトが割り当てられるといった階層構造となります。図4 スライドを構成するテキスト関連のオブジェクト

オブジェクトの階層構造
図4 スライドを構成するテキスト関連のオブジェクト
  • テキストボックス(Shapeオブジェクト)・・・赤の枠線
  • テキストフレーム(TextFrameオブジェクト)・・・水色の枠線
  • 段落(Paragraphオブジェクト)・・・緑の枠線
  • 個別文字(Runオブジェクト)・・・青の枠線

それでは、次節より各オブジェクトの詳細と関連するメソッド属性について解説をしていきます。

1.2 TextFrameオブジェクトの取得と設定

テキストの管理領域となるTextFrameオブジェクトは実際に文字を挿入したい、テキストボックスや図形などのShapeオブジェクト(※) 配下の「text_frameプロパティ」から取得できます。

(※Shapeオブジェクトは別記事で詳しく解説します)

TextFrameオブジェクト

Shapeオブジェクト.text_frameプロパティ


戻り値: TextFrameオブジェクト

TextFrameオブジェクトの主要なメソッドやプロパティには以下のようなものがあります。

TextFrameオブジェクト.機能その他詳細
textプロパティテキストフレームに文字列
を設定/取得する
autosizeプロパティ文字のサイズを自動調整
する場合の指定
MSO_AUTO_SIZEクラス
・.NONE(自動調整しない)
・.SHAPE_TO_FIT_TEXT(Frameサイズをテキストに合わせる)
・.TEXT_TO_FIT_SHAPE(テキストをFrameサイズに合わせる)
word_wrapプロパティ文字の折り返しの有無を
設定/取得する
・折り返す場合はTrueを指定
・デフォルト(折り返さない)はFalse
vertical_anchorプロパティ文字の上下位置MSO_VERTICAL_ANCHORクラス
・.TOP(上揃え)
・.MIDDLE(中央揃え)
・.BOTTOM(下揃え)
margin_top(bottom)プロパティ上下の余白を調整する
margin_left(right)プロパティ左右の余白を調整する
表1 TextFrameオブジェクト配下の主要プロパティ

テキストをフレームに設定するには、textプロパティを使います。文字サイズはTextFrame上での直接指定はできず、autosizeプロパティによる自動サイズ調整にて対応します。文字サイズはこのあと紹介する段落(Paragraph)や文字(Run)のレイヤーで指定できます。

このほか、フレーム内の文字位置をvertical_anchorプロパティで、フレームの余白の調整をmargin_*プロパティで行います。(図5)

Python_TextFrame_marginの解説
図5 margin_*プロパティによる位置調整

SAMPLE➀

ここでTextFrameオブジェクトに関連した具体例を紹介します。

コードの概要は、スライド内の図形などのShapeオブジェクトの素性を調べます。そして、各ShapeオブジェクトのTextFrameにテキストを設定します。フレーム内の文字のサイズや折り返しは有効とします。<List1>

from pptx import Presentation
from pptx.enum.text import MSO_AUTO_SIZE   # MOS_AUTO_SIZEクラスのインポート

prs = Presentation('0218_Blog.pptx')   # 既存のファイルを読み込む

sld0 = prs.slides[0]

for shape in sld0.shapes:           # スライド中の要素を抽出、種類を表示
    print(shape.name)               # >> タイトル1、テキストボックス3、矢印:右4、吹き出し:円形12
    if not shape.has_text_frame:    # shapeオブジェクトにTextFrameが含まれているか確認
        continue
        
    textFrame = shape.text_frame                         # 各種ShapeオブジェクトからTextFrameを取得
    textFrame.text = 'Pythonのサンプルプログラムです'      # TextFrameにテキストを設定
    textFrame.autosize = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE # TextFrameのテキストサイズを自動調整
    textFrame.word_wrap = True                           #TextFrameのテキストの自動折り返しを有効に設定
    
prs.save('0218_Blog_out.pptx')

ポイントを解説します。

10,11行目:【TextFrameの包含を確認】

スライド上のすべての図形(Shape)に、テキストを挿入できるとは限りません。もし、テキスト設定ができないShapeオブジェクトからTextFrameを取得しようとしてしまうとエラーが発出されます。そのため、すべてのShapeオブジェクトに対して、has_text_frameプロパティでTextFrameの包含の有無をまず確認します。

16,17行目:【サイズと折り返しの設定】

図形には固有のフレームサイズが存在します。何も考えずにテキストを設定すると、途中でテキストが途切れたり、上手く表示できないことがあります。

そこで、autosizeプロパティでフレーム内に収まる文字サイズに自動調整する設定をし、

word_wrapプロパティを“True”とし文字列の折り返しを有効にしています。

コードの実行結果は以下のようになりました。

「タイトルのプレースフォルダ」「テキストボックス」「図形」に対して、「Pythonのサンプルプログラムです」というテキストが設定されました。また、各Shapeオブジェクトのフレームに収まるサイズや折り返し設定が反映されています。

TextFrameオブジェクトのサンプルプログラム実行例
図6 List1の実行結果

2. 段落(Paragraphオブジェクト)を追加する

Python_基本文法_内包表記

TextFrameオブジェクトの中で段落を管理するユニットが、Paragraphオブジェクトとなります。TextFrameオブジェクトには最低1個の段落がデフォルトで存在しているので、複数行の段落分けされたテキストを設定する場合は、Paragraphを追加します。

2.1 Paragraphオブジェクトの追加と取得

TextFrameオブジェクトに段落(Paragraphオブジェクト)を追加するには、add_paragraph()メソッドを取得にはparagraphsプロパティを使います。

通常、段落は複数持つことを前提としますので、TextFrameオブジェクト内ではコレクション(Paragraphオブジェクトを要素としたイテラブルなオブジェクト)として管理されています。

Paragraph(段落)オブジェクトの取得

TextFrameオブジェクト.add_paragraph()

戻り値:なし(Paragraphオブジェクトのコレクションに追加される)


TextFrameオブジェクト.paragraphsプロパティ

戻り値:Paragraphオブジェクトのコレクション(イテラブル)


TextFrameオブジェクト.paragraphs[index]プロパティ

引数:inex:コレクション要素のインデックス

戻り値:Paragraphオブジェクト

2.2 Paragraphオブジェクトの関連メソッドとプロパティ

Paragraphオブジェクト配下には、主として次のようなメソッド・プロパティが用意され、段落レイヤーに対する操作が可能となります。

Paragraphオブジェクト機能の説明その他詳細
textプロパティ段落に文字列を設定/取得する
levelプロパティ段落の字下げレベルを
設定/取得する
・0~8の範囲でレベルを指定する
fontプロパティフォントを設定する
(Fontオブジェクトを取得)
Fontオブジェクト関連属性
bold(太字),size(文字サイズ),italic(斜体),color(文字色)
alignmentプロパティ文字列の水平位置の指定PP_ALIGNクラス
・.CENTER(中央)
・.LEFT(左揃え)
・.RIGHT(右揃え)
line_spacingプロパティ行間の高さの指定pt(ポイント)などで指定
space_after(before)プロパティ前後の段落の間隔pt(ポイント)などで指定
表2 Paragraphオブジェクトの主要属性

段落以降のレイヤーからはfontプロパティにてフォントの設定を行うことができます。また、段落の字下げを9段階で指定することができるlevelプロパティ、それから、行間や段落間の間隔を指定するプロパティがあります。(図7)

Python_Paragraphオブジェクトの属性解説rev0.1
図7 Paragraphオブジェクトの属性

SAMPLE②

それでは、Paragraphレイヤでの操作例をサンプルコードを使って確認してみます。

コードの概要は、スライド上のShapeオブジェクト(テキストボックス)に段落(Paragraphオブジェクト)を追加して、表2の主要属性の効果を確認する内容になります。

from pptx import Presentation
from pptx.enum.text import PP_ALIGN       # 段落の水平位置のEnume
from pptx.enum.dml import MSO_THEME_COLOR # テーマカラーのEnume
from pptx.util import Pt                  # 単位の定義(ポイント)

prs = Presentation("Paragraph_Sample.pptx")  # pptxの読込み
sld0 = prs.slides[0]


# スライド上のShapeオブジェクト(テキストボックス)の属性情報の調査
# has_text_frame属性が「True」でTextFrameオブジェクトの包含が可能
for sp in sld0.shapes:
    print(sp.shape_type, sp.name, sp.has_text_frame)
    # >> TEXT_BOX (17) テキスト ボックス 1 True
    # >> TEXT_BOX (17) テキスト ボックス 2 True
    # >> TEXT_BOX (17) テキスト ボックス 3 True
    # >> TEXT_BOX (17) テキスト ボックス 4 True


# TextFrameオブジェクトに段落(Paragraphオブジェクト)を2つ追加する
for dumy in range(2):
    sld0.shapes[0].text_frame.add_paragraph()
    sld0.shapes[1].text_frame.add_paragraph()
    sld0.shapes[2].text_frame.add_paragraph()
    sld0.shapes[3].text_frame.add_paragraph()


# 段落の字下げ調整--------------------------------------------------------------------
paras = sld0.shapes[0].text_frame.paragraphs

for i, para in enumerate(paras, 0):
    para.text = "段落ごとに字下げを指定する"
    para.level = i


# 水平位置調整--------------------------------------------------------------------

List_PP_ALIGN = [PP_ALIGN.LEFT, PP_ALIGN.CENTER, PP_ALIGN.RIGHT]
paras = sld0.shapes[1].text_frame.paragraphs

for i, para in enumerate(paras, 0):
    para.text = "段落ごとの水平位置(左/中央/右揃え)を指定する"
    para.alignment = List_PP_ALIGN[i]


# 文字列のフォントの設定----------------------------------------------------------

List_MSO_THEME_COLOR = [MSO_THEME_COLOR.ACCENT_1, MSO_THEME_COLOR.ACCENT_2, MSO_THEME_COLOR.ACCENT_6]
paras = sld0.shapes[2].text_frame.paragraphs

for i, para in enumerate(paras, 0):
    para.text = "段落レベルで文字列のフォントを調整"
    para.font.color.theme_color = List_MSO_THEME_COLOR[i]  # フォントの色
    para.font.bold = True  # フォントの大きさ


# 段落間の間隔調整----------------------------------------------------------------

paras = sld0.shapes[3].text_frame.paragraphs
for para in paras:
    para.text = "段落間の間隔(space_after)のPt(15)で調整"
    para.space_after = Pt(15)


prs.save('Paragraph_Sample_Apply.pptx')  # pptxの保存

ポイントを解説します。

21~25行目:【各TextFrameに段落を2つ追加】

Forループによって、各Shapeオブジェクトに段落を2つずつ追加します。追加には、TextFrameオブジェクトのadd_paragraph()メソッドを使います。

また、先述したとおり、Shapeオブジェクトには、はじめから1個の段落を含んでいるので、追加したい段落数-1個のループで済みます。

29~33行目:【段落の字下げ】

ParagraphのコレクションをFor文とEnumerate関数で展開します。個々の段落に対して、テキストと段落レベルをlevelプロパティで設定します。設定値はEnumerate関数で得た、インデックスを利用します。

以降の処理も同様の手順でインデックスを取得します。

38~43行目:【水平揃え】

各段落の水平位置揃えは、alignmentプロパティで設定します。設定値は、PP_ALIGNクラスのEnumeオプションをLEFT(左揃え)、CENTER(中央揃え)、RIGHT(右揃え)のように指定します。

48~54行目:【フォントの設定】

段落全体のフォントの設定は、fontプロパティを経由して各詳細設定を行います。ここでは、文字色をMSO_THEME_COLORクラスのEnumeオプションで設定し、フォントを太字にしています。Fontオブジェクトに関しては後述します。

最後に、段落間のスペース調整をspace_afterプロパティで指定します。

今回は、15ポイントの間隔を空けるように調整しています。


コードの実行結果は以下のようになりました。

段落レベルの「字下げ」「水平位置揃え」「フォント設定」「間隔」の各属性が反映されました。(図8)

Python_Paragraph_List2実行結果_rev0.1
図8 List2の実行結果

3. 文字(Runオブジェクト)の設定

段落(Paragraphオブジェクト)内の個々の文字(単語)を管理するユニットが、Runオブジェクトになります。Runオブジェクトとして個別管理することで、文字ごとにフォントの書式を指定できるようになります。

3.1 Runオブジェクトの追加と取得

Paragraphオブジェクトに単語(Runオブジェクト)を追加するには、add_run()メソッドを使います。また、取得するにはrunsプロパティを使います。

通常、テキストは複数の単語の集合体で構成されますので、Runオブジェクトは段落の中で、コレクション(Runオブジェクトを要素としたイテラブルなオブジェクト)としてまとめて管理されています。

Runオブジェクトの取得・設定

Paragraphオブジェクト.add_run()メソッド

戻り値: Runオブジェクト(Runオブジェクトのコレクションにも追加される)


Paragraphオブジェクト.runsプロパティ

戻り値: Runオブジェクトのコレクション(イテラブル)


Paragraphオブジェクト.runs[index]

引数:inex:要素のインデックス

戻り値:Runオブジェクト インデックス指定で特定のRunオブジェクトを取得

ここまでの、各オブジェクトの親子関係と主要メソッド・プロパティについて整理すると次のようになります。(図9)

TextFrameの階層構造
図9 テキスト設定に関連するオブジェクトの階層構造

3.2 Runオブジェクトの関連プロパティ

Runオブジェクト配下には、次のようなプロパティが用意され、文字単位に対する操作が可能です。

基本的には、文字textプロパティと、フォントfontプロパティの設定ができる属性が提供されます。

Runオブジェクト機能その他詳細
textプロパティ文字を設定/取得する
fontプロパティ文字にフォントを設定する、
Fontオブジェクトを取得
Fontオブジェクト関連属性
bold(太字),size(文字サイズ),italic(斜体),color(文字色)
hyperlink.addressプロパティハイパーリンクを割り当てるWebサイトのURLなど
表3 Runオブジェクトの属性

SAMPLE➂

Runオブジェクトを使って、テキストを追加・編集する例をサンプルコードで確認します。

コードの概要は、段落内のテキストをRunオブジェクトで細かく設定し、文字色を指定するといったものです。<List3>

from pptx import Presentation
from pptx.dml.color import RGBColor

prs = Presentation()

#------------------------------------------------------------------------------------------------------
title_slide_layout = prs.slide_layouts[1]      	# "タイトルとコンテンツ"のレイアウトオブジェクトを取得
sld0 = prs.slides.add_slide(title_slide_layout) # 新しいスライドを追加(タイトルとコンテンツ)

for s in sld0.shapes:   			# スライド中の要素を抽出、種類を表示
    print(s.name)        			# >> Title 1 Content Placeholder 2

    
sld0.shapes[0].text = 'タイトルの文字色を変更します'
pg = sld0.shapes[0].text_frame.paragraphs[0]
rn = pg.runs[0]     			# 段落(paragraphオブジェクト)を操作するために、runオブジェクトを取得する

rn.font.color.rgb = RGBColor(50, 185, 20)    	# runオブジェクトのfont.color.rgbプロパティに文字色を指定

#------------------------------------------------------------------------------------------------------
tf = sld0.shapes[0].text_frame
tf.add_paragraph()                       	# 段落(paragraphオブジェクト)を追加する
pg = sld0.shapes[0].text_frame.paragraphs[1]   	# 追加した段落を取得

rn0 = pg.add_run()                    		# runオブジェクトをコレクションに追加
rn0.text = '文字列1'                  		# 段落に文字を設定
rn0.font.color.rgb = RGBColor(255, 0, 0) 	# 段落文字に色(赤)を設定

rn1 = pg.add_run()
rn1.text = '文字列2'
rn1.font.color.rgb = RGBColor(0, 255, 0) 		# 段落文字に色(緑)を設定

rn2 = pg.add_run()
rn2.text = '文字列3'
rn2.font.color.rgb = RGBColor(0, 0, 255)  	# 段落文字に色(青)を設定

prs.save('Blog_テキストに色付け_段落付け.pptx') 

ポイントを解説します。

14~16行目: 【Runオブジェクトの取得】

14行目で、新規プレースフォルダ“TITLE”(Shapeオブジェクト)に対してtextプロパティで直接、文字列を設定しています。

実はこの時点で、TextFrame、Paragraphはもとより、Runオブジェクトまでの参照ができます。追加した文字(列)は一つですので、段落内のRunオブジェクトは1つ、つまりruns[0]でアクセスできます。

18行目:【文字列に書式を設定】

Runオブジェクトのfontプロパティにて、フォントの書式を適用します。

この例では、colorプロパティを繋げて文字色を設定しています。

段落ごと、書式設定するのではなく文字ごとに書式を適用できる点がポイントです。

25~27行目:【文字列を追加】

add_run()メソッドでRunオブジェクトを追加・取得し、今度は「(Runの)textプロパティ」にて文字列を追記していきます。(29~31, 33~35行目も同様にして文字列を追記します)


コードの実行結果は以下のようになりました。

文字(列)レベルでのフォントの書式設定が可能となりました。(図10)

python-pptxの使い方_文字列の着色_段下げ
図10 List3の実行結果

3.3 フォントの書式設定について

ここで、段落や文字のレイヤのfontプロパティで取得・設定できるFontオブジェクトの関連プロパティについてまとめます。

Fontオブジェクト機能その他・詳細
color.rgbプロパティ文字色の設定(RGB)RGBColorクラス】 例)RGBColor(255, 255, 255)
color.theme_colorプロパティ文字色の設定(テーマカラー)MSO_THEME_COLORクラス】のオプション
italicプロパティ斜体文字の設定True(有効)/False(無効)
boldプロパティ太文字の設定True(有効)/False(無効)
nameプロパティフォント名の設定/取得例) ‘Calibri’
sizeプロパティ文字サイズの設定/取得Pt(ポイント)などで指定
underlineプロパティ下線の設定True(有効)/False(無効)または、
MSO_UNDERLINEクラス】のオプション
表4 Fontオブジェクトの属性

一通りのフォント書式の設定ができます。上記のほか「fillプロパティ」による塗り潰し効果も提供されているようですが、適用効果がないため割愛します。

また、フォントの書式は、特に指定しなければ、上位オブジェクトから継承されます。

例えば、TextFrameオブジェクト→Paragraphオブジェクト→Runオブジェクトの順番に継承されますが、現在のレイヤでフォント設定をすることで書式を更新できます。

4. まとめ

いかがでしたでしょうか?

今回はpython-pptxライブラリ」を使って、スライド上のテキストを編集する方法について解説しました。

最後に、今回の記事内容をまとめておきましょう。

➀. Python-pptxでは、テキストをフレーム領域(TextFrameオブジェクト)や段落(Paragraphオブジェクト)という単位で管理している。

➁. 新たな文章を追加するには、Paragraphオブジェクトを取得・追加し、配下の属性でテキスト設定、体裁を整える。

➂. 文字単位での編集を行うには、さらにRunオブジェクトを追加・取得する。文字(単語)の追記やフォントの書式を設定ができる。

先にも述べた通り、図や表をメインとしたPowerPointの資料づくりにおいても、必ずこのテキスト編集作業は必要となります。本記事の内容が少しでもお役に立てば幸いです。


次回の記事は、スライドにグラフを挿入する方法について解説をしていきます。

グラフを活用して数値データを可視化することで、より説得力のある資料に仕上げることができます。

ぜひ、次回の記事も参考にして頂けましたら幸いです。リンク先はこちらになります。↓

最後までお読み頂きありがとうございました。

タイトルとURLをコピーしました