LoginSignup
4
5

More than 1 year has passed since last update.

【Python】Excel、Word、PowerPointの図形処理をしたら嵌った話

Last updated at Posted at 2022-04-20

目次

1. はじめに
2. 環境
3. インストールするライブラリ
4. サンプルコード
5. 補足
6. 参考にしたサイト

1. はじめに

PythonでExcelWordPowerPointの図形処理をしたら嵌ったお話

  • Googleで検索だとpython-docxpython-pptxのライブラリが出てくるが、このライブラリだと図形で操作できない機能があるので嵌る(結局、pywin32になる)
  • ExcelWordPowerPointでパスワード(読み取り、書き込み)を設定されてるとダイアログが表示されて処理が停止して嵌る(Googleで検索するとパスワード解析ばかりで、スキップするだけの内容が出てこない)
  • ネットワークドライブ経由のファイルサーバ操作で大量処理するとwin32comでネットワークエラーになり嵌る(win32comエラーはあまり情報がなくて探すのが大変)

2. 環境

  • Windows10 Pro:21H2
  • Microsoft Office 2019
  • Python:3.10.4

3. インストールするライブラリ

  • pywin32:WindowsのAPIを呼び出すライブラリ
pip install pywin32

4. サンプルコード

shape_control.py
import win32com.client
import pythoncom
from abc import ABCMeta, abstractmethod

#main処理
def main():
 #Excel図形操作
 excel = Excel(r"Excelファイルのフルパス")
 excel.shape_control()

 #Word図形操作
 word = Word(r"Wordファイルのフルパス")
 word.shape_control()

 #PowerPoint図形操作
 powerpoint = PowerPoint(r"PowerPointファイルのフルパス")
 powerpoint.shape_control()

#-----------------------------------------------------
# Documentクラス(インターフェース)
#-----------------------------------------------------
class Document(metaclass=ABCMeta):
 @abstractmethod
 def shape_control(self):
  pass
#-----------------------------------------------------
# Excelクラス
#-----------------------------------------------------
class Excel(Document):
 def __init__(self, file_name):
  self.file_name = file_name

 # Excel図形操作
 def shape_control(self):
  pythoncom.CoInitialize()  #win32com開始前にこれを呼び出す
  excel = win32com.client.DispatchEx("Excel.Application") #ファイルサーバなどのリモートの大量処理ではDispatchではなくDispatchExを使う
  excel.Visible = True
  try:
   excel.DisplayAlerts = False
   doc = excel.Workbooks.Open(self.file_name,False ,False ,None ,"dummy@password" ,"dummy@password" ,True) #パスワード有りはダミーパスワードで無視
   sheet = doc.Worksheets(1) #1シート目を対象
   #シート内の図形を全て処理
   for shape in sheet.Shapes:
    try:
     print(shape.TextFrame.Characters().Text.strip())
    except:
     print("Error")
   doc.Close(False) #閉じる
  except:
   print("Error")
  finally:
   excel.DisplayAlerts = True
   excel.Quit()
   del excel
   pythoncom.CoUninitialize() #終了した後はこれを呼び出す

#-----------------------------------------------------
# Wordクラス
#-----------------------------------------------------
class Word(Document):
 def __init__(self, file_name):
  self.file_name = file_name

 # Word図形操作
 def shape_control(self):
  pythoncom.CoInitialize()  #win32com開始前にこれを呼び出す
  word = win32com.client.DispatchEx("Word.Application") #ファイルサーバなどのリモートの大量処理ではDispatchではなくDispatchExを使う
  word.Visible = True
  try:
   word.DisplayAlerts =  False
   doc = word.Documents.Open(self.file_name, False, False, None,"dummy@password", "dummy@password", False, "dummy@password", "dummy@password") #パスワード有りはダミーパスワードで無視する
   #ドキュメント内の図形を全て処理
   for shape in doc.Shapes:
    try:
     print(shape.TextFrame.TextRange.Text.strip())
    except:
     print("Error")
   doc.Close(False) #閉じる
  except:
   print("Error")
  finally:
   word.DisplayAlerts =True
   word.Quit()
   del word
   pythoncom.CoUninitialize() #win32com終了時にこれを呼び出す

#-----------------------------------------------------
# PowerPointクラス
#-----------------------------------------------------
class PowerPoint(Document):
 def __init__(self, file_name):
  self.file_name = file_name

 # PowerPoint図形操作
 def shape_control(self):
  pythoncom.CoInitialize()  #win32com開始前にこれを呼び出す
  powerpoint =win32com.client.DispatchEx("PowerPoint.Application") #ファイルサーバなどのリモートの大量処理ではDispatchではなくDispatchExを使う
  powerpoint.Visible = True
  try:
   doc = powerpoint.Presentations.Open(self.file_name +"::dummy@password::dummy@password") #パスワード有りはダミーパスワードで無視する
   slide = doc.slides[0] #1スライド目を対象
   #ドキュメント内の図形を全て処理
   for shape in slide.shapes:
    try:
     print(shape.TextFrame.TextRange.Text.strip())
    except:
     print("Error")
   doc.Close() #閉じる
  except:
   print("Error")
  finally:
   powerpoint.Quit()
   del powerpoint
   pythoncom.CoUninitialize() #win32com終了時にこれを呼び出す

#main呼び出し
if __name__ == "__main__":
 main()

5. 補足

  • 【情報少なめの嵌まりポイント】
    pywin32(win32com)で頻発するエラー

Traceback (most recent call last):
File "C:\Python39\lib\site-packages\win32com\client\dynamic.py", line 86, in _GetGoodDispatch
IDispatch = pythoncom.connect(IDispatch)
pywintypes.com_error: (-2147221021, '操作を利用できません', None, None)
IDispatch = pythoncom.CoCreateInstance(
pywintypes.com_error: (-2146959355, 'サーバーの実行に失敗しました', None, None)

Traceback (most recent call last):
File "C:\Python39\lib\site-packages\win32com\client\dynamic.py", line 707, in setattr
raise AttributeError(
AttributeError: Property 'Excel.Application.Visible' can not be set.

6. 参考にしたサイト

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