Pythonでパワポのスライドショーを操作

やりたいこと

Pythonで、ネットワーク経由でのHTTPアクセスに応じて、PowerPointのスライドショーを操作する。
OSはWindows限定でよい。

ライブラリのインストール

pip install flask
pip install pywin32

スクリプト

from flask import Flask
import pythoncom
import win32com.client

app = Flask(__name__)

# PowerPointアプリケーションを取得または起動
def get_ppt():
    ppt = win32com.client.Dispatch("PowerPoint.Application")
    ppt.Visible = True
    return ppt

# アクティブなプレゼンテーションを取得
def get_active_presentation(ppt):
    if ppt.Presentations.Count == 0:
        return None
    return ppt.ActivePresentation

# スライドショーのビューを取得
def get_slideshow_view(ppt, pres):
    if ppt.SlideShowWindows.Count == 0:
        return None
    return pres.SlideShowWindow.View

# 各コマンドに対応する処理
@app.route("/<action>")
def slideshow_control(action):
    pythoncom.CoInitialize()
    ppt = get_ppt()
    pres = get_active_presentation(ppt)
    if pres is None:
        return "No active presentation"

    # スライドショーの開始
    if action == "start":
        if ppt.SlideShowWindows.Count == 0:
            pres.SlideShowSettings.Run()
            return "Slideshow started"
        else:
            return "Slideshow is already running"
    # その他のコマンド
    else:
        view = get_slideshow_view(ppt, pres)
        if view is None:
            return "No slideshow running"
        # 次のスライド
        if action == "next":
            view.Next()
            return "Next slide"
        # 前のスライド
        elif action == "prev":
            view.Previous()
            return "Previous slide"
        # スライドショーの終了
        elif action == "end":
            view.Exit()
            return "Slideshow ended"
        # ブラックアウト
        elif action == "black":
            view.State = 3
            return "Blackout"
        # ブラックアウト解除
        elif action == "resume":
            view.State = 1
            return "Resume slideshow"
        # ページ番号とページ数の取得
        elif action == "pageinfo":
            slide = view.Slide
            page_number = slide.SlideIndex
            total_pages = pres.Slides.Count
            return f"{page_number}/{total_pages}"
        # ノートの取得
        elif action == "note":
            note_page = view.Slide.NotesPage
            try:
                # 通常、Placeholders(2)がノートテキスト
                note_text = note_page.Shapes.Placeholders(2).TextFrame.TextRange.Text
                # 改行コードをCRLFに変換
                note_text = note_text.replace('\r\n', '\n').replace('\r', '\n').replace('\n', '\r\n')
            except Exception:
                note_text = ""
            return note_text
        else:
            return f"Unknown action: {action}" 

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

動作確認

上記のスクリプトを実行し、ローカルのコマンドプロンプトで下記を実行。

curl http://127.0.0.1:5000/start
curl http://127.0.0.1:5000/next
curl http://127.0.0.1:5000/prev
curl http://127.0.0.1:5000/black
curl http://127.0.0.1:5000/resume
curl http://127.0.0.1:5000/pageinfo
curl http://127.0.0.1:5000/note
curl http://127.0.0.1:5000/end

関連記事