LoginSignup
4
4

More than 3 years have passed since last update.

[Python] 既存のPowerpointのテキストをフォーマットを変えずに変更する python-pptx

Last updated at Posted at 2021-03-06

python-pptxでPowerPointのレポートを操作したい時、事前にテンプレートを用意しておいて文字のフォーマットはそのままで内容の一部を変更したいことがあります。思ったよりも面倒でしたので、こちらの備忘録として残します。

動作を確認するために、以下のようにフォーマットされた文字列のあるPPTファイルの一部(「。。。」)を今日の日付(2021/3/6)で変換するコードを書いてみました。元の文字は影をつけたり、下線をつけたりと、いろいろと装飾してあります。コードを実施される方は"元のファイル.pptx"というファイルを作ってコードと同じディレクトリに保存してください。

スクリーンショット 2021-03-06 122130.png

なお、既存の文字を置き換える方法は、python-pptxの作者であるScannyさんがこちらで説明していますので、その関数(モジュール)はそのまま利用します。
https://github.com/scanny/python-pptx/issues/285
replace_paragraph_text_retaining_initial_formattingという名前の長い関数がそうです。

私が工夫したポイントとしては、元のファイルの中から該当するparagraphオブジェクトを探すところです。このオブジェクトの関係がいろいろとややこしいのですが、こちらを参考にさせていただきました。この階層のどちらが上だったか、ぜんぜん記憶することができません。。。
スクリーンショット 2021-03-08 130142.png


import pptx, re
from pptx.util import Cm, Pt, Inches

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p # the lxml element containing the <a:p> paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
        paragraph.runs[0].text = new_text

prs = pptx.Presentation("元のファイル.pptx")
slide=prs.slides[0] #先頭のページを選択

for shp in slide.shapes:

    if shp.has_text_frame:
        if "日付は" in shp.text: #変更する文字列の一部でマッチさせる
            new_text=re.sub('。。。', '2021年3月6日', shp.text) #置き換え
            replace_paragraph_text_retaining_initial_formatting(shp.text_frame.paragraphs[0], new_text)

prs.save('変更後のファイル.pptx')

4
4
0

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
4
4