scala/basic
apache poi 를 사용해 scala 에서 Excel 파일 읽기
wefree
2021. 10. 14. 11:17
def main(args: Array[String]): Unit = {
val rows = readSheet[MyModel]("c:/work/input.xlsx", "평가 항목", true)
println(rows)
}
문제
apache poi 를 사용해 Excel 파일을 읽어보자. apache poi 는 자바 라이브러리지만 스칼라 스타일로 코딩해 보도록 한다.
코드
일반적으로 사용할 수 있도록 아래처럼 Generic 한 util 을 작성한다.
import org.apache.poi.openxml4j.opc.OPCPackage
import org.apache.poi.ss.usermodel.{Row, Workbook}
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.File
import scala.collection.JavaConverters._
trait RowConverter[A] {
def from(row: Row): A
}
object ExcelUtil {
def readSheet[A: RowConverter](path: String, sheetName: String, hasHeader: Boolean): Seq[A] = {
val rowConverter = implicitly[RowConverter[A]]
val pkg = OPCPackage.open(new File(path))
val workbook: Workbook = new XSSFWorkbook(pkg)
val sheet = workbook.getSheet(sheetName)
val rows: Iterator[Row] = sheet.iterator().asScala
// header 제거
val convertedRows: Seq[A] = rows
.filterNot(hasHeader && _.getRowNum == 0)
.map(rowConverter.from)
.toList
workbook.close()
pkg.close()
convertedRows
}
}
사용 목적에 맞게 모델링 하고, implicit instance 를 구현해 준다.
import org.apache.poi.ss.usermodel.Row
case class MyModel(
no: Int,
keyword: String,
residence: Option[String]
)
object MyModel {
implicit val rowConverterInstance: RowConverter[MyModel] = new RowConverter[MyModel] {
override def from(row: Row): MyModel = {
val no = row.getCell(0).getNumericCellValue.toInt
val keyword = row.getCell(1).getStringCellValue
val residence = Option(row.getCell(2)).map(_.getStringCellValue)
MyModel(no, keyword, residence)
}
}
}
마지막으로 아래처럼 사용하면 된다.
def main(args: Array[String]): Unit = {
val convertedRows: Seq[MyModel] = readSheet[MyModel]("c:/now/input.xlsx", "평가 항목", true)
println(convertedRows)
}