銀月の符号

Python 使い見習いの日記・雑記

Python-Uno で OpenOffice calc 操作 - 7時間目

すこしずつ OOoBasic マクロを Python に翻訳するコツがわかってきた。ほとんどそのままだけど直さなきゃいけないところはやっぱりあって、 StarDesktop は XSCRIPTCONTEXT.getDesktop() だったり Array はタプルだったり、 struct は uno.createUnoStruct("com.sun.star.beans.PropertyValue") のように作ったり。

ファイル開こうとしたけど実在しない、とかやってしまうと簡単に calc ごと落ちるため例外処理がいるはず。API リファレンスをみると送出される例外は書いてあるけど com::sun::star::io::IOException とかどうやってつかまえるんだ?

といったところで今日は力尽きたのでコードだけ。ファイルオープンと各シートへのアクセス方法の。

# -*- coding: utf-8 -*-
u"""
OpenOffice calc を動かすぜ!?
7 時間目。
"""
import uno
import unohelper

# XSCRIPTCONTEXT
# com.sun.star.script.provider.XScriptContext インターフェース
# http://api.openoffice.org/docs/common/ref/com/sun/star/script/provider/XScriptContext.html
# Python と OOo とのやり取りをする。
# OOo マクロとして用いる場合、グローバル変数として無条件で用意される。


# コンポーネントコンテキスト
ctx = XSCRIPTCONTEXT.getComponentContext()
# 定数やサービスマネージャにアクセスできる。
# com.sun.star.uno.XComponentContext インターフェース
# http://api.openoffice.org/docs/common/ref/com/sun/star/uno/XComponentContext.html


# サービスマネージャ
smgr = ctx.getServiceManager()
# smgr = ctx.ServiceManager # get* や set* のようなメソッドにはプロパティとしてのアクセスも可能
# ここからサービスをインスタンス化できる。
# com.sun.star.lang.XMultiComponentFactory インターフェース
# http://api.openoffice.org/docs/common/ref/com/sun/star/uno/XComponentContext.html


# デスクトップ
desktop = XSCRIPTCONTEXT.getDesktop()
# com.sun.star.frame.XDesktop インターフェース
# http://api.openoffice.org/docs/common/ref/com/sun/star/script/provider/XScriptContext.html
# com.sun.star.frame.Desktop サービスも参照
# http://api.openoffice.org/docs/common/ref/com/sun/star/frame/Desktop.html
# OOoBasic の StarDesktop ショートカット変数と同義。


def load_file():
    u"""
    Calc ドキュメントを開いて各シートに入力
    OpenOffice 対応ファイルなら開ける。
    けれども calc 用のファイルでないとその後の処理でとまるはず
    """
    file_path = u"C:\\uno-test\\test.xls"
    # なぜか raw 文字列が使えない。要調査。


    # struct の作り方
    property_value = uno.createUnoStruct("com.sun.star.beans.PropertyValue")
    # http://api.openoffice.org/docs/common/ref/com/sun/star/beans/PropertyValue.html
    # これに値を設定をし loadComponentFromURL 第4引数の sequence に含めるとなにかできる模様…


    doc =desktop.loadComponentFromURL(
            unohelper.systemPathToFileUrl(file_path),
            u"_blank",
            0,
            (), # Uno の sequence は Python ではタプル、 Basic だと Array
            )
    # http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html
    # 第1引数はファイルを示す URL 。systemPathToFileUrl で通常のパスを URL に変換して渡す。
    # 第2引数は _balnk, _default, _self, _parent, _top, _beamer が指定可能。


    # スプレッドシートへのアクセス用オブジェクト
    sheets = doc.getSheets()
    # com.sun.star.sheet.XSpreadsheets インターフェース
    # http://api.openoffice.org/docs/common/ref/com/sun/star/sheet/XSpreadsheets.html
    # com.sun.star.container.XNameAccess インターフェース
    # http://api.openoffice.org/docs/common/ref/com/sun/star/container/XNameAccess.html
    # com.sun.star.container.XNameReplace インターフェース
    # http://api.openoffice.org/docs/common/ref/com/sun/star/container/XNameReplace.html
    # など


    # スプレッドシートの名前が入った sequence, Python ではタプルを得る
    sheets_names = sheets.getElementNames()


    # スプレッドシートそのもの
    for name in sheets_names:
        sheet = sheets.getByName(name) # 名前で得る
        # com.sum.star.sheet.XSpreadsheet インターフェース
        # http://api.openoffice.org/docs/common/ref/com/sun/star/sheet/XSpreadsheet.html
        # com.sun.star.table.XCellRange インターフェース
        # http://api.openoffice.org/docs/common/ref/com/sun/star/table/XCellRange.html
        # など

        # なんらかの処理を行う
        for i in range(5):
            for j in range(4):
                cell = sheet.getCellByPosition(i, j)
                cell.setValue(i * j)