C#.NET+OpenOffice.org クラスサンプル
ここではC#.NETで業務系アプリケーションを作るためのOpenOffice.org操作用クラスのサンプルを書いてみることにします。
インターネットで入手できる「uno」の情報をなるべく活用できるように、UNO/CLIの完全ラッパークラスではなく、ドキュメントを取得するところだけをラップすることを今回の目標にしています。
それでは順番に各クラスを紹介します。
ネームスペース:YSystem.OpenOffice | |
---|---|
クラス名 | 説明 |
YCOpenOffice | OpenOffice起動と各種オブジェクトの取得のクラスです。 |
YCOpenOfficeComponent | OpenOfficeの各アプリケーションの親クラスです。 |
YCCalc |
OpenOffice.org Calcのクラスです。 (YCOpenOfficeComponentを継承) |
YCWriter |
OpenOffice.org Writerのクラスです。 (YCOpenOfficeComponentを継承) |
YCOpenOfficeHelper |
OpenOffice.org 用のヘルパクラスです。 |
(解凍後、UNO/CLIライブラリと一緒にプロジェクトに参照追加してご利用下さい。)
※上記のクラスを利用するに当たり、非表示モードでOpenOffice.orgを起動すると「soffice.bin」「soffice.exe」の2つのプロセスが残ります。残っていても不具合はないですが、もし気になる場合はProcessクラス等を使ってプロセスを停止するコードを別途記述して下さい。
YCOpenOffice(YCOpenOffice.cs)
using System; using System.Collections.Generic; using System.Text; using unoidl.com.sun.star.uno; using unoidl.com.sun.star.lang; using unoidl.com.sun.star.frame; using unoidl.com.sun.star.graphic; using uno.util; namespace YSystem.OpenOffice { /// <summary> /// OpenOffice起動と各種オブジェクトの取得のクラスです。 /// </summary> internal abstract class YCOpenOffice { /// <summary> /// サービスマネージャを取得します。 /// </summary> /// <returns>サービスマネージャ</returns> public static unoidl.com.sun.star.lang.XMultiServiceFactory CreateServiceManager() { XComponentContext componentContext = null; XMultiServiceFactory serviceManager = null; try { //コンポーネントコンテキストとサービスマネージャの生成 componentContext = Bootstrap.bootstrap(); serviceManager = (XMultiServiceFactory)componentContext.getServiceManager(); componentContext = null; return serviceManager; } catch (System.Exception e) { componentContext = null; serviceManager = null; throw e; } } /// <summary> /// コンポーネントローダオブジェクトを取得します。 /// </summary> /// <returns>コンポーネントローダ</returns> public static unoidl.com.sun.star.frame.XComponentLoader CreateComponentLoader(XMultiServiceFactory serviceManager) { return (XComponentLoader)serviceManager.createInstance("com.sun.star.frame.Desktop"); } /// <summary> /// ディスパッチャオブジェクトを取得します。 /// </summary> /// <returns>ディスパッチャ</returns> public static unoidl.com.sun.star.frame.XDispatchHelper CreateDispatcher(XMultiServiceFactory serviceManager) { return (XDispatchHelper)serviceManager.createInstance("com.sun.star.frame.DispatchHelper"); } /// <summary> /// デスクトップオブジェクトを取得します。 /// </summary> /// <returns>デスクトップ</returns> public static unoidl.com.sun.star.frame.XDesktop CreateDesktop(XMultiServiceFactory serviceManager) { return (XDesktop)serviceManager.createInstance("com.sun.star.frame.Desktop"); } } }
YCOpenOfficeComponent(YCOpenOfficeComponent.cs)
using System; using System.Collections.Generic; using System.Text; using unoidl.com.sun.star.lang; using unoidl.com.sun.star.beans; using unoidl.com.sun.star.frame; using unoidl.com.sun.star.drawing; namespace YSystem.OpenOffice { /// <summary> /// OpenOfficeの各アプリケーションの親クラスです。 /// </summary> public abstract class YCOpenOfficeComponent : IDisposable { private XComponent _component = null; private XMultiServiceFactory _serviceManager = null; private XDispatchHelper _dispatcher = null; private XDesktop _desktop = null; private bool _isDisposable = true; private bool _hidden = false; private bool _readOnly = false; private bool _overwrite = true; private string _fileName = string.Empty; private bool _isNewDocument = true; private bool _frameIsBlank = true; /// <summary> /// デフォルトコンストラクタです。 /// </summary> public YCOpenOfficeComponent() { } /// <summary> /// リソースを解放します。 /// </summary> public virtual void Dispose() { if (this.IsDisposable) { if (_component != null) { //アプリケーションが非表示起動の場合はDisposeする。 if (this.Hidden) { try { _component.dispose(); } catch { } } _component = null; } _serviceManager = null; _dispatcher = null; _desktop = null; _isDisposable = false; } } /// <summary> /// Disposeが可能ならTrue /// </summary> protected bool IsDisposable { get { return _isDisposable; } } /// <summary> /// コンポーネントオブジェクトを取得、設定します。 /// <para>サブクラス(各アプリケーションのクラス)にてそれぞれのドキュメントクラスにキャストしたプロパティを準備するして下さい。</para> /// </summary> protected XComponent Component { get { return _component; } set { _component = value; } } /// <summary> /// サービスマネージャを取得します。 /// </summary> public XMultiServiceFactory ServiceManager { get { if (_serviceManager == null) { _serviceManager = YCOpenOffice.CreateServiceManager(); } return _serviceManager; } } /// <summary> /// ディスパッチャを取得します。 /// </summary> public XDispatchHelper Dispatcher { get { if (_dispatcher == null) { _dispatcher = YCOpenOffice.CreateDispatcher(this.ServiceManager); } return _dispatcher; } } /// <summary> /// ディスパッチプロバイダオブジェクトを取得します。 /// </summary> public XDispatchProvider DispatchProvider { get { if (_desktop == null) { _desktop = YCOpenOffice.CreateDesktop(this.ServiceManager); } return (XDispatchProvider)_desktop.getCurrentFrame(); } } /// <summary> /// 起動時の非表示設定を取得、設定します。 /// <para>起動時に非表示にするならtrue</para> /// </summary> public bool Hidden { get { return _hidden; } set { _hidden = value; } } /// <summary> /// 起動時の読み取り専用設定を取得、設定します。 /// <para>起動時に読み取り専用にするならtrue</para> /// </summary> public bool ReadOnly { get { return _readOnly; } set { _readOnly = value; } } /// <summary> /// 起動時の上書き可設定を取得、設定します。 /// <para>起動時に上書き不可にするならfalse</para> /// </summary> public bool Overwrite { get { return _overwrite; } set { _overwrite = value; } } /// <summary> /// 対象のファイル名を取得、設定します。 /// <para>ファイル名はフルパスで指定して下さい。</para> /// </summary> public string FileName { get { return _fileName; } set { _fileName = value; } } /// <summary> /// 新規ファイルかどうかを取得、設定します。 /// <para>Openの時に新規ファイルの場合はtrue</para> /// </summary> public bool IsNewDocument { get { return _isNewDocument; } set { _isNewDocument = value; } } //; /// <summary> /// ウインドウを新規に開くかどうかを取得、設定します。 /// <para>ウィンドウを新規に開く場合はtrue</para> /// </summary> public bool FrameIsBlank { get { return _frameIsBlank; } set { _frameIsBlank = value; } } /// <summary> /// 既にオープンされていればtrue /// </summary> public bool IsOpened { get { if (_component != null) return true; else return false; } } /// <summary> /// アプリケーションを開きます。 /// </summary> public virtual void Open() { PropertyValue[] properties = new PropertyValue[3]; try { //既に開いている時は開かない。 if (!this.IsOpened) { string url = string.Empty; if (this.IsNewDocument) url = this.NewDocumentURL; else url = KCOpenOfficeHelper.ConvertToUrl(this.FileName); string frameTarget = string.Empty; if(this.FrameIsBlank) frameTarget = "_blank"; else frameTarget = "_default"; properties[0] = new PropertyValue(); properties[0].Name = "Hidden"; if (this.Hidden) properties[0].Value = new uno.Any(true); else properties[0].Value = new uno.Any(false); properties[1] = new PropertyValue(); properties[1].Name = "ReadOnly"; if (this.ReadOnly) properties[1].Value = new uno.Any(true); else properties[1].Value = new uno.Any(false); properties[2] = new PropertyValue(); properties[2].Name = "Overwrite"; if (this.Overwrite) properties[2].Value = new uno.Any(true); else properties[2].Value = new uno.Any(false); _component = KCOpenOffice.CreateComponentLoader(this.ServiceManager).loadComponentFromURL(url, frameTarget, 0, properties); } } catch(Exception e) { if(_component != null) { try{_component.dispose();} catch{} _component= null; } properties = null; throw e; } } /// <summary> /// ファイルを保存します。 /// </summary> public virtual void Save() { ((XStorable)this.Component).storeToURL(YCOpenOfficeHelper.ConvertToUrl(this.FileName), new PropertyValue[0]); } /// <summary> /// OpenOfficeの各アプリケーション起動用のURLを返します。 /// </summary> protected abstract string NewDocumentURL { get; } } }
YCCalc(YCCalc.cs)
using System; using System.Collections.Generic; using System.Text; using unoidl.com.sun.star.sheet; namespace YSystem.OpenOffice { /// <summary> /// OpenOffice Calcのクラスです。 /// </summary> public class YCCalc : YCOpenOfficeComponent { /// <summary> /// デフォルトコンストラクタです。 /// </summary> public YCCalc() : base() { } /// <summary> /// OpenOffice Calcを開く時のURLです。 /// </summary> protected override sealed string NewDocumentURL { get { return "private:factory/scalc"; } } /// <summary> /// OpenOffice Calcのドキュメントインスタンスです。 /// </summary> public XSpreadsheetDocument Document { get { return (XSpreadsheetDocument)this.Component; } } /// <summary> /// シートオブジェクトを取得します。 /// </summary> /// シート名 /// <returns>シートオブジェクト</returns> public XSpreadsheet GetSheet(string sheetName) { return (XSpreadsheet)this.Document.getSheets().getByName(sheetName).Value; } /// <summary> /// 画像シェイプを挿入します。 /// </summary> /// <param name="sheetName">シート名</param> /// <param name="graphicFileName">画像ファイル(フルパス)</param> /// <param name="left">シェイプの左の位置(0.01mm単位)</param> /// <param name="top">シェイプの上の位置(0.01mm単位)</param> /// <param name="width">シェイプの幅(0.01mm単位)</param> /// <param name="height">シェイプの高さ(0.01mm単位)</param> public void InsertGraphicShape(string sheetName, string graphicFileName, int left, int top, int width, int height) { unoidl.com.sun.star.drawing.XDrawPage drawPage = null; unoidl.com.sun.star.drawing.XShape shape = null; if (!this.IsOpened) throw new Exception("オープンしていません。"); try { //DrawPageの取得 drawPage = ((unoidl.com.sun.star.drawing.XDrawPageSupplier)this.Document.getSheets().getByName(sheetName).Value).getDrawPage(); //Shapeの生成 shape = (unoidl.com.sun.star.drawing.XShape)((unoidl.com.sun.star.lang.XMultiServiceFactory)this.Document).createInstance("com.sun.star.drawing.GraphicObjectShape"); shape.setPosition(new unoidl.com.sun.star.awt.Point(left, top)); shape.setSize(new unoidl.com.sun.star.awt.Size(width, height)); ((unoidl.com.sun.star.beans.XPropertySet)shape).setPropertyValue("GraphicURL", new uno.Any(YCOpenOfficeHelper.ConvertToUrl(graphicFileName))); //Shapeの追加 drawPage.add(shape); shape = null; drawPage = null; } catch (Exception e) { shape = null; drawPage = null; throw e; } } /// <summary> /// 指定のインデックス番号のシートにジャンプします。。 /// </summary> /// <param name="index">インデックス番号</param> public void GoToSheet(int index) { unoidl.com.sun.star.beans.PropertyValue[] args = new unoidl.com.sun.star.beans.PropertyValue[1]; args[0] = new unoidl.com.sun.star.beans.PropertyValue(); args[0].Name = "Nr"; args[0].Value = new uno.Any(index); this.Dispatcher.executeDispatch(this.DispatchProvider, ".uno:JumpToTable", "", 0, args); args = null; } /// <summary> /// 指定のセルにジャンプします。 /// </summary> /// <param name="cell">セル文字列</param> public void GoToCell(string cell) { unoidl.com.sun.star.beans.PropertyValue[] args = new unoidl.com.sun.star.beans.PropertyValue[1]; args[0] = new unoidl.com.sun.star.beans.PropertyValue(); args[0].Name = "ToPoint"; args[0].Value = new uno.Any(cell); this.Dispatcher.executeDispatch(this.DispatchProvider, ".uno:GoToCell", "", 0, args); args = null; } /// <summary> /// 現在のセルに画像を貼り付けます。 /// <para>原寸サイズでしか貼り付けできません。</para> /// </summary> /// <param name="graphicFileName">画像ファイル(フルパス)</param> public void PasteGraphicToCurrentCell(string graphicFileName) { unoidl.com.sun.star.beans.PropertyValue[] args = new unoidl.com.sun.star.beans.PropertyValue[2]; args[0] = new unoidl.com.sun.star.beans.PropertyValue(); args[0].Name = "FileName"; args[0].Value = new uno.Any(YCOpenOfficeHelper.ConvertToUrl(graphicFileName)); args[1] = new unoidl.com.sun.star.beans.PropertyValue(); args[1].Name = "AsLink"; args[1].Value = new uno.Any(false); this.Dispatcher.executeDispatch(this.DispatchProvider, ".uno:InsertGraphic", "", 0, args); args = null; } } }
YCWriter(YCWriter.cs)
using System; using System.Collections.Generic; using System.Text; using unoidl.com.sun.star.text; namespace YSystem.OpenOffice { /// <summary> /// OpenOffice Writerのクラスです。 /// </summary> public class YCWriter : YCOpenOfficeComponent { /// <summary> /// デフォルトコンストラクタです。 /// </summary> public YCWriter() : base() { } /// <summary> /// OpenOffice Writerを開く時のURL /// </summary> protected override sealed string NewDocumentURL { get { return "private:factory/swriter"; } } /// <summary> /// OpenOffice Writerのドキュメントインスタンスです。 /// </summary> public XTextDocument Document { get { return (XTextDocument)this.Component; } } /// <summary> /// 画像シェイプを挿入します。 /// </summary> /// <param name="graphicFileName">画像ファイル(フルパス)</param> /// <param name="left">シェイプの左の位置(0.01mm単位)</param> /// <param name="top">シェイプの上の位置(0.01mm単位)</param> /// <param name="width">シェイプの幅(0.01mm単位)</param> /// <param name="height">シェイプの高さ(0.01mm単位)</param> public void InsertGraphicShape(string graphicFileName, int left, int top, int width, int height) { unoidl.com.sun.star.drawing.XDrawPage drawPage = null; unoidl.com.sun.star.drawing.XShape shape = null; try { //DrawPageの取得 drawPage = ((unoidl.com.sun.star.drawing.XDrawPageSupplier)this.Document).getDrawPage(); //Shapeの生成 shape = (unoidl.com.sun.star.drawing.XShape)((unoidl.com.sun.star.lang.XMultiServiceFactory)this.Document).createInstance("com.sun.star.drawing.GraphicObjectShape"); shape.setPosition(new unoidl.com.sun.star.awt.Point(left, top)); shape.setSize(new unoidl.com.sun.star.awt.Size(width, height)); ((unoidl.com.sun.star.beans.XPropertySet)shape).setPropertyValue("GraphicURL", new uno.Any(YCOpenOfficeHelper.ConvertToUrl(graphicFileName))); ((unoidl.com.sun.star.beans.XPropertySet)shape).setPropertyValue("AnchorType", new uno.Any(TextContentAnchorType.AT_PAGE.ToString())); //Shapeの追加 drawPage.add(shape); shape = null; drawPage = null; } catch (Exception e) { shape = null; drawPage = null; throw e; } } } }
YCOpenOfficeHelper(YCOpenOfficeHelper.cs)
using System; using System.Collections.Generic; using System.Text; namespace YSystem.OpenOffice { /// <summary> /// OpenOffice用のヘルパクラスです。 /// </summary> public abstract class YCOpenOfficeHelper { /// <summary> /// ファイルパスをURLに変換します。 /// </summary> /// <param name="filePath">ファイル名(フルパス)</param> /// <returns>URL</returns> public static string ConvertToUrl(string filePath) { string ans = filePath; ans = @"file:///" + ans.Replace(@"\", @"/"); return ans; } } }
最後に上記のクラスを使ったテスト用のコードを記述します。 新規プロジェクトにUNO/CLIライブラリと上記で作ったDLLを参照に追加して使って下さい。
OpenOfficeTestMain(OpenOfficeTestMain.cs)
using System; using YSystem.OpenOffice; using unoidl.com.sun.star.sheet; namespace OpenOfficeTest { static class OpenOfficeTestMain { /// <summary> /// OpenOfficeのテスト /// </summary> [STAThread] static void Main() { //OpenOffice.org Calcの動作テスト //新規起動の場合 YCCalc calc = new YCCalc(); //既存ファイルを開く場合はこちら //calc.IsNewDocument = false; //calc.FileName = @"C:\テスト.ods"; //OpenOffice.org ドキュメントを開く calc.Open(); //シート「表2」のセルにデータを書き込む calc.GetSheet("sheet2").getCellByPosition(0, 0).setFormula("Hello World!"); calc.GetSheet("sheet2").getCellByPosition(0, 1).setFormula("こんにちは世界!"); //シート「表2」に画像の挿入 calc.InsertGraphicShape("sheet2", @"C:\Sample.jpg", 1000, 500, 10000, 10000); //シートの移動 calc.GoToSheet(2); //セルの移動 calc.GoToCell("F3"); //現在のセルに画像の貼り付け calc.PasteGraphicToCurrentCell(@"C:\Sample.jpg"); calc.Dispose(); calc = null; } } }