Jakarta Commonsつかいまくり(その2)

データベースのアクセスがすっきりした所で、次はExcelを読む事を考える。
CSV?TAB区切り? いやいや、もちろんここはJakartaのPOIを使わせていただきます。
以前にも使用した事があるのだが、その時は日本語の文字列をとってきた時に余計な空白が末尾についてしまうと言う、しかもシステムが稼働してから気がつくと言う失態をおかした事がある(笑)。今回は念のためにStringのtrim()をかけるようにする。
POIでExcelを読むのは非常に簡単。
ファイルを指定して、シートを指定して、行を指定して、セルを指定する。VBマクロみたいなもんだ。(やったことないけど。AppleScriptならある。)

//
InputStream instr = new FileInputStream(new File("hoge.xls"));
POIFSFileSystem fs = new POIFSFileSystem(instr);
instr.close();
//ワークブックをつくる。
HSSFWorkbook workbook = new HSSFWorkbook(fs);

//シートを指定する。
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFRow row = sheet.getRow((short) 0);
HSSFCell cell = row.getCell((short) 0);
String value = cell.getStringCellValue();

ここでやっているのは、Excelの最初のシートの最初のセル(A1)の文字列をとってきている事になる。
ただし、ここで注意。仮にExcelのセルの設定が「数値」となっていた場合、getStringCellValue()メソッドを呼ぶと例外が発生する。
入力した人間がずぼらな場合、もしくはExcelが余計な気を使ってしまった場合を考慮して、値を取得する前に念のためにセルタイプをとってきた方がベターであろう。

int cellType = cell.getCellType();
switch (cellType) {
	case HSSFCell.CELL_TYPE_STRING :
		str = cell.getStringCellValue();
		break;
	case HSSFCell.CELL_TYPE_NUMERIC :
		double d = cell.getNumericCellValue();
		str = String.valueOf((int) d);
		break;
	case HSSFCell.CELL_TYPE_BLANK :
		;

みたいなかんじでコーディングした方が安全。じっさいこのケースでもぼろぼろ出てきた・・(泣)

事の詳細は省くが、とにかくこんな感じでひたすら値を読み出し、先ほどDBのテーブルをJavaBeans化した(実際はちょっと違ってしまいましたが)Hogeオブジェクトに値をセットしまくるのだ。

ただ、ここで一つ困った事が出てきた。
電話番号である。Excel上では

03-1111-1111

のようなかたちで、一つの項目に入っているが、DB上(つまりHogeクラス)では

public class Hoge {
	protected String tel1;
	protected String tel2;
	protected String tel3;
}

になっている。つまり、文字列をハイフンでsplitしなければならない。
さぁ、どうする。ここまできたんだ。またもやJakarta Commonsに登場願おう!

ここで使用するのはCommons Lang。Langって言うぐらいだから、地味な(失礼・・有用な)クラスがまとまって入っている。
この中のStringUtilsに、splitメソッドがある。こいつをありがたく使わせていただく。

String phone="03-1111-1111";
String[] phones=StringUtils.split(phone,"-");
hoge.setTel1(phones[0]);
hoge.setTel2(phones[0]);
hoge.setTel3(phones[0]);

いいねぇ。StringTokenizerとかしなくてもいいんだ。ラクチンラクチン。
ただ、ここで問題が発覚・・。人によっては「半角ハイフン」で区切らずに、「全角ハイフン」で区切っているケースもあったのだ。
でも、こういうときも慌てず騒がず、ありがたくStringUtilsのお世話になる。

phone=StringUtils.replace(phone,"ー","-");
String[] phones=StringUtils.split(phone,"-");
hoge.setTel1(phones[0]);
hoge.setTel2(phones[0]);
hoge.setTel3(phones[0]);

このソースを見て怒る方もいるであろう。しかしこの場合はこれで良いのだ。
シビアさを求めるものでもなんでもないし、便利なものは積極的に使うのだ。

こんな感じで、見事Excelを読んで、DBに登録するアプリが完成した。
かかった時間・・・結局半日。調べながらやったのもあるが、予想以上にExcelデータがひどくて、エラー処理に手間どったという(笑)。
そんなこんなで、Commons万歳!