<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>
LibreOfficeまたはApache OpenOfficeのCalcスプレッドシートを拡張機能を通してJavaまたはマクロプログラムから操作する(読むまたは書く)方法を知る
スプレッドシートセルに値をセットしよう。
オーケー。
セルに値が内部的にどのように保持されているかから推測できるように、値が文字列でも式でもない場合、値は、doubleの値としてセットできる。しかし、そうするためには、例えば、日付値をその日付値を表わすdouble値へと変換しなければならない。この変換ルールを我々は知らないので、我々は、別の方法で値をセットすることにする。
いいだろう。
日付値は、セルUNOオブジェクトのUNOコンポーネントが実装している'com.sun.star.table.XCell'UNOインターフェースの'setFormula'メソッドを使ってセットすることができる。
式をセットするわけでもないのに、'setFormula'メソッドを使うのか?
変だと思うかもしれないが、そう、そうする。セル値表現フォーマット(数値フォーマットと呼ばれているもの)をセットした後、'setFormula'メソッドを、引数にセル値表現文字列を渡して呼び出す。
ふーむ。
日付値、時刻値、日付時刻値、真偽値について、我々は、値をこの同じ方法でセットする。
整数値と小数値はどうする?
それらも同じ方法でセットできるが、それらは、直接、double値をセットすることにしよう。そうすれば、セル値表現文字列を作らなくてもよいから。
まあ、整数値と小数値については、それがより面倒でない方法だということは理解できる。
文字列値については、値を、セルUNOオブジェクトのUNOコンポーネントが実装している'com.sun.star.text.XText'UNOインターフェースの'insertString'メソッドを呼んでセットする。このメソッドを呼ぶためには、まず、セルUNOオブジェクトから、'com.sun.star.text.XText'UNOインターフェースを使って'com.sun.star.text.XTextCursor'インスタンス得る。
新たな文字列値を挿入する前に、まず、既存の値を取り除く必要はないのか?
既存のdouble値は自動的に破棄されるようだ。既存の文字列値については、我々は、'setFormula'メソッドを、引数に""を渡して呼んで、文字列を消去する。
文字列値を'setFormula'メソッドで直接セットできないのか?
文字列値が式として解釈できる場合(例えば、"= A8 + 1")、それは、文字列値としてではなく、式としてセットされるだろう。だから、我々は、文字列値を'setFormula'メソッドでセットしない。
ははあ。
doubleベースの値がセットされる場合も、文字列値は自動的に破棄されるのか?
そのようだ。
なるほど。
式は、'setFormula'メソッドを使ってセットできる。
ははあ。
結局、前記事のtryブロックの最後の位置に以下を書いた。
XPropertySet l_spreadSheetCellInXPropertySet = null;
XText l_spreadSheetCellInXText = null;
// set a formula to the cell 0, 0
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 0);
String l_formula = "= A8 + 1";
l_spreadSheetCell.setFormula (l_formula);
// set a date to the cell 0, 1
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 1);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
LocalDate l_date = LocalDate.parse ("2017-01-01", DateTimeFormatter.ISO_LOCAL_DATE);
String l_dateString = l_date.format (DateTimeFormatter.ISO_LOCAL_DATE);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_dateFormatIdentification));
l_spreadSheetCell.setFormula (l_dateString);
// set a time to the cell 0, 2
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 2);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
LocalTime l_time = LocalTime.parse ("01:02:03", DateTimeFormatter.ISO_LOCAL_TIME);
String l_timeString = l_time.format (DateTimeFormatter.ISO_LOCAL_TIME);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_timeFormatIdentification));
l_spreadSheetCell.setFormula (l_timeString);
// set a date time to the cell 0, 3
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 3);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
LocalDateTime l_dateTime = LocalDateTime.parse ("2017-01-01T01:02:03", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
String l_dateTimeString = l_dateTime.format (DateTimeFormatter.ISO_LOCAL_DATE_TIME);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_dateTimeFormatIdentification));
l_spreadSheetCell.setFormula (l_dateTimeString);
// set a boolean to the cell 0, 4
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 4);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
Boolean l_boolean = new Boolean (true);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_booleanFormatIdentification));
l_spreadSheetCell.setFormula (l_boolean.toString ());
// set a string to the cell 0, 5
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 5);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
l_spreadSheetCellInXText = (XText) UnoRuntime.queryInterface (XText.class, l_spreadSheetCell);
String l_string = "= A8 + 1";
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_textFormatIdentification));
l_spreadSheetCell.setFormula ("");
XTextCursor l_textCursor = l_spreadSheetCellInXText.createTextCursor();
l_spreadSheetCellInXText.insertString (l_textCursor, l_string, true);
// set a double to the cell 0, 6
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 6);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
Double l_double = new Double (1.1);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_doubleFormatIdentification));
l_spreadSheetCell.setValue (l_double.doubleValue ());
// set an integer to the cell 0, 7
l_spreadSheetCell = l_currentSpreadSheetInXSpreadsheet.getCellByPosition (0, 7);
l_spreadSheetCellInXPropertySet = (XPropertySet) UnoRuntime.queryInterface (XPropertySet.class, l_spreadSheetCell);
Integer l_integer = new Integer (1);
l_spreadSheetCellInXPropertySet.setPropertyValue("NumberFormat", new Integer (l_integerFormatIdentification));
l_spreadSheetCell.setValue (l_integer.intValue ());
また、以下のimportを追加した。
import com.sun.star.text.XTextCursor;
import com.sun.star.beans.PropertyVetoException;
それに、catchブロックに、以下の例外タイプを追加した。
com.sun.star.lang.IndexOutOfBoundsException
PropertyVetoException
ふーむ、第1列の上方のセル群に値をセットしている。
文字列値を'java.time.LocalDate'値に変換して、さらにこの'java.time.LocalDate'値を元の文字列に変換し直しているのはなぜなのか?
ああ、それは、将来のスプレッドシートセルラッパークラスで行なうことのシミュレーションだ。'java.time.LocalDate'の値を受け取り、この値をセルにセットする。
値を'java.lang.Object'として受け取り、データタイプを判定し、値をそのデータタイプに応じてセットするんだろう。
そうだ。