2011/09/21

[groovy] POIでExcelのセルの値を取得してみた

概要

GroovyからApache POIを使用してExcelのデータを読んでみました。
Excel持ってないので、OpenOfficeで作成したExcelデータですが。。。

内容

groovyでPOIを使用してセルのデータを読むコードをこんな感じで書いてみました。
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

class POIUtils {
    static def getCellValue(Sheet sheet, rowNum, colNum) {

        // nullセーフナビゲーションを使用してセルにアクセスする
        Cell cellObj = sheet?.getRow(rowNum)?.getCell(colNum)
        switch (cellObj) {
        case null:
            ""
            break;
        default:
            switch (cellObj.cellType) {
            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cellObj)) {
                    cellObj.getDateCellValue()
                } else {
                    cellObj.getNumericCellValue()
                }
                break;
            case Cell.CELL_TYPE_BLANK:
                ""
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                cellObj.getBooleanCellValue()
                break;
            case Cell.CELL_TYPE_ERROR:
                ""
                break;
            case Cell.CELL_TYPE_FORMULA:
                cellObj.getCellFormula()
                break;
            case Cell.CELL_TYPE_STRING:
                cellObj.getStringCellValue()
                break;
            }
        }
    }
}

上記を呼び出すソースは以下。
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

class Startup {
    static void main(args) {

        // ローンパターンを使用し、ストリーム使用後に安全にクローズする
        new FileInputStream("./resources/test.xls").withStream {fis ->
            Sheet sheet = WorkbookFactory.create(fis).getSheetAt(0)

            println(POIUtils.getCellValue(sheet, 0, 0));

            // groovy版のループを使用し、1行目から10行目までのセルの値を書き出す
            // TODO クロージャ内でfor文が使えない!!!
            // なぜかorg.codehaus.groovy.control.MultipleCompilationErrorsExceptionが発生。。。
            for (def i in 0..<10) {
                println(i.toString())
            }
        }
    }
}
上記ソース上のコメントにも書きましたが、クロージャ内でfor文を書くと org.codehaus.groovy.control.MultipleCompilationErrorsExceptionが発生しました。 なんで???意味不明です。書き方が悪いのかな。 もう少し調査します。 あと、POIUtilsの部分ももっと(?)groovyチックに書きたいです。 徐々に勉強しながらカスタマイズしていこう。 2011/09/22追記 クロージャ内のfor文はうまくいかなかったですが、以下のようにループを書いてやるとうまくいきました。 原因は不明です。
//            for (def i in 0..<10) {
//                println(i.toString())
//            }
            10.times {
                println(POIUtils.getCellValue(sheet, it, 0));
            }
           for (int i = 0; i < 10; i++) {
                println(POIUtils.getCellValue(sheet, i, 0))
            }

クロージャ内の制御文は失敗する仕様なのかも知れない。。。
原因分かればまた追記します。

ただ単に構文ミスってようです。
これで動作しました。

2 件のコメント:

  1. GExcelAPIというnobeansさんという世界的にも有名な開発者の方
    (勿論fumokmmさんと同じJGGUGのスタッフ)
    が作られたGroovyのpoiのラッパーが既にありますので
    そちらを使われると大分楽になります。
    http://d.hatena.ne.jp/nobeans/20101216/1292513322

    自分が試した例等は
    https://gist.github.com/1216787
    https://gist.github.com/1221382
    あたり

    あともう少し勉強を進めていくと
    SwingBuilderというSwingのラッパー辺りを触ると楽しくなると思います
    <kiy0takaさんというJGGUGの方が一番詳しいです

    返信削除
  2. kimukouさん

    >GExcelAPIというnobeansさんという世界的にも有名な開発者の方
    (勿論fumokmmさんと同じJGGUGのスタッフ)
    既にPOIのラッパーがあったんですね。
    サンプル等を見てみると使いやすそうで、すてきな感じですね。

    返信削除