S2TestCaseでEXCELを読み込む場合にというかJakartaPOI

S2Container 2.3.15に含まれるS2TestCaseを利用してEXCELファイルからデータを読み込む場合、
EXCELファイルにオートフィルタが設定されていると例外が発生するようです。

     [java] Caused by: org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance, the following exception occured: null
     [java]     at org.apache.poi.hssf.record.RecordFactory.createRecord(RecordFactory.java:237)
     [java]     at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:160)
     [java]     at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:163)
     [java]     at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:210)
     [java]     at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:191)
     [java]     at org.seasar.extension.dataset.impl.XlsReader.<init>(XlsReader.java:73)
     [java]     at org.seasar.extension.dataset.impl.XlsReader.<init>(XlsReader.java:68)

#S2TestCaseでデータベースを使ったユニットテストについては、
こちらを参照。

reload(DataSet)を使って、データの中身をプライマリーキーでリロードして新しいDataSetを取得できます。更新後の予想される結果をExcelで定義しておき、DataSet expected = readXls("予想される結果.xls");assertEquals(expected, reload(expected);のようにして簡単に更新のテストができます。

この機能はJakarta POIを利用して実装されていますが、このPOIが悪さをしているようです。
S2Container 2.3.15ではpoi-2.5.1-final-20040804.jarを使っているようです。

とりあえず、Jakarta POIのダウンロードページから、
開発版をダウンロードして入れ替えると例外は発生しなくなります。


http://www.meisei-u.ac.jp/mirror/apache/dist/jakarta/poi/dev/bin/poi-bin-3.0-alpha2-20060616.zip

XlsReaderもXlsWriterも今のところ影響なく動いているので大丈夫でしょう。

  • org.seasar.extension.dataset.impl.XlsReader#read
  • org.seasar.extension.dataset.impl.XlsWriter#write

レコード数が多いテストデータを使った場合にEXCELに用意したデータを整理していたら遭遇しました。



余談ですが、このEXCELを使ったさまざまな機能は、データベース処理のテストにとっても便利なのです。

下記は利用例のコードです。
org.seasar.extension.dataset.DataSetあたりは情報が少ないので参考になればと思います。

package test.org.seasar.extension.dataset;

import org.seasar.dao.unit.S2DaoTestCase;
import org.seasar.extension.dataset.DataReader;
import org.seasar.extension.dataset.DataRow;
import org.seasar.extension.dataset.DataSet;
import org.seasar.extension.dataset.DataTable;
import org.seasar.extension.dataset.DataWriter;
import org.seasar.extension.dataset.impl.SqlWriter;
import org.seasar.extension.dataset.impl.XlsReader;
import org.seasar.extension.dataset.impl.XlsWriter;

public class XlsReaderTest extends S2DaoTestCase {

	final String XLS_IN = "HOGE_IN.xls";

	final String XLS_OUT = "HOGE_OUT.xls";

	public void setUp() {
		include("test/j2ee.dicon");
		setupDataSource();
	}

	/**
	 * EXCELファイルを読み込んでデータベースに登録して別のEXCELに書き出すテスト
	 * メソッド名の末尾に『Tx』をつけるとトランザクションをロールバックしてくれる。
	 */
	public void testReadTx() {
		// Excelファイルを読み込んで、DataSetに展開する
		// テーブル名=シート名
		// カラム名=1行目のセル
		// データ=2行目以降のセル
		DataReader reader = new XlsReader(convertPath(XLS_IN));
		DataSet ds = reader.read();

		// テーブル数分繰り返し
		for (int i = 0; i < ds.getTableSize(); i++) {
			DataTable dt = ds.getTable(i);
			String tableName = dt.getTableName();

			System.out.println("TableName = " + tableName);

			for (int j = 0; j < dt.getRowSize(); j++) {
				DataRow dr = dt.getRow(k);

				String buf = "DataRow[";
				for (int k = 0; k < dt.getColumnSize(); k++) {
					String columnName = dt.getColumnName(k); // カラム名
					buf += columnName + " = ";
					buf += dr.getValue(columnName);
					buf += ",";
				}
				buf += "]";
			}
		}
		// SqlWriterは、DataSetをテーブルに追加挿入する機能
		DataWriter writer = new SqlWriter(getDataSource());
		writer.write(ds);

		// XlsWriterは、DataSetをEXCELファイルに作成する機能
		DataWriter xlsWriter = new XlsWriter(convertPath(XLS_OUT));
		xlsWriter.write(ds);
	}
}