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

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

(.Net,OpenOffice).NetからCalc操作時に罫線(枠線)を引く

(.NetからOpenOfficeを操作する方法はを参照。OpenOfficeは3.2です。)

.NetからCalcファイルを作成し、データを吐きたいんですが枠線を入れる方法がわかりませんでした。

最初、こちらを参考にしてディスパッチを使った方法を検討していました。

Calc で枠線を引くマクロを記録し、そこに吐かれたディスパッチを使う方法です。

しかし、結局うまくいきませんでした。どうも、ディスパッチが効いてないないようです。。。

で、途方に暮れているとPCにインストールしたOpenOffice SDKのサンプルにやりたいことが書いていました。

サンプルは、OpenOffice.org_3.2_SDK\sdk\examples\CLI\CSharp\Spreadsheet\SpreadsheetDocHelper.cs の prepareRange メソッドに書いてあります。

ほぼサンプルそのままですが、一応ソース載せておきます。(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;

using unoidl.com.sun.star.container;

 

string filename = @"d:\a.ods";

 

//ファイルパスを変換

Uri uriCalcFile;

Uri.TryCreate(filename, UriKind.Absolute, out uriCalcFile);

filename = uriCalcFile.ToString();

//コンポーネントコンテキストオブジェクト取得

XComponentContext context = Bootstrap.bootstrap();

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

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

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

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

//ドキュメントオブジェクト取得

XSpreadsheetDocument doc = (XSpreadsheetDocument)loader.loadComponentFromURL(filename, "_blank", 0, null);

//シート取得

XSpreadsheets sheets = doc.getSheets();

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

 

XPropertySet xPropSet = null;

XCellRange xCellRange = null;

 

//セル範囲選択

//xCellRange = xSheet.getCellRangeByName("A1"); //セルの名前でアクセスする場合

xCellRange = xSheet.getCellRangeByPosition(0, 0, 5, 5);

xPropSet = (XPropertySet)xCellRange;

 

//枠線オブジェクト

BorderLine aLine = new BorderLine();

//枠線の色を設定

int color = ColorTranslator.ToWin32(Color.Blue);

aLine.Color = color;

aLine.InnerLineWidth = 0;

aLine.LineDistance = 0;

aLine.OuterLineWidth = 10;

 

TableBorder aBorder = new TableBorder();

//ラインを設定

aBorder.TopLine = aLine;

aBorder.BottomLine = aLine;

aBorder.LeftLine = aLine;

aBorder.RightLine = aLine;

 

//選択セルRangeのどの辺にライン引くか設定

aBorder.IsTopLineValid = true;

aBorder.IsBottomLineValid = true;

aBorder.IsLeftLineValid = true;

aBorder.IsRightLineValid = true;

 

/*

選択されたセル範囲内のすべてのセルに垂直線を引くにはIsVerticalLineValidを、

* 水平線を引くには、IsHorizontalLineValidプロパティをTrueにします。

aBorder.IsHorizontalLineValid = true;

aBorder.IsVerticalLineValid = true;

aBorder.HorizontalLine = aBorder.TopLine;

aBorder.VerticalLine = aBorder.TopLine;

*/

 

//ここで実行

xPropSet.setPropertyValue("TableBorder", new uno.Any( typeof(TableBorder), aBorder));

注意すべきなのは、XSpreadsheet.getCellRangeByPosition() でセル範囲選択時の引数です。

この引数は、セル範囲左端インデックス,セル範囲上端インデックス,セル範囲右端インデックス,セル範囲下端インデックス という順番で、どの引数もA1セルからの絶対値であり、セル範囲選択開始セルからの相対値ではありません。

ここをついつい相対値と勘違いしてしまって unoidl.com.sun.star.lang.IndexOutOfBoundsException 例外を発生させまくってしまいました。

(例えば B2:C4 の範囲を選択するには、XSpreadsheet.SelectRangeByPosition(1, 1, 2, 3) とします。)