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()
"""
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