Excelで佐々木希を描く with Scala

これのあれです。
qiita.com

概要

これの他言語portとしてScala版をつくってみました。(もう本家投稿から2ヶ月も経ってた…
qiita.com
ScalaなのでExcelJavaライブラリであるApache POIを使って、セルの色塗りをしました。

環境

コード

import java.io._
import java.awt.Color

import org.apache.poi.xssf.usermodel.{XSSFColor, XSSFWorkbook}
import javax.imageio.ImageIO

import org.apache.poi.ss.usermodel.CellStyle

object main {
  val PixelHeight:Short = 35
  val PixelWidth:Short = 50
  val FilePrefix:String = "sasaki_nozomi"
  val XlsxPath:String = ".\\" + FilePrefix + "_scala.xlsx"
  val ImagePath:String = ".\\" + FilePrefix + ".jpg"

  def main(args: Array[String]): Unit = {
    val image = ImageIO.read(new File(ImagePath))
    val workbook = new XSSFWorkbook()
    workbook.createSheet(FilePrefix)
    val sheet = workbook.getSheetAt(0)
    val width = image.getWidth()
    val height = image.getHeight()
    for( j <- 0 until height ) {
      sheet.createRow(j)
      val row = sheet.getRow(j)
      row.setHeight(PixelHeight)
      for( i <- 0 until width ) {
        row.createCell(i)
        val cel = row.getCell(i)
        val pixel = image.getRGB(i, j)
        val color = new XSSFColor(this.getRGBArray(pixel))
        val style = workbook.createCellStyle()
        style.setFillPattern(CellStyle.SOLID_FOREGROUND)
        style.setFillForegroundColor(color)
        cel.setCellStyle(style)
      }
    }
    for( i <- 0 until width ) {
      sheet.setColumnWidth(i, PixelWidth)
    }

    val outfile = new java.io.FileOutputStream(XlsxPath)
    workbook.write(outfile)
    outfile.close()
  }
  def getRGBArray(pixel:Int):Color = {
    val r:Int = (pixel >> 16) & 0xff
    val g:Int = (pixel >> 8) & 0xff
    val b:Int = pixel & 0xff
    new Color(r,g,b)
  }
}

結果

f:id:bhind:20160810154925p:plain

ハマったこと・課題など

  • ハマった: IntelliJgithubへのリモートリポジトリの作成からpushまでが新規でできない(いまもできない)
  • ハマった: XSSFColorがRGBのbyte arrayコンストラクタを最初使ってたのだが、byteのMAX_VALUEって127やん?255入らんやん?負数つかうん?と思ってやめた(別のコンストラクタにした)
  • ハマった: セルの背景ぬるんだろとStyle::setFillBackgroundColorをよびつづけてた(正解はsetFillForegroundColorおよびパターン指定)
  • 課題: 行がすすむにつれて処理がすっごく重くなる。(小一時間以上かかる)メモリ上のXSSFWorkbookがボトルネックかと思い、20行ずつファイルに書き出してみるも結局速度変わらず。XSSWorkbookインスタンス構築でもうがっつりメモリに乗せちゃってるんだろうなと想像。
  • 良かったこと: IntelliJ買ってよかった(Eclipseのころより楽な気がした。まあ最近ずっとPhpStorm使ってたってのもあるけど)