Kotlin Script で POI を使ってエクセルデータをつくる。 セルスタイルを設定してやることで、エクセルデータの表現力を増すことができる。 エクセルを人間が扱うものとして考えると、この辺は重要かつ便利な機能ではある。
出来上がりは、こんな感じ:
kotlin script の詳細はこちらのエントリー をご覧ください。
一番肝心のセルのスタイルをつくる部分のコード。 ボールドにするかどうか、フォントサイズ、フォントカラー、セル(の背景)色、を指定して Style オブジェクトを生成します:
val createCellStyle: (XSSFWorkbook, Boolean, Short, Short, Short)->XSSFCellStyle = { workbook, bold, fontSize, fontColor, cellColor->
val style = workbook.createCellStyle()
val font = workbook.createFont()
if( bold ){
font.setBold(true)
}
font.setColor(fontColor)
font.setFontHeightInPoints(fontSize)
style.setFont(font)
style.setFillForegroundColor( cellColor )
style.setFillPattern(FillPatternType.SOLID_FOREGROUND)
style
}
ポケモンのタイプに応じて、セルの色を切り替える部分はこれ:
val cellColor =
when(pokemonType) {
"Electric" -> IndexedColors.LIGHT_YELLOW.index
"Water" -> IndexedColors.PALE_BLUE.index
"Fire" -> IndexedColors.ORANGE.index
else -> IndexedColors.WHITE.index
}
タイプに応じてそれぞれの色を返す、という意味そのままなコードですが、この表現力は Kotlin の素敵なところですね。
xlsx.main.kts コード全体はこちら:
@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("org.apache.poi:poi:5.0.0")
@file:DependsOn("org.apache.poi:poi-ooxml:5.0.0")
import java.io.*
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.apache.poi.xssf.usermodel.XSSFCellStyle
import org.apache.poi.ss.usermodel.IndexedColors
import org.apache.poi.ss.usermodel.FillPatternType
val createCellStyle: (XSSFWorkbook, Boolean, Short, Short, Short)->XSSFCellStyle = { workbook, bold, fontSize, fontColor, cellColor->
val style = workbook.createCellStyle()
val font = workbook.createFont()
if( bold ){
font.setBold(true)
}
font.setColor(fontColor)
font.setFontHeightInPoints(fontSize)
style.setFont(font)
style.setFillForegroundColor( cellColor )
style.setFillPattern(FillPatternType.SOLID_FOREGROUND)
style
}
val cellStyleResolver: (XSSFWorkbook, Int, String)->XSSFCellStyle = { workbook, rowIndex, rowValue->
if( rowIndex==0 ){
// a cell style of header row:
createCellStyle(
workbook,
true,
20.toShort(),
IndexedColors.WHITE.index,
IndexedColors.GREY_80_PERCENT.index)
} else {
// a cell style of body rows:
val pokemonType = rowValue.split("/")[1]
val cellColor = when(pokemonType) {
"Electric" -> IndexedColors.LIGHT_YELLOW.index
"Water" -> IndexedColors.PALE_BLUE.index
"Fire" -> IndexedColors.ORANGE.index
else -> IndexedColors.WHITE.index
}
createCellStyle(
workbook,
false,
14.toShort(),
IndexedColors.BLACK.index,
cellColor)
}
}
val rowList = listOf(
"name/type",
"Pikachu/Electric",
"Eevee/Normal",
"Charmander/Fire",
"Electivire/Electric",
"Squirtle/Water")
val workbook = XSSFWorkbook()
val sheet = workbook.createSheet()
rowList.forEachIndexed { index, rowValue->
val row = sheet.createRow(index)
val style = cellStyleResolver(workbook, index, rowValue)
row.createCell(0).apply{
setCellValue( rowValue.split("/")[0] )
setCellStyle( style )
}
row.createCell(1).apply{
setCellValue( rowValue.split("/")[1] )
setCellStyle( style )
}
}
val outputStream = FileOutputStream(File("pokemon.xlsx"))
workbook.write(outputStream)
outputStream.close()
コードを動かすには、以下の通り。kotlin コマンドが使える必要があります。
$ kotlinc -script xlsx.main.kts