LoginSignup
8
4

More than 3 years have passed since last update.

kotlinでExcelからデータを読み込む

Posted at

kotlinからExcelを操作する機会があったのでメモ。
コード全文はgitにあげてます。

環境

  • JDK: 1.8
  • kotlin: 1.3

準備

Apache POIを利用します。
build.gradleのdependenciesに以下の行を追加します。

build.gradle
compile 'org.apache.poi:poi-ooxml:4.1.0'

また、テスト用に以下のExcelファイルを用意します。
image.png

Workbook,Worksheetの取得

val file = Paths.get("PoiSampleWorkbook.xlsx").toFile()
val book = WorkbookFactory.create(file)
val sheet = book.getSheet("Sheet1")

シート内の全てのデータを読み込む

以下のように行、列をシーケンスとして取得できます。

sheet.rowIterator().asSequence().forEach { row ->
    val values = row.cellIterator().asSequence().map { cell ->
        when (cell.cellType) {
            CellType.NUMERIC -> cell.numericCellValue.toString()
            CellType.STRING -> cell.stringCellValue
            else -> throw RuntimeException("CellType=${cell.cellType}]")
        }
    }
    println(values.toList())
}
結果
[商品名, 価格]
[商品A, 5000.0]
[商品B, 7000.0]
[商品C, 10000.0]

ちなみに、CellTypeが数値のセルをstringCellValueで取得しようとすると以下のように怒られます。

Exception in thread "main" java.lang.IllegalStateException: Cannot get a STRING value from a NUMERIC cell

シート内の任意のセルの値を読み込む

データの存在しない行、列を取得しようとするとnullが返されます。

// indexは0オリジン
val row = sheet.getRow(1)
if (row != null) {
    val cell = row.getCell(0)
    if (cell != null) {
        println(cell.stringCellValue)
    }
}
結果
商品A

またはCellUtilを利用すれば、存在しないセルを取得してもnullではなく空のセルを取得できます。

// indexは0オリジン
val row = CellUtil.getRow(1, sheet)
val cell = CellUtil.getCell(row, 0)
println(cell.stringCellValue)

// 存在しないセルを指定してもぬるぽにならず、CellType.BLANKのセルが取得できる
val row2 = CellUtil.getRow(999, sheet)
val cell2 = CellUtil.getCell(row2, 999)
println("CellType=${cell2.cellType}, value=${cell2.stringCellValue}")
結果
商品A
CellType=BLANK, value=

拡張関数でVBAっぽく

通常の使い方だとわざわざ行->列の順で取得しないといけないので面倒ですが、kotlinの拡張関数を使えばVBAのCellsっぽいことができます。

fun Sheet.cells(row: Int = 0, col: Int = 0) = CellUtil.getCell(CellUtil.getRow(row, this), col)
fun Cell.value() = when (cellType) {
    CellType.NUMERIC -> numericCellValue.toString()
    CellType.STRING -> stringCellValue
    else -> throw RuntimeException("CellType=$cellType]")
}

println(sheet.cells(1, 0).value())
println(sheet.cells(1, 1).value())
結果
商品A
5000.0

参考

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4