home changes contents help options

222:Windowsアプリを操る

多くのWindowsアプリケーションがCOMインターフェースというのを提供しています。pythonからCOMを使うとWindwosアプリケーションを自動操縦できます。例えば、あるフォルダの下に何百個もワードファイルがあって、そこに自宅の住所が書いてあったとします。引越ししたときにそれを全部書き換えるのは大変ですよね。pythonを使えば、ファイルのリストを取って一つ一つ開いて書き換えるということが自動操縦でできるのです。それも多分15行くらいのプログラムでです。これってすごいことですよね。

pythonからCOMコンポーネントにアクセスするには Windows用拡張モジュール を使います。当然ですが、 Widnows用のPython とかEXCELやWordもいります。 予めダウンロードしてインストールしておいて下さい。

Rubyが題材ですが、COMについて大変丁寧でわかりやすい解説があります。

http://jp.rubyist.net/magazine/?0003-Win32OLE

Wordの例

次の例は、Wordのファイルからテキストだけを抽出するものです。Windows2000+Office2000で実験してあります。 苦労したところは、オブジェクトやメソッドの大文字小文字です。documentsでは駄目でDocumentsと頭を大文字にしなくてなりません。 それと、doc.Close()も()がいります。

Wordのヘルプを見ると、VBAの使い方は載っていますが、COMについては記述が無いようです。大体VBAと同じなので、トライアンドエラーでやるしかないのかもしれません。

 import win32com.client,os,string
 wordApp=win32com.client.Dispatch("Word.Application")  ##Win32COM object
 wordApp.Visible=1                                     ##Make it visible

 fname='C:/Documents and Settings/Administrator/My Documents/umi.doc'

 doc=wordApp.Documents.Open(os.path.normpath(fname))  ##doc object フルパスが必要。Windowsのファイル区切り。
 for s in doc.Sentences:                              ##get sentences センテンスはリストになっている。
     ##print str(s)
     print string.rstrip(str(s))           ##COMオブジェクトを文字列に直し、右端の改行などを除く
 doc.Close()                     ##Close doc objects
 wordApp.Quit()                                       ##Close word objects

EXCELの例

http://scienceoss.com/read-excel-files-from-python/

次の例は、tempディレクトリのリストを取って、その絶対パスとサイズ、最終更新時刻をEXCELに貼っていくというもの。実行するとEXCELが開き、シートが追加され、そこに下方向にデータが入っていく。

 import win32com.client,os,time
 xlApp=win32com.client.Dispatch("Excel.Application")
 xlApp.Visible=1

 xlApp.WorkBooks.Add()
 sheet=xlApp.Sheets(1)
 path='c:/temp'
 filelist=os.listdir(path)
 #print filelist
 for i in range(len(filelist)):
     item=os.path.join(os.path.normpath(path),filelist[i])
     #print item
     #print i+1,os.path.basename(item),os.stat(item).st_size,time.ctime(os.stat(item).st_mtime)
     sheet.Cells(i+1, 1).Value=item
     sheet.Cells(i+1,2).Value=os.stat(item).st_size
     sheet.Cells(i+1,3).Value=time.ctime(os.stat(item).st_mtime)

PythonでExcelの初歩的な操作 という記事を発見。

 # -*- coding: cp932 -*-
 import win32com.client

 def booksdict(Workbooks):
        d ={}
        for book in Workbooks:
                d[book.Name]=(book,{})
                for sheet in book.Worksheets:
                        d[book.Name][1][sheet.Name]=sheet
        return d

 MyData = (('A',3),('B',6),('C',1)) #元データ
 LenData = len(MyData) 

 xlApp = win32com.client.Dispatch("Excel.Application")
 xlApp.Visible = 1
 xlApp.Workbooks.Open("D:\Excel\PyExcel.xls")
 xlSheet = xlApp.Workbooks(1).Sheets(1)
 print xlApp.Workbooks(1).Name
 #print xlSheet
 #data=xlSheet.Cells.value(1,1)
 #print data
 for i in xlApp.Workbooks("PyExcel.xls").Worksheets:
     print i.Name 

 d = booksdict(xlApp.Workbooks)
 print d
 print d["PyExcel.xls"][1]['Sheet1'].Range('A1').value
 print d["PyExcel.xls"][1]['Sheet1'].Cells(1,1).value
 """
 for i in range(LenData):
     xlSheet.Cells(i+1,1).value = MyData[i][0]
     xlSheet.Cells(i+1,2).value = MyData[i][1]

 SumCell = xlSheet.Cells(LenData+1,2)
 SumCell.Value = "=SUM(B1:B%d)" % LenData #合計欄の数式
 AllRegion = SumCell.CurrentRegion        #セルを含む表全体の選択
 AllRegion.Borders.Weight = 2
xlSheet.Range("A%d:B%d" % (LenData, LenData)).Borders(9).Weight = 4

 xlApp.Workbooks(1).SaveAs(Filename = "D:\Excel\PyExcel.xls")
 xlApp.Quit()
 """

EXCELでグラフを描く例

win32comでの、Excelのワークシート操作の高速化テクニック

IEの例

 import win32com.client
 ie=win32com.client.Dispatch("InternetExplorer.Application")
 ie.Visible=1
 ie.Navigate("http://www.yahoo.co.jp")

Lotus Notesの例

企業では、まだまだLotus Notesを使っているところも多いのではないだろうか。NOTESのデータをデータベースに取り込んでZopeで見せたいなどというときは、次のようなプログラムでpythonからNotesのクライアント経由でデータをテキストファイルに落とすことができる。RubyでNotesにアクセスする方法

 import string,win32com.client ## COM モジュールをインポート
 nSs=win32com.client.Dispatch("Notes.NotesSession") ## NOTES COM オブジェクトを開く
 DBServer = "CN=hoge/O=hoge" ## replace server name
 DBFile = "hoge.nsf"  ##replace DB name 
 nDb = nSs.GetDataBase(DBServer, DBFile)  ## DBのオブジェクト
 view = nDb.GetView("hoge")  ## select view
 doc = view.GetFirstDocument ## Viewの一番上の文書を設定
 o=open('c:/temp/output.txt','w') ## opent output file 

 fieldlist=('hoge1','hoge2','hoge3','hoge4') ## 取りたいデータのNOTES上のフィールド名をリストに
 i=1
 while doc:  ## 行がなくなるまで実行
     outline=[]
     for j in fieldlist:
         fieldvalue=doc.GetItemValue(j)[0]  ##listになっているのでデータのある一つ目だけを取り出す
        fieldvalue=string.replace(fieldvalue,'\r\n',' ') ##改行をスペースに変換
        fieldvalue=string.replace(fieldvalue,'\\','\\ ') ##\を\+spaceに変換
        fieldvalue=string.replace(fieldvalue,'\t','  ')  ##TABをspace二つに変換
        outline.append(fieldvalue)
     oline=string.join([str(x) for x in outline],'\t')+ '\t'+doc.NotesURL+'\n' ##Join with tab  and add URL
     print i,oline
     o.write(oline.encode('cp932')) ##shift-jisで書き込む
     i=i+1
     doc=view.GetNextDocument(doc)
 o.close()

こんな例もありました。

http://oldriver.org/blog/2005/09/python_com_lotu.html