OpenOffice形式に変換する
OpenOffice形式(ODF:.odt, .ods, .odpなど)はZip圧縮された複数のXMLファイルなので、テキストを抽出したりするのが容易です。
一方、以前のMS Office形式(.doc, .xls, .pptなど)はバイナリ形式なのでテキスト抽出などは困難です。
なのでOpenOffice形式への変換方法などを調べました。
目的
MS Office形式(.doc, .xls, .pptなど)からOpenOffice形式(ODF:.odt, .ods, .odpなど)に変換したい。
解決策
下記の参考サイトを参考にして、OpenOfficeを使用してファイル形式を変換することにしました。
OpenOfficeにファイル変換用マクロを登録し、そのマクロを呼び出してファイル形式を変換します。
以下の2つのファイルを編集して、ファイル変換用マクロを登録します。
1. ~/.openoffice.org/3/user/basic/Standard/Export.xba
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd"> <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Export" script:language="StarBasic"> Function MakePropertyValue( Optional cName As String, Optional uValue ) _ As com.sun.star.beans.PropertyValue Dim oPropertyValue As New com.sun.star.beans.PropertyValue If Not IsMissing( cName ) Then oPropertyValue.Name = cName EndIf If Not IsMissing( uValue ) Then oPropertyValue.Value = uValue EndIf MakePropertyValue() = oPropertyValue End Function Sub SaveAsOOO( cInFile, cOutFile ) On Error Goto ErrorHandler cInURL = ConvertToURL( cInFile ) oDoc = StarDesktop.loadComponentFromURL( cInURL, "_blank", 0, _ Array( MakePropertyValue( "Hidden", True ), ) ) cOutURL = ConvertToURL( cOutFile ) oDoc.storeAsURL( cOutURL, Array() ) oDoc.close( True ) Exit Sub ErrorHandler: Resume Next End Sub </script:module>
下記の参考サイトのソースをベースに作成しました。SaveAsOOOにはエラーハンドラを追加しました。これを追加しておかないと、ファイルが見つからないなど、何らかのエラーが生じた際にメッセージボックスが表示されてしまい、バッチ処理には向きません。
2. ~/.openoffice.org/3/user/basic/Standard/script.xlb
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd"> <library:library xmlns:library="http://openoffice.org/2000/library" library:name="Standard" library:readonly="false" library:passwordprotected="false"> <library:element library:name="Export"/> </library:library>
登録したマクロをシェルから呼ぶには以下のようにします。
ooffice -invisible -nologo 'macro:///Standard.Export.SaveAsOOO("/tmp/example.ppt", "/tmp/example.odp")'
仕様かどうかはわかりませんが、-nologoを付けないと処理がバックグラウンドで行われるようです。
ソースコード
上記のマクロを呼び出すpythonコードを作成しました。
import os, stat def convert_from(from_path, to_path): updated_at = os.stat(to_path)[stat.ST_MTIME] if os.path.exists(to_path) else None command = 'ooffice -invisible -nologo '\ '\'macro:///Standard.Export.SaveAsOOO("{0}", "{1}")\'' # TODO escape from_path and to_path os.system(command.format(from_path, to_path)) if not os.path.exists(to_path): raise Exception, 'Failed to convert to OpenOffice format, not exists' if os.stat(to_path)[stat.ST_MTIME] == updated_at: raise Exception, 'Failed to convert to OpenOffice format, not updated' def _test(): import tempfile tempfd, temppath = tempfile.mkstemp() convert_from('/tmp/validfile.ppt', temppath) os.remove(temppath) tempfd, temppath = tempfile.mkstemp() #convert_from('/tmp/invalidfile.ppt', temppath) os.remove(temppath) temppath = '/tmp/out.odp' convert_from('/tmp/validfile.ppt', temppath) os.remove(temppath) #convert_from('/tmp/invalidfile.ppt', temppath) #os.remove(temppath) if __name__ == '__main__': _test()
変換が正常に行われたかどうかは、リターンコードでは判別できません。
出力ファイルが存在しない、もしくは出力ファイルが更新されていないときは変換に失敗したと判断します。