###はじめに
PPTXから画像ファイルへの変換について調べたので、その備忘録として記載します。
Windows ApplicationをPythonで使うには、comtypesまたは、pywin32をインストールする必要があります。また、操作する(今回はPowerpoint)アプリケーションもインストールされている必要があります。
COMという言葉が出てきますが、Component Object Model (COM)のことのようです。communication port(COMポート)とは違います。
###参考
Windows ApplicationをPythonで使うには
(1)PowerpointをPythonで使うための検討
(2)Automating Windows Applications Using COM - Practical ...
(3)PythonでExcelを操作してみる
(4)win32com-PyWin32(Python for Windows extensions)
Powerpointを画像に出力するには
(5)Automate the export of PowerPoint files to Images
(6) PythonでPowerPointの各ページを画像ファイルにする
エラー対応
comtypes
(7)AttributeError: module 'comtypes.gen.Word' has no ... - GitHub
Dispatch()とDispatchEx()の違い
(8)[b-PAC SDKをPython + pywin32(win32com)で操作してみた
###環境と環境構築
Win10
Anaconda
Python3.7
Microsoft Office 2013 (PowerPoint含む)
####モジュールインストール
同じ機能を提供しているモジュールとして、comtypesとpywin32の2つがありますが、今のところpywin32の方を使っています。
Condaでインストールするならば
conda install -c conda-forge comtypes
conda install -c conda-forge pywin32
conda-forgeからインストールできます。
comtypesをインストールするとpywin32もインストールされるかもしれません。
pipでインストールするならば
pip install comtypes
pip install pywin32
私の環境でのインストール状況(conda listの結果)
comtypes 1.1.7 py37hc8dfbb8_1001 conda-forge
pywin32 227 py37hfa6e2cd_0 conda-forge
###作成コード
参考(6) のPythonでPowerPointの各ページを画像ファイルにするを参考にコードを作成しました。題材として、以下のようなPowerPointファイル(Qiita_test.pptx)を作成しました。PPTXデータは添付しませんので、データはご自身で作成してください。
#####ホルダー構成
dataホルダー(この中にPPTXファイルを入れます)
imageホルダー(画像になったものがこのホルダーに入ります)
test.py(コードが書かれたファイル)
#####コードと解説
from pathlib import Path
import win32com.client
def export_pptx_img(file_name, output_dir, image_name='slide', fmt="png"):
"""
pptxファイルを画像ファイルに変換する関数
file_name: file name -> str or pathlib object
output_dir: output dir -> str or pathlib object
image_name:output slide name ->str
fmt = "png" or "jpg" or "bmp"
"""
#Pathlib objectに変換、絶対パスに変更
f_path = Path(file_name)
f_path_abs =f_path.resolve()
o_path = Path(output_dir)
o_path_abs = o_path.resolve()
# application = comtypes.client.CreateObject("Powerpoint.Application")
# AttributeError: module 'comtypes.gen.PowerPoint' has no attribute '_Application'
# エラーが出るためwin32comに変更しています
# DispatchExとDispatchの違い参照
application = win32com.client.DispatchEx("Powerpoint.Application")
# Trueにしないとうまく動かない
application.Visible = True
# file Path は絶対パスでないとエラーになる
# pathlib objectは受け付けないので文字列に変更
presentation = application.Presentations.open(str(f_path_abs))
presentation.Export(str(o_path_abs), FilterName=fmt)
presentation.close()
application.quit()
# スライドをリネームします
# globでファイルを見つけてリストにします
rename_list = list(o_path.glob('スライド?.{}'.format(fmt.upper())))
for i, file in enumerate(rename_list):
# 新しい名前
name_format = '{}_{:02d}.{}'.format(image_name,i+1,fmt.upper())
name_path = Path(file.parent/name_format)
# print(name_path)
if name_path.exists() == False:
# # 存在しないことを確認
# print("is_exists?:", name_path.exists()) # False
file.replace(name_path)
else:
print("Rename is Failure")
if __name__ == '__main__':
input_path = Path('./data')
output_path = Path('./image')
input_file_lists = list(input_path.glob('*'))
# 注:リストオブジェクトが帰って来ます
print(input_file_lists[0])
export_pptx_img(input_file_lists[0],output_path,image_name='test1',fmt="png")
参考にしたコードではos.path
オブジェクトを使っていますが、pathlib
オブジェクトに変更しています。
application= comtypes.client.CreateObject("Powerpoint.Application")
のインスタンスを作るところで
AttributeError: module 'comtypes.gen.PowerPoint' has no attribute '_Application'
のようなエラーが出るため、以下のように書き換えています(参考(7))。
application = win32com.client.DispatchEx("Powerpoint.Application")
参考(8)にあるDispatchEx
とDispatch
の違いよりDispatchEx
にしています。
#####実行
実行すると、一度PowerPointのアプリケーションが開きます。そして処理が終わると閉じます。
最終的imageホルダー内にtest1とリネームされたファイルが作成されます。