3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(.Net,OpenOffice).Net から OpenOffice ドキュメントを操作する

.NetからOpenOfficeのドキュメントを操作するための方法です。

OpenOfficeには UNO(Universal Network Objects) というAPIが用意されてるのでそれを使って操作できるようです。

(OpenOffice内のマクロも UNO 経由で動いてるっぽいです)

UNO を .Net Framework CLI から利用するためのライブラリも用意されています。

まず、.Net から UNO 操作を行うために、OpenOffice SDK を入れます。

今回はここから、3.2の SDK をダウンロードしました。

下記の UNO 操作のライブラリを VisualStudio のプロジェクトフォルダにコピーして、参照設定を行います。

C:\Program Files\OpenOffice.org 3\URE\bin\

cli_uno.dll

C:\Program Files\OpenOffice.org_3.2_SDK\sdk\cli\

cli_basetypes.dll

cli_cppuhelper.dll

cli_oootypes.dll

cli_ure.dll

cli_uretypes.dll

Calcのファイルを開き、セルに値を入れて保存するという処理をするというサンプルを下記に載せてみました。(C#)

//下記のインポートが必要

using uno.util;

using unoidl.com.sun.star.frame;

using unoidl.com.sun.star.lang;

using unoidl.com.sun.star.sheet;

using unoidl.com.sun.star.table;

using unoidl.com.sun.star.uno;

using unoidl.com.sun.star.beans;

using unoidl.com.sun.star.util;

 

//コンポーネントコンテキストオブジェクト取得(OpenOfficeの基本プロセスらしい)

XComponentContext context = Bootstrap.bootstrap();

//サービスマネージャ取得

XMultiServiceFactory factory = (XMultiServiceFactory)context.getServiceManager();

//コンポーネントローダオブジェクト取得

XComponentLoader loader = (XComponentLoader)factory.createInstance("com.sun.star.frame.Desktop");

 

//非表示で実行するためのプロパティ指定

PropertyValue[] args1 = new PropertyValue[1];

args1[0] = new PropertyValue();

args1[0].Name = "Hidden";

args1[0].Value = new uno.Any((Boolean)true);

 

//ファイルを開きドキュメントオブジェクトを生成

XSpreadsheetDocument doc = (XSpreadsheetDocument)loader.loadComponentFromURL("file:///c:/a.ods", "_blank", 0, args1);

//シートたちを取得

XSpreadsheets sheets = doc.getSheets();

//Sheet1 を取得

XSpreadsheet sheet = (XSpreadsheet)sheets.getByName("Sheet1").Value;

 

//セルを選択

XCell cell = sheet.getCellByPosition(2, 2);

//セルに数値代入

cell.setValue(1000);

//セルを選択

cell = sheet.getCellByPosition(2, 3);

//セルに文字列代入

cell.setFormula("ホゲホゲ");

 

//保存するために使うクラス(インターフェイス?)取得

XStorable xstorable = (XStorable)doc;

//保存時のプロパティ設定

PropertyValue[] storeProps = new PropertyValue[1];

storeProps[0] = new PropertyValue();

storeProps[0].Name = "Overwrite"; //上書き

storeProps[0].Value = new uno.Any((Boolean)true);

try

{

String sURL = "file:///c:/a2.ods" ;

//保存

xstorable.storeAsURL(sURL, storeProps);

//閉じる

if (doc != null)

{

XCloseable xCloseable = (XCloseable)doc;

xCloseable.close(true);

doc = null;

 

}

}

catch (unoidl.com.sun.star.uno.Exception ex)

{

MessageBox.Show(ex.Message);

}

OpenOfficeファイルを開く XComponentLoader.loadComponentFromURL() や 保存を行う XStorable.storeAsURL() の第一引数のパスはWindows標準のパス形式(例 C:\aa\a.ods)だとダメなようで、URL形式で渡さないといけないようです。

Windowsのパス名をURL形式に変換するには、¥を/に、:を|に、スペースを%20に変換して、先頭に file:/// を付けてやるのもいいけど、.Netには便利なクラスがあります。

下記のようにすれば簡単にURLエンコードできます。

Uri uriCalcFile;

Uri.TryCreate(@"C:\test test\テスト フォルダ\a.ods", UriKind.Absolute, out uriCalcFile);

string strCalcFile = uriCalcFile.ToString();

また、Calcのセルから値の取得をするには、下記のメソッドでできます。

XCell.getValue()    //double型の数値の値

XCell.setFormula() //文字列(数式)型の取得

XCloseable.close(treu) の処理をしても soffice.bin , soffice.exe プロセスは残ったままになります。

どうやら、openoffice.bin を Kill しないといけないようです。

プロセス終了については、ここを参考できます。

ただ、特定のユーザだけのプロセスを終了する場合はちょっと工夫が必要でこれは後日書きたいと思います。

OpenOfficeにはPDF出力機能があるので、UNOを応用して帳票のPDF出力にも使えそうですね。

参考:

ソフトウェア雑工学 : OpenOfficeのCalcの名前付きセルにC#から値をセットする

C#でOpenOfficeを使おう presented by ワイワークス ソフトウェア C#からOpenOffice操作するための基本が載ってます。

VB.NET+OOo VB.NetからOpenOfficeを操作するサンプルが載ってます。

OpenOffice.org Writerを使ってPDF出力 | Juice

日々の戯言などを - 暇なのでなにかやる -  OpenOffice.orgのファイルを閉じる

オフィスの開発 OpenOffice.orgの公式のマニュアルっぽいですが、結構難解です。気合い入れないと読む気しません。