読者です 読者をやめる 読者になる 読者になる

OpenofficeのPythonマクロでimpressの情報を取得するには

前回と同様、OpenofficePythonマクロなのだが、今回はimpressの方で作ってみた。前回同様powerpointにもVBAでのマクロが存在するようなのだが、gitとの連携や、Linuxでも使える点を考え、こちらで進めている。
前回についてはこちら:
http://d.hatena.ne.jp/aaabbb_200904/20110212/1297519086
今回は、同じようなimpressファイルから表を抜きだし、更にその中から特定の行を抜き出すロジックを作ってみた。今回も最初にプログラム本体を載せることにする。。
注意: ちなみにこのスクリプトを実行すると、時々Openofficeがクラッシュするので注意。orz 実行したタイミングでどの部分がアクティブになっているかによるようなのだが、詳しい条件はわからなかった。。

スクリプト本体

#! # test.py 
# -*- coding: utf_8 -*- 

def hello(): 
    from com.sun.star.table import ShadowFormat 
    from com.sun.star.table.ShadowLocation import BOTTOM_RIGHT 
    from com.sun.star.table import TableBorder 
    from com.sun.star.table import BorderLine 
    from com.sun.star.awt.FontWeight import BOLD 
    from com.sun.star.awt import Point, Size 
    Doc  = XSCRIPTCONTEXT.getDocument() 

    # Setting slide 
    Page = Doc.DrawPages.getByIndex(0) 
    Page.Width = 30000 

    # insert Slide 
    #Page = Doc.DrawPages.insertNewByIndex(1) 

    # insert textbox 
    RectangleShape = Doc.createInstance("com.sun.star.drawing.RectangleShape") 
    size = Size() 
    point = Point() 
    point.X = 1000 
    point.Y = 1000 
    size.Width = 10000 
    size.Height = 10000 

    RectangleShape.Size = size 
    RectangleShape.Position = point 
 
    RectangleShape.String = "This is a test" 
    RectangleShape.CharWeight = BOLD 
    Page.add(RectangleShape) 
 
    # table 
    def createtable(page, row, column): 
     Table = Doc.createInstance("com.sun.star.drawing.TableShape") 
     page.add(Table) 
     model=Table.Model 
     rows=model.getRows() 
     columns=model.getColumns() 
     for i in range(row): 
      #print model.RowCount 
      rows.insertByIndex(0,1) 
      #rows.getByIndex(0).Height=2000 
     for i in range(column): 
      #print model.ColumnCount 
      columns.insertByIndex(0,1) 
      #columns.getByIndex(0).Width=2000 
     cell=model.getCellByPosition(0,0) 
     cell.String = "Test1" 
     cell=model.getCellByPosition(0,1) 
     cell.String = "Test2" 
     cell=model.getCellByPosition(1,0) 
     cell.String = "Result1" 
     cell=model.getCellByPosition(1,1) 
     cell.String = "Resutl2" 

    print "createtables" 
    createtable(Page, 2, 2) 

    # Search for table 
    print Page.Count 
    for i in range(Page.Count): 
     shape = Page.getByIndex(i) 
     print shape.getShapeType() 
     if (shape.getShapeType() == 'com.sun.star.drawing.TableShape'): 
      break 
    model=shape.Model 
    print model.RowCount 
    print model.ColumnCount 
    for i in range(model.RowCount): 
      cell=model.getCellByPosition(0,i) 
      if (cell.String == 'Test2'): 
        cell = model.getCellByPosition(1,i) 
        print 'The Result is ' + cell.String 
    return None 

if __name__ == '__main__': 
	import unopy 
	XSCRIPTCONTEXT = unopy.connect() 
 	if not XSCRIPTCONTEXT: 
 		print("Failed to connect to OpenOffice.org.") 
 	 	import sys 
 	 	sys.exit(0) 
 	 
 	hello() 

説明

スライドを取得するには

スライドを取得するには、次のように Doc.DrawPages.getByIndex で取得する。スライドは上から順に通し番号を振られるようである。(スタートは0から)

    Page = Doc.DrawPages.getByIndex(0) 
スライドを追加するには

スライドを追加する場合には、insertNewByIndexで追加できる。

    Page = Doc.DrawPages.insertNewByIndex(1) 
図形を追加するには

今回直接は使っていないのだが、図形を追加するには、 Doc.createInstance でインスタンスを指定して図形を作成し、Page.addで追加する形になる。

        RectangleShape = Doc.createInstance("com.sun.star.drawing.RectangleShape") 
        Page.add(RectangleShape) 
表を作成するには

表を作成する場合にも、createInstanceで作成するのだが、インスタンス名は com.sun.star.drawing.TableShape となる。(writerの表では、com.sun.star.text.TextTableなので注意)

     Table = Doc.createInstance("com.sun.star.drawing.TableShape")
     page.add(Table)

この後もwriterの表とは少々異なり、modelから、rows, columnsを取得し、行、列を追加していく形になる。個々の行、列はgetByIndexで取得し、幅、高さも指定できるはずなのだが、なぜか実際に指定すると頻繁にクラッシュしたため、指定していない。。orz

     model=Table.Model
     rows=model.getRows()
     columns=model.getColumns()
     for i in range(row):
      #print model.RowCount
      rows.insertByIndex(0,1)
     #for i in range(row):
     # rows.getByIndex(i).Height=2000
     for i in range(column):
      #print model.ColumnCount
      columns.insertByIndex(0,1)
表を探すには

既に資料の中に、表があることが分かっている場合には、まず、スライドを指定し、その中の要素から表を探していくことになる。(本来はスライドも上から順に探していく(スライドのタイトルなどで検索)べきなのだが、今回は時間の都合により省略。。orz)
まず、スライドをPageで指定すると、Pageの中の要素はPage.Countで取得出来るので、要素ごとにgetShapeTypeを確認し、'com.sun.star.drawing.TableShape'と等しいものを探す。

    for i in range(Page.Count):
     shape = Page.getByIndex(i)
     print shape.getShapeType()
     if (shape.getShapeType() == 'com.sun.star.drawing.TableShape'):
      break

見つかったら、1列目の中身を順に探していき、予定のもの(ここでは1列目が'Test2'のもの)が見つかったら、2列目を出力している。

    model=shape.Model 
    for i in range(model.RowCount): 
      cell=model.getCellByPosition(0,i) 
      if (cell.String == 'Test2'): 
        cell = model.getCellByPosition(1,i) 
        print 'The Result is ' + cell.String 

まとめ

プレゼンのフォーマットが決まっている資料から必要な情報(発表者、日付など)を抜いていくには、このようなマクロが必要になりそうだ。。<<参考リンク>>
http://www.oooforum.org/forum/viewtopic.phtml?t=102812 <== TableShapeの場合は2重のループが必要。。
http://api.openoffice.org/servlets/ReadMsg?listName=dev&msgNo=20714