├── .gitignore ├── .scalafmt.conf ├── .travis.yml ├── LICENSE ├── README.md ├── build.sbt ├── codecov.yml ├── deps.sbt ├── project ├── build.properties ├── plugins.sbt └── sbt-launch-0.13.7.jar ├── src ├── main │ ├── scala-2.12 │ │ └── CollectionCompat.scala │ ├── scala-2.13 │ │ └── CollectionCompat.scala │ └── scala │ │ └── net │ │ └── scalax │ │ └── cpoi │ │ ├── api │ │ └── package.scala │ │ ├── content │ │ ├── CellContent.scala │ │ └── CellData.scala │ │ ├── exception │ │ └── CellTypeNotConfirmException.scala │ │ ├── rw │ │ ├── CPoiDone.scala │ │ ├── CellReader.scala │ │ ├── CellWriter.scala │ │ └── impl │ │ │ ├── CellReadersImpl.scala │ │ │ ├── CellReadersImplicits.scala │ │ │ ├── CellWritersImpl.scala │ │ │ ├── CellWritersImplicits.scala │ │ │ ├── ImmutableCellReadersImpl.scala │ │ │ └── ImmutableCellReadersImplicits.scala │ │ ├── style │ │ ├── MutableStyleGen.scala │ │ ├── StyleGen.scala │ │ ├── StyleKeyWrap.scala │ │ └── StyleTransform.scala │ │ └── utils │ │ ├── Alias.scala │ │ └── CPoi.scala └── test │ ├── resources │ └── test01.xls │ └── scala │ └── net │ └── scalax │ └── cpoi │ ├── poi │ ├── HSSFWorkbookLawBooleanCellTest.scala │ ├── HSSFWorkbookLawNumbricCellTest.scala │ └── HSSFWorkbookLawStringCellTest.scala │ ├── read │ ├── HSSFWorkbookBlankCellTest.scala │ ├── HSSFWorkbookBlankStringCellTest.scala │ ├── HSSFWorkbookBooleanFormulaCellTest.scala │ ├── HSSFWorkbookEmptyStringCellTest.scala │ ├── HSSFWorkbookFalseBooleanCellTest.scala │ ├── HSSFWorkbookNotBlankStringCellTest.scala │ ├── HSSFWorkbookNullCellTest.scala │ ├── HSSFWorkbookNumbericCellTest1.scala │ ├── HSSFWorkbookNumbericCellTest2.scala │ ├── HSSFWorkbookNumbricFormulaCellTest.scala │ ├── HSSFWorkbookOptionReaderTest.scala │ ├── HSSFWorkbookStringFormulaCellTest.scala │ └── HSSFWorkbookTrueBooleanCellTest.scala │ └── write │ └── HSSFWorkbookMemoryWriterTest.scala └── version.sbt /.gitignore: -------------------------------------------------------------------------------- 1 | *target 2 | *.idea 3 | /logs 4 | /sbt 5 | /sbt.bat 6 | /sbt-launch.jar 7 | *.sbtserver* -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | maxColumn = 160 2 | align = more 3 | continuationIndent.defnSite = 2 4 | lineEndings = unix 5 | optIn.breakChainOnFirstMethodDot = false 6 | rewrite.rules = [SortImports] 7 | poorMansTrailingCommasInConfigStyle = true 8 | version = 2.0.0-RC8 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: scala 2 | sudo: required 3 | dist: trusty 4 | 5 | scala: 6 | - 2.12.8 7 | - 2.13.1 8 | 9 | jdk: 10 | - oraclejdk8 11 | 12 | cache: 13 | directories: 14 | - $HOME/.ivy2/cache 15 | - $HOME/.sbt/boot 16 | - $HOME/.coursier 17 | 18 | before_install: 19 | - pip install --user codecov 20 | 21 | script: 22 | - sbt +test 23 | - sbt clean coverage test coverageReport 24 | 25 | after_success: 26 | - bash <(curl -s https://codecov.io/bash) 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Scala China 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | poi-collection 2 | ============================================ 3 | [ ![Download](https://api.bintray.com/packages/djx314/maven/poi-collection/images/download.svg) ](https://bintray.com/djx314/maven/poi-collection/_latestVersion) 4 | [![codecov](https://codecov.io/gh/scalax/poi-collection/branch/master/graph/badge.svg)](https://codecov.io/gh/scalax/poi-collection) 5 | [![Build Status](https://travis-ci.org/scalax/poi-collection.svg?branch=master)](https://travis-ci.org/scalax/poi-collection) 6 | 7 | A Scala wrapper for Apache POI's Excel API. 8 | 9 | [Chinese documentation](https://github.com/scalax/poi-collection-chinese-documentation) 10 | 11 | How to get it 12 | ------------- 13 | 14 | - Add dependency 15 | 16 | ```scala 17 | resolvers += Resolver.bintrayRepo("djx314", "maven") 18 | libraryDependencies += "net.scalax" %% "poi-collection" % "0.4.0-M8" 19 | ``` 20 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | //bintrayOrganization := Some("scalax") 2 | //bintrayRepository := "poi-collection" 3 | 4 | resolvers += Resolver.jcenterRepo 5 | 6 | resolvers += Resolver.bintrayRepo("djx314", "maven") 7 | 8 | licenses += ("MIT", url("http://opensource.org/licenses/MIT")) 9 | bintrayVcsUrl := Some("git@github.com:scalax/poi-collection.git") 10 | bintrayPackageLabels := Seq("scala", "poi") 11 | organization := "net.scalax" 12 | name := "poi-collection" 13 | 14 | scalaVersion := "2.13.1" 15 | crossScalaVersions := Seq("2.13.1", "2.12.10") 16 | 17 | scalacOptions ++= Seq("-feature", "-deprecation") 18 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | token: d211f2c4-e623-4911-9216-ec516a9394a8 -------------------------------------------------------------------------------- /deps.sbt: -------------------------------------------------------------------------------- 1 | libraryDependencies += "org.typelevel" %% "cats-core" % "2.1.0" 2 | 3 | val poiVersion = "4.1.1" 4 | 5 | libraryDependencies ++= { 6 | Seq( 7 | //poi 8 | "org.apache.poi" % "poi" % poiVersion exclude ("stax", "stax-api") 9 | , "org.apache.poi" % "poi-ooxml" % poiVersion exclude ("stax", "stax-api") 10 | , "org.apache.poi" % "poi-ooxml-schemas" % poiVersion exclude ("stax", "stax-api") 11 | ) 12 | } 13 | 14 | libraryDependencies += "org.apache.commons" % "commons-math3" % "3.6.1" 15 | 16 | libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.8" 17 | libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test" 18 | 19 | libraryDependencies += "org.scala-lang.modules" %% "scala-collection-compat" % "2.1.3" 20 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.6 -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.1") 2 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") 3 | addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.5") 4 | addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.11") 5 | -------------------------------------------------------------------------------- /project/sbt-launch-0.13.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalax/poi-collection/bd9fcbca77441fd4d872ae4a2a487361d9644726/project/sbt-launch-0.13.7.jar -------------------------------------------------------------------------------- /src/main/scala-2.12/CollectionCompat.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.utils.compat 2 | 3 | import scala.collection.compat._ 4 | 5 | object CollectionCompat { 6 | 7 | type LazyList[T] = scala.collection.immutable.Stream[T] 8 | def seqToLazyList[T](seq: Seq[T]): LazyList[T] = seq.toStream 9 | 10 | def mapFromMutable[T1, T2](map: scala.collection.mutable.Map[T1, T2]): Map[T1, T2] = Map.from(map) 11 | def mapFromImmutable[T1, T2](map: Map[T1, T2]): scala.collection.mutable.Map[T1, T2] = scala.collection.mutable.Map.from(map) 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/scala-2.13/CollectionCompat.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.utils.compat 2 | 3 | object CollectionCompat { 4 | 5 | type LazyList[T] = scala.collection.immutable.LazyList[T] 6 | def seqToLazyList[T](seq: Seq[T]): LazyList[T] = seq.to(LazyList) 7 | 8 | def mapFromMutable[T1, T2](map: scala.collection.mutable.Map[T1, T2]): Map[T1, T2] = map.to(Map) 9 | def mapFromImmutable[T1, T2](map: scala.collection.immutable.Map[T1, T2]): scala.collection.mutable.Map[T1, T2] = map.to(scala.collection.mutable.Map) 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/api/package.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi 2 | 3 | import net.scalax.cpoi.utils.Alias 4 | 5 | package object api extends Alias 6 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/content/CellContent.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.content 2 | 3 | import net.scalax.cpoi.rw.{CellReader, CellWriter} 4 | 5 | import org.apache.poi.ss.usermodel.{Cell, CellStyle, CellType} 6 | 7 | import scala.util.Try 8 | 9 | trait CellContentAbs { 10 | 11 | val poiCell: Option[Cell] 12 | 13 | def isBlank: Boolean = 14 | poiCell.map(_.getCellType == CellType.BLANK).getOrElse(true) 15 | 16 | def cellType: Option[CellType] = 17 | Try(poiCell.map(_.getCellType)).toOption.flatten 18 | 19 | def cellStyle: Option[CellStyle] = poiCell.map(_.getCellStyle) 20 | 21 | lazy val rowIndex: Option[Int] = poiCell.map(_.getRowIndex) 22 | lazy val columnIndex: Option[Int] = poiCell.map(_.getColumnIndex) 23 | 24 | def genData[T: CellWriter: CellReader]: CellReader.CellReadResult[CellData[T]] = { 25 | val valueEt = CellReader[T].get(poiCell) 26 | valueEt.map(s => CellDataImpl(s, List.empty)) 27 | } 28 | 29 | def tryValue[T: CellReader]: CellReader.CellReadResult[T] = { 30 | CellReader[T].get(poiCell) 31 | } 32 | 33 | } 34 | 35 | object CellContentAbs { 36 | 37 | implicit class CellContentOptExtensionMethon(cellOpt: Option[CellContentAbs]) { 38 | 39 | def openAlways: CellContentAbs = { 40 | cellOpt match { 41 | case Some(s) => s 42 | case _ => 43 | new CellContentAbs { 44 | override val poiCell = Option.empty 45 | } 46 | } 47 | } 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/content/CellData.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.content 2 | 3 | import net.scalax.cpoi.rw.{CPoiDone, CellWriter} 4 | import net.scalax.cpoi.style.StyleTransform 5 | import org.apache.poi.ss.usermodel.Cell 6 | 7 | import scala.util.Try 8 | import scala.collection.compat._ 9 | 10 | trait CellDataAbs { 11 | self => 12 | 13 | type DataType 14 | val data: DataType 15 | 16 | protected val operation: CellWriter[DataType] 17 | 18 | def untyped: CellDataAbs = self 19 | 20 | val styleTransform: List[StyleTransform] 21 | 22 | def set(cell: Cell): Try[CPoiDone] = { 23 | operation.setValue(cell, data) 24 | } 25 | 26 | def withTransforms(trans: List[StyleTransform]): CellDataAbs = { 27 | implicit val operation1 = self.operation 28 | CellDataImpl(data, trans) 29 | } 30 | 31 | def withTransforms(trans: StyleTransform*): CellDataAbs = { 32 | implicit val operation1 = self.operation 33 | CellDataImpl(data, trans.to(List)) 34 | } 35 | 36 | def addTransform(tran: List[StyleTransform]): CellDataAbs = { 37 | implicit val operation1 = self.operation 38 | val thisTrans = this.styleTransform 39 | CellDataImpl(data, thisTrans ::: tran) 40 | } 41 | 42 | def addTransform(tran: StyleTransform*): CellDataAbs = { 43 | implicit val operation1 = self.operation 44 | val thisTrans = this.styleTransform 45 | CellDataImpl(data, thisTrans ::: tran.to(List)) 46 | } 47 | 48 | } 49 | 50 | trait CellData[T] extends CellDataAbs { 51 | self => 52 | 53 | override val data: T 54 | override val styleTransform: List[StyleTransform] 55 | 56 | override type DataType = T 57 | 58 | override protected val operation: CellWriter[T] 59 | 60 | override def untyped: CellDataAbs = self 61 | 62 | override def withTransforms(trans: List[StyleTransform]): CellData[T] = { 63 | implicit val operation1 = self.operation 64 | CellDataImpl(data, trans) 65 | } 66 | 67 | override def withTransforms(trans: StyleTransform*): CellData[T] = { 68 | implicit val operation1 = self.operation 69 | CellDataImpl(data, trans.to(List)) 70 | } 71 | 72 | override def addTransform(tran: List[StyleTransform]): CellData[T] = { 73 | val thisTrans = this.styleTransform 74 | implicit val operation1 = self.operation 75 | CellDataImpl(data, thisTrans ::: tran) 76 | } 77 | 78 | override def addTransform(tran: StyleTransform*): CellData[T] = { 79 | val thisTrans = this.styleTransform 80 | implicit val operation1 = self.operation 81 | CellDataImpl(data, thisTrans ::: tran.to(List)) 82 | } 83 | 84 | } 85 | 86 | case class CellDataImpl[T](override val data: T, override val styleTransform: List[StyleTransform] = List.empty)( 87 | implicit 88 | override val operation: CellWriter[T] 89 | ) extends CellData[T] 90 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/exception/CellTypeNotConfirmException.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.exception 2 | 3 | sealed trait CellReaderException extends Exception {} 4 | 5 | trait CellNotConfirmException extends CellReaderException {} 6 | 7 | class CellNotExistsException extends Exception("Cell not found.") with CellReaderException {} 8 | 9 | sealed trait CellTypeNotConfirmException extends CellReaderException {} 10 | 11 | class ExpectFormulaException extends Exception("Expect formula cell.") with CellTypeNotConfirmException { 12 | def this(cause: Throwable) = { 13 | this() 14 | initCause(cause) 15 | } 16 | } 17 | 18 | class ExpectNumericCellException extends Exception("Expect numeric cell.") with CellTypeNotConfirmException { 19 | def this(cause: Throwable) = { 20 | this() 21 | initCause(cause) 22 | } 23 | } 24 | 25 | class ExpectDateException extends Exception("Expect date cell.") with CellTypeNotConfirmException { 26 | def this(cause: Throwable) = { 27 | this() 28 | initCause(cause) 29 | } 30 | } 31 | 32 | class ExpectRichTextException extends Exception("Expect rich text cell.") with CellTypeNotConfirmException { 33 | def this(cause: Throwable) = { 34 | this() 35 | initCause(cause) 36 | } 37 | } 38 | 39 | class ExpectStringCellException extends Exception("Expect string cell.") with CellTypeNotConfirmException { 40 | def this(cause: Throwable) = { 41 | this() 42 | initCause(cause) 43 | } 44 | } 45 | 46 | class ExpectBooleanCellException extends Exception("Expect boolean cell.") with CellTypeNotConfirmException { 47 | def this(cause: Throwable) = { 48 | this() 49 | initCause(cause) 50 | } 51 | } 52 | 53 | class ExpectErrorCellException extends Exception("Expect error cell.") with CellTypeNotConfirmException { 54 | def this(cause: Throwable) = { 55 | this() 56 | initCause(cause) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/CPoiDone.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | class CPoiDone 4 | 5 | object CPoiDone { 6 | val instance: CPoiDone = new CPoiDone 7 | } 8 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/CellReader.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import cats._ 4 | import net.scalax.cpoi.exception._ 5 | import org.apache.poi.ss.usermodel.Cell 6 | import cats.implicits._ 7 | 8 | trait CellReader[T] { 9 | 10 | def get(cell: Option[Cell]): CellReader.CellReadResult[T] 11 | 12 | } 13 | 14 | object CellReader { 15 | 16 | def apply[T: CellReader]: CellReader[T] = implicitly 17 | 18 | type CellReadResult[R] = Either[CellReaderException, R] 19 | 20 | implicit def optionCellReaderToNoneOptionCellReader[T: CellReader]: CellReader[Option[T]] = { 21 | CellReader[T].map(Option(_)).recover { 22 | case _: CellNotExistsException => 23 | Option.empty 24 | } 25 | } 26 | 27 | implicit val monadError: MonadError[CellReader, CellReaderException] = 28 | new MonadError[CellReader, CellReaderException] with StackSafeMonad[CellReader] { 29 | 30 | override def map[A, B](fa: CellReader[A])(f: A => B): CellReader[B] = { 31 | new CellReader[B] { 32 | def get(cell: Option[Cell]): CellReadResult[B] = { 33 | fa.get(cell).map(f) 34 | } 35 | } 36 | } 37 | 38 | override def pure[A](x: A): CellReader[A] = new CellReader[A] { 39 | def get(cell: Option[Cell]): CellReadResult[A] = { 40 | Right(x) 41 | } 42 | } 43 | 44 | override def flatMap[A, B](fa: CellReader[A])(f: A => CellReader[B]): CellReader[B] = new CellReader[B] { 45 | def get(cell: Option[Cell]): CellReadResult[B] = { 46 | fa.get(cell).flatMap(s => f(s).get(cell)) 47 | } 48 | } 49 | 50 | override def raiseError[A](e: CellReaderException): CellReader[A] = 51 | new CellReader[A] { 52 | def get(cell: Option[Cell]): CellReadResult[A] = { 53 | Left(e) 54 | } 55 | } 56 | 57 | override def handleError[A](fa: CellReader[A])(f: CellReaderException => A): CellReader[A] = new CellReader[A] { 58 | def get(cell: Option[Cell]): CellReadResult[A] = { 59 | fa.get(cell) match { 60 | case Left(e) => 61 | Right(f(e)) 62 | case r @ Right(_) => 63 | r 64 | } 65 | } 66 | } 67 | 68 | override def handleErrorWith[A](fa: CellReader[A])(f: CellReaderException => CellReader[A]): CellReader[A] = 69 | new CellReader[A] { 70 | def get(cell: Option[Cell]): CellReadResult[A] = { 71 | fa.get(cell) match { 72 | case Left(e) => 73 | f(e).get(cell) 74 | case r @ Right(_) => 75 | r 76 | } 77 | } 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/CellWriter.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import cats.Contravariant 4 | import org.apache.poi.ss.usermodel.Cell 5 | 6 | import scala.util.Try 7 | 8 | trait CellWriter[T] { 9 | def setValue(cell: Cell, value: T): Try[CPoiDone] 10 | } 11 | 12 | object CellWriter { 13 | 14 | def apply[T: CellWriter]: CellWriter[T] = implicitly 15 | 16 | implicit def optionCellOperationToNoneOptionCellOpreation[T: CellWriter]: CellWriter[Option[T]] = { 17 | new CellWriter[Option[T]] { 18 | override def setValue(cell: Cell, value: Option[T]): Try[CPoiDone] = { 19 | value 20 | .map { v => 21 | CellWriter[T].setValue(cell, v) 22 | } 23 | .getOrElse(Try { CPoiDone.instance }) 24 | } 25 | } 26 | } 27 | 28 | implicit val contravariant: Contravariant[CellWriter] = { 29 | new Contravariant[CellWriter] { 30 | override def contramap[A, B](fa: CellWriter[A])(f: B => A): CellWriter[B] = { 31 | new CellWriter[B] { 32 | override def setValue(cell: Cell, value: B): Try[CPoiDone] = { 33 | Try { f(value) }.flatMap(s => fa.setValue(cell, s)) 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/CellReadersImpl.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import java.util.Date 4 | 5 | import cats.ApplicativeError 6 | import net.scalax.cpoi.exception._ 7 | import org.apache.poi.ss.usermodel.{Cell, CellType} 8 | import cats.implicits._ 9 | 10 | trait CellReadersImpl { 11 | 12 | def nonBlankStringReader: CellReader[String] = { 13 | 14 | val m = ApplicativeError[CellReader, CellReaderException] 15 | 16 | stringReader.flatMap { str => 17 | val trimStr = str.trim 18 | 19 | val either = if (trimStr.isEmpty) { 20 | Left(new CellNotExistsException()) 21 | } else { 22 | Right(trimStr) 23 | } 24 | 25 | m.fromEither(either) 26 | } 27 | 28 | } 29 | 30 | def nonEmptyStringReader: CellReader[String] = { 31 | 32 | val m = ApplicativeError[CellReader, CellReaderException] 33 | 34 | stringReader.flatMap { str => 35 | val trimStr = str 36 | 37 | val either = if (trimStr.isEmpty) { 38 | Left(new CellNotExistsException()) 39 | } else { 40 | Right(trimStr) 41 | } 42 | 43 | m.fromEither(either) 44 | } 45 | 46 | } 47 | 48 | def stringReader: CellReader[String] = new CellReader[String] { 49 | self => 50 | 51 | override def get(cell: Option[Cell]): CellReader.CellReadResult[String] = { 52 | cell match { 53 | case Some(c) => 54 | c.getCellType match { 55 | case CellType.BLANK => 56 | Right(c.getStringCellValue) 57 | case CellType.STRING => 58 | Right(c.getStringCellValue) 59 | case CellType.NUMERIC => 60 | c.setCellType(CellType.STRING) 61 | Right(c.getStringCellValue) 62 | //convert boolean to string is meaningless. 63 | //case CellType.BOOLEAN => 64 | //c.setCellType(CellType.STRING) 65 | //Right(c.getStringCellValue) 66 | case CellType.FORMULA => 67 | val wb = c.getSheet.getWorkbook 68 | val crateHelper = wb.getCreationHelper 69 | val evaluator = crateHelper.createFormulaEvaluator 70 | self.get(Option(evaluator.evaluateInCell(c))) 71 | case _ => 72 | Left(new ExpectStringCellException()) 73 | } 74 | case _ => 75 | //read null as empty cell 76 | Right("") 77 | } 78 | } 79 | } 80 | 81 | def doubleReader: CellReader[Double] = new CellReader[Double] { 82 | self => 83 | 84 | override def get(cell: Option[Cell]): CellReader.CellReadResult[Double] = { 85 | cell match { 86 | case Some(c) => 87 | c.getCellType match { 88 | case CellType.BLANK => 89 | Left(new CellNotExistsException()) 90 | case CellType.NUMERIC => 91 | Right(c.getNumericCellValue) 92 | case CellType.FORMULA => 93 | val wb = c.getSheet.getWorkbook 94 | val crateHelper = wb.getCreationHelper 95 | val evaluator = crateHelper.createFormulaEvaluator 96 | self.get(Option(evaluator.evaluateInCell(c))) 97 | case _ => 98 | Left(new ExpectNumericCellException()) 99 | } 100 | case _ => 101 | Left(new CellNotExistsException()) 102 | } 103 | } 104 | } 105 | 106 | def booleanReader: CellReader[Boolean] = new CellReader[Boolean] { 107 | self => 108 | 109 | override def get(cell: Option[Cell]): CellReader.CellReadResult[Boolean] = { 110 | cell match { 111 | case Some(c) => 112 | c.getCellType match { 113 | case CellType.BLANK => 114 | Left(new CellNotExistsException()) 115 | case CellType.BOOLEAN => 116 | Right(c.getBooleanCellValue) 117 | case CellType.FORMULA => 118 | val wb = c.getSheet.getWorkbook 119 | val crateHelper = wb.getCreationHelper 120 | val evaluator = crateHelper.createFormulaEvaluator 121 | self.get(Option(evaluator.evaluateInCell(c))) 122 | case _ => 123 | Left(new ExpectBooleanCellException()) 124 | } 125 | case _ => 126 | Left(new CellNotExistsException()) 127 | } 128 | } 129 | } 130 | 131 | def dateReader: CellReader[Date] = new CellReader[Date] { 132 | self => 133 | 134 | override def get(cell: Option[Cell]): CellReader.CellReadResult[Date] = { 135 | cell match { 136 | case Some(c) => 137 | c.getCellType match { 138 | case CellType.BLANK => 139 | Left(new CellNotExistsException()) 140 | case CellType.NUMERIC => 141 | Option(c.getDateCellValue) match { 142 | case Some(s) => 143 | Right(s) 144 | case _ => 145 | Left(new ExpectDateException()) 146 | } 147 | case CellType.FORMULA => 148 | val wb = c.getSheet.getWorkbook 149 | val crateHelper = wb.getCreationHelper 150 | val evaluator = crateHelper.createFormulaEvaluator 151 | self.get(Option(evaluator.evaluateInCell(c))) 152 | case _ => 153 | Left(new ExpectDateException()) 154 | } 155 | case _ => 156 | Left(new CellNotExistsException()) 157 | } 158 | } 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/CellReadersImplicits.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import java.util.Date 4 | 5 | trait CellReadersImplicits { 6 | 7 | protected val readers: CellReadersImpl = new CellReadersImpl {} 8 | 9 | lazy val nonEmptyStringReader: CellReader[String] = 10 | readers.nonEmptyStringReader 11 | 12 | lazy val nonBlankStringReader: CellReader[String] = 13 | readers.nonBlankStringReader 14 | 15 | implicit lazy val stringReader: CellReader[String] = readers.stringReader 16 | 17 | implicit lazy val doubleReader: CellReader[Double] = readers.doubleReader 18 | 19 | implicit lazy val booleanReader: CellReader[Boolean] = readers.booleanReader 20 | 21 | implicit lazy val dateReader: CellReader[Date] = readers.dateReader 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/CellWritersImpl.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import java.util.Date 4 | 5 | import org.apache.poi.ss.usermodel.Cell 6 | 7 | import scala.util.Try 8 | 9 | trait CellWritersImpl { 10 | 11 | val stringWriter: CellWriter[String] = new CellWriter[String] { 12 | override def setValue(cell: Cell, value: String): Try[CPoiDone] = { 13 | Try { 14 | cell.setCellValue(value) 15 | CPoiDone.instance 16 | } 17 | } 18 | } 19 | 20 | val doubleWriter: CellWriter[Double] = new CellWriter[Double] { 21 | override def setValue(cell: Cell, value: Double): Try[CPoiDone] = { 22 | Try { 23 | cell.setCellValue(value) 24 | CPoiDone.instance 25 | } 26 | } 27 | } 28 | 29 | val booleanWriter: CellWriter[Boolean] = new CellWriter[Boolean] { 30 | override def setValue(cell: Cell, value: Boolean): Try[CPoiDone] = { 31 | Try { 32 | cell.setCellValue(value) 33 | CPoiDone.instance 34 | } 35 | } 36 | } 37 | 38 | val dateWriter: CellWriter[Date] = new CellWriter[Date] { 39 | override def setValue(cell: Cell, value: Date): Try[CPoiDone] = { 40 | Try { 41 | cell.setCellValue(value) 42 | CPoiDone.instance 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/CellWritersImplicits.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import java.util.Date 4 | 5 | trait CellWritersImplicits { 6 | 7 | protected val writers: CellWritersImpl = new CellWritersImpl {} 8 | 9 | implicit val stringWriter: CellWriter[String] = writers.stringWriter 10 | 11 | implicit val doubleWriter: CellWriter[Double] = writers.doubleWriter 12 | 13 | implicit val booleanWriter: CellWriter[Boolean] = writers.booleanWriter 14 | 15 | implicit val dateWriter: CellWriter[Date] = writers.dateWriter 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/ImmutableCellReadersImpl.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import net.scalax.cpoi.exception._ 4 | import org.apache.poi.ss.usermodel.{Cell, CellType} 5 | 6 | trait ImmutableCellReadersImpl extends CellReadersImpl { 7 | 8 | override def stringReader: CellReader[String] = new CellReader[String] { 9 | self => 10 | 11 | override def get(cell: Option[Cell]): CellReader.CellReadResult[String] = { 12 | cell match { 13 | case Some(c) => 14 | c.getCellType match { 15 | case CellType.BLANK => 16 | Right(c.getStringCellValue) 17 | case CellType.STRING => 18 | Right(c.getStringCellValue) 19 | case CellType.FORMULA => 20 | val wb = c.getSheet.getWorkbook 21 | val crateHelper = wb.getCreationHelper 22 | val evaluator = crateHelper.createFormulaEvaluator 23 | self.get(Option(evaluator.evaluateInCell(c))) 24 | case _ => 25 | Left(new ExpectStringCellException()) 26 | } 27 | case _ => 28 | //read null as empty cell 29 | Right("") 30 | } 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/rw/impl/ImmutableCellReadersImplicits.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.rw 2 | 3 | import java.util.Date 4 | 5 | trait ImmutableCellReadersImplicits { 6 | 7 | protected val readers: ImmutableCellReadersImpl = 8 | new ImmutableCellReadersImpl {} 9 | 10 | implicit lazy val stringReader: CellReader[String] = readers.stringReader 11 | 12 | implicit lazy val doubleReader: CellReader[Double] = readers.doubleReader 13 | 14 | implicit lazy val booleanReader: CellReader[Boolean] = readers.booleanReader 15 | 16 | implicit lazy val dateReader: CellReader[Date] = readers.dateReader 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/style/MutableStyleGen.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.style 2 | 3 | import net.scalax.cpoi.content.CellDataAbs 4 | import net.scalax.cpoi.rw.CPoiDone 5 | import net.scalax.cpoi.utils.compat.CollectionCompat 6 | import org.apache.poi.ss.usermodel.{Cell, CellStyle} 7 | 8 | import scala.collection.mutable.{Map => MutableMap} 9 | import scala.util.Try 10 | import scala.collection.compat._ 11 | 12 | trait MutableStyleGen { 13 | self => 14 | 15 | protected val cellMap: MutableMap[StyleKeyWrap, CellStyle] = MutableMap.empty 16 | 17 | protected def getCellStyle(cellDate: CellDataAbs, cell: Cell): CellStyle = { 18 | val workbook = cell.getSheet.getWorkbook 19 | val key = 20 | StyleKeyWrap(workbook = workbook, styleTrans = cellDate.styleTransform) 21 | val cellStyleOpt = cellMap.get(key) 22 | val cellStyle = cellStyleOpt match { 23 | case Some(c) => 24 | c 25 | case None => 26 | val c = workbook.createCellStyle 27 | val newCellStyle = key.styleTrans.foldLeft(c) { (style, tran) => 28 | tran.operation(workbook, style) 29 | } 30 | self.cellMap += (key -> newCellStyle) 31 | newCellStyle 32 | } 33 | cellStyle 34 | } 35 | 36 | def setCellStyle(cellDate: CellDataAbs, cell: Cell): Try[CPoiDone] = { 37 | Try { 38 | val cStyle = getCellStyle(cellDate, cell) 39 | cell.setCellStyle(cStyle) 40 | CPoiDone.instance 41 | } 42 | } 43 | 44 | def toImmutable: StyleGen = new StyleGen { 45 | override protected val cellMap = CollectionCompat.mapFromMutable(self.cellMap) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/style/StyleGen.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.style 2 | 3 | import net.scalax.cpoi.content.CellDataAbs 4 | import net.scalax.cpoi.utils.compat.CollectionCompat 5 | import org.apache.poi.ss.usermodel.{Cell, CellStyle} 6 | 7 | import scala.collection.compat._ 8 | 9 | trait StyleGen { 10 | self => 11 | 12 | protected val cellMap: Map[StyleKeyWrap, CellStyle] 13 | 14 | protected def getCellStyle(cellData: CellDataAbs, cell: Cell): (CellStyle, StyleGen) = { 15 | val workbook = cell.getSheet.getWorkbook 16 | val key = 17 | StyleKeyWrap(workbook = workbook, styleTrans = cellData.styleTransform) 18 | val cellStyleOpt = cellMap.get(key) 19 | val (cellStyle, newMap) = cellStyleOpt match { 20 | case Some(c) => (c, self.cellMap) 21 | case None => 22 | val c = workbook.createCellStyle 23 | val newCellStyle = key.styleTrans.foldLeft(c) { (style, tran) => 24 | tran.operation(workbook, style) 25 | } 26 | (newCellStyle, self.cellMap + (key -> newCellStyle)) 27 | } 28 | val newGen = new StyleGen { 29 | override protected val cellMap = newMap 30 | }: StyleGen 31 | (cellStyle, newGen) 32 | } 33 | 34 | def setCellStyle(cellData: CellDataAbs, cell: Cell): StyleGen = { 35 | val (cStyle, newStyleGen) = getCellStyle(cellData, cell) 36 | cell.setCellStyle(cStyle) 37 | newStyleGen 38 | } 39 | 40 | def toMutable: MutableStyleGen = { 41 | val newMap = CollectionCompat.mapFromImmutable(self.cellMap) 42 | new MutableStyleGen { 43 | override protected val cellMap = newMap 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/style/StyleKeyWrap.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.style 2 | 3 | import org.apache.poi.ss.usermodel.Workbook 4 | 5 | case class StyleKeyWrap(workbook: Workbook, styleTrans: List[StyleTransform]) 6 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/style/StyleTransform.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.style 2 | 3 | import org.apache.poi.ss.usermodel.{CellStyle, Workbook} 4 | 5 | trait StyleTransform { 6 | 7 | def operation(workbook: Workbook, cellStyle: CellStyle): CellStyle 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/utils/Alias.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.utils 2 | 3 | import net.scalax.cpoi.rw.{CellReadersImplicits, CellWritersImplicits, ImmutableCellReadersImplicits} 4 | 5 | trait Alias { 6 | 7 | val CPoi: CPoi = new CPoi 8 | 9 | val readers: CellReadersImplicits = new CellReadersImplicits {} 10 | val immutableReaders: ImmutableCellReadersImplicits = 11 | new ImmutableCellReadersImplicits {} 12 | val writers: CellWritersImplicits = new CellWritersImplicits {} 13 | 14 | type MutableStyleGen = net.scalax.cpoi.style.MutableStyleGen 15 | type StyleGen = net.scalax.cpoi.style.StyleGen 16 | type StyleTransform = net.scalax.cpoi.style.StyleTransform 17 | 18 | type CPoiDone = net.scalax.cpoi.rw.CPoiDone 19 | val CPoiDone: CPoiDone = net.scalax.cpoi.rw.CPoiDone.instance 20 | 21 | type CellWriter[T] = net.scalax.cpoi.rw.CellWriter[T] 22 | val CellWriter = net.scalax.cpoi.rw.CellWriter 23 | type CellReader[T] = net.scalax.cpoi.rw.CellReader[T] 24 | val CellReader = net.scalax.cpoi.rw.CellReader 25 | 26 | type CellContentAbs = net.scalax.cpoi.content.CellContentAbs 27 | type CellDataAbs = net.scalax.cpoi.content.CellDataAbs 28 | type CellData[T] = net.scalax.cpoi.content.CellData[T] 29 | 30 | type CellReaderException = net.scalax.cpoi.exception.CellReaderException 31 | type CellReadResult[T] = net.scalax.cpoi.rw.CellReader.CellReadResult[T] 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/net/scalax/cpoi/utils/CPoi.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.utils 2 | 3 | import net.scalax.cpoi.content.{CellContentAbs, CellData, CellDataAbs, CellDataImpl} 4 | import net.scalax.cpoi.rw.{CPoiDone, CellWriter} 5 | import net.scalax.cpoi.style.{MutableStyleGen, StyleGen, StyleKeyWrap, StyleTransform} 6 | import net.scalax.cpoi.utils.compat.CollectionCompat 7 | import org.apache.poi.ss.usermodel.{Cell, CellStyle} 8 | 9 | import scala.util.{Failure, Try} 10 | import scala.collection.mutable.{Map => MutableMap} 11 | 12 | class CPoi { 13 | 14 | def multiplySet(styleGen: StyleGen, seq: Seq[(Cell, CellDataAbs)]): Try[StyleGen] = { 15 | val ms = styleGen.toMutable 16 | CollectionCompat 17 | .seqToLazyList(seq) 18 | .map { item => 19 | Try { 20 | item match { 21 | case (eachCell, eachCData) => 22 | ms.setCellStyle(eachCData, eachCell).flatMap { (_: CPoiDone) => 23 | eachCData.set(eachCell) 24 | } 25 | } 26 | }.flatten: Try[CPoiDone] 27 | } 28 | .collectFirst { case Failure(e) => e } match { 29 | case Some(e) => 30 | Failure(e) 31 | case None => 32 | Try { ms.toImmutable } 33 | } 34 | } 35 | 36 | def multiplySet(styleGen: MutableStyleGen, seq: Seq[(Cell, CellDataAbs)]): Try[CPoiDone] = { 37 | CollectionCompat 38 | .seqToLazyList(seq) 39 | .map { item => 40 | Try { 41 | item match { 42 | case (eachCell, eachCData) => 43 | styleGen.setCellStyle(eachCData, eachCell).flatMap { (_: CPoiDone) => 44 | eachCData.set(eachCell) 45 | } 46 | } 47 | }.flatten: Try[CPoiDone] 48 | } 49 | .collectFirst { case Failure(e) => e } match { 50 | case Some(e) => 51 | Failure(e) 52 | case None => 53 | Try { CPoiDone.instance } 54 | } 55 | } 56 | 57 | def wrapCell(poiCell: Option[Cell]): CellContentAbs = { 58 | val c1 = poiCell 59 | new CellContentAbs { 60 | override val poiCell = c1 61 | } 62 | } 63 | 64 | def wrapCell(poiCell: Cell): CellContentAbs = { 65 | val c1 = poiCell 66 | new CellContentAbs { 67 | override val poiCell = Option(c1) 68 | } 69 | } 70 | 71 | def wrapData[T](data: T, styleTransform: List[StyleTransform] = List.empty)( 72 | implicit 73 | operation: CellWriter[T] 74 | ): CellData[T] = 75 | CellDataImpl(data, styleTransform) 76 | 77 | def newStyleGen: StyleGen = new StyleGen { 78 | override protected val cellMap: Map[StyleKeyWrap, CellStyle] = Map.empty 79 | } 80 | 81 | def newMutableStyleGen: MutableStyleGen = new MutableStyleGen { 82 | override protected val cellMap: MutableMap[StyleKeyWrap, CellStyle] = MutableMap.empty 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/test/resources/test01.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalax/poi-collection/bd9fcbca77441fd4d872ae4a2a487361d9644726/src/test/resources/test01.xls -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/poi/HSSFWorkbookLawBooleanCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 6 | import org.apache.poi.ss.usermodel.CellType 7 | import org.scalatest._ 8 | 9 | class HSSFWorkbookLawBooleanCellTest extends FlatSpec with Matchers { 10 | 11 | "String cell" should "be set a boolean cell type" in { 12 | val workbook = new HSSFWorkbook() 13 | val sheet = workbook.createSheet("Sheet1") 14 | val cell = sheet.createRow(0).createCell(0) 15 | cell.setCellValue("2333.44") 16 | cell.setCellType(CellType.BOOLEAN) 17 | cell.getBooleanCellValue should be(false) 18 | } 19 | 20 | "Numberic cell" should "be set a boolean cell type" in { 21 | val workbook = new HSSFWorkbook() 22 | val sheet = workbook.createSheet("Sheet1") 23 | val cell = sheet.createRow(0).createCell(0) 24 | cell.setCellValue(2333.2233) 25 | cell.setCellType(CellType.BOOLEAN) 26 | cell.getBooleanCellValue should be(true) 27 | 28 | val cell2 = sheet.createRow(0).createCell(0) 29 | cell2.setCellValue(-2333.2233) 30 | cell2.setCellType(CellType.BOOLEAN) 31 | cell2.getBooleanCellValue should be(true) 32 | } 33 | 34 | "Date cell" should "be set a boolean cell type" in { 35 | val workbook = new HSSFWorkbook() 36 | val sheet = workbook.createSheet("Sheet1") 37 | val cell = sheet.createRow(0).createCell(0) 38 | cell.setCellValue(new Date()) 39 | cell.setCellType(CellType.BOOLEAN) 40 | cell.getBooleanCellValue should be(true) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/poi/HSSFWorkbookLawNumbricCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 6 | import org.apache.poi.ss.usermodel.CellType 7 | import org.scalatest._ 8 | 9 | class HSSFWorkbookLawNumbricCellTest extends FlatSpec with Matchers { 10 | 11 | "String cell" should "throw exception when setting a numeric cell type" in { 12 | val workbook = new HSSFWorkbook() 13 | val sheet = workbook.createSheet("Sheet1") 14 | val cell = sheet.createRow(0).createCell(0) 15 | cell.setCellValue("2333.44") 16 | a[IllegalStateException] should be thrownBy { 17 | cell.setCellType(CellType.NUMERIC) 18 | } 19 | } 20 | 21 | "Boolean cell" should "be set a numberic cell type" in { 22 | val workbook = new HSSFWorkbook() 23 | val sheet = workbook.createSheet("Sheet1") 24 | val cell = sheet.createRow(0).createCell(0) 25 | cell.setCellValue(false) 26 | a[IllegalStateException] should be thrownBy { 27 | cell.setCellType(CellType.NUMERIC) 28 | } 29 | } 30 | 31 | "Date cell" should "be set a numeric cell type" in { 32 | val workbook = new HSSFWorkbook() 33 | val sheet = workbook.createSheet("Sheet1") 34 | val cell = sheet.createRow(0).createCell(0) 35 | cell.setCellValue(new Date(0)) 36 | cell.setCellType(CellType.NUMERIC) 37 | cell.getNumericCellValue.toInt should be(25569) 38 | cell.getDateCellValue should be(new Date(0)) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/poi/HSSFWorkbookLawStringCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 6 | import org.apache.poi.ss.usermodel.CellType 7 | import org.scalatest._ 8 | 9 | class HSSFWorkbookLawStringCellTest extends FlatSpec with Matchers { 10 | 11 | "Numberic cell" should "be set a string cell type" in { 12 | val workbook = new HSSFWorkbook() 13 | val sheet = workbook.createSheet("Sheet1") 14 | val cell = sheet.createRow(0).createCell(0) 15 | cell.setCellValue(2333.2233) 16 | cell.setCellType(CellType.STRING) 17 | cell.getStringCellValue should be("2333.2233") 18 | } 19 | 20 | "Boolean cell" should "be set a string cell type" in { 21 | val workbook = new HSSFWorkbook() 22 | val sheet = workbook.createSheet("Sheet1") 23 | val cell = sheet.createRow(0).createCell(0) 24 | cell.setCellValue(true) 25 | cell.setCellType(CellType.STRING) 26 | cell.getStringCellValue should be("TRUE") 27 | 28 | val cell2 = sheet.createRow(0).createCell(2) 29 | cell2.setCellValue(false) 30 | cell2.setCellType(CellType.STRING) 31 | cell2.getStringCellValue should be("FALSE") 32 | } 33 | 34 | "Date cell" should "be set a string cell type" in { 35 | val workbook = new HSSFWorkbook() 36 | val sheet = workbook.createSheet("Sheet1") 37 | val cell = sheet.createRow(0).createCell(0) 38 | cell.setCellValue(new Date(0)) 39 | cell.setCellType(CellType.STRING) 40 | cell.getStringCellValue.startsWith("25569") should be(true) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookBlankCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.exception.CellNotExistsException 6 | import net.scalax.cpoi.api._ 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookBlankCellTest extends FlatSpec with Matchers { 11 | 12 | "blank cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | val wrap = CPoi.wrapCell(cell) 19 | val value = wrap.tryValue[String] 20 | wrap.isBlank should be(true) 21 | value.isRight should be(true) 22 | value.getOrElse(throw new Exception("Test not pass")) should be("") 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | val wrap = CPoi.wrapCell(cell) 32 | val value = wrap.tryValue[Double] 33 | wrap.isBlank should be(true) 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 36 | } 37 | 38 | it should "throw exception when read by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | val wrap = CPoi.wrapCell(cell) 45 | val value = wrap.tryValue[Boolean] 46 | wrap.isBlank should be(true) 47 | value.isLeft should be(true) 48 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | val wrap = CPoi.wrapCell(cell) 58 | val value = wrap.tryValue[Date] 59 | wrap.isBlank should be(true) 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 62 | } 63 | 64 | it should "read as empty string by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | val wrap = CPoi.wrapCell(cell) 71 | val value = wrap.tryValue[String] 72 | wrap.isBlank should be(true) 73 | value.isRight should be(true) 74 | value.getOrElse(throw new Exception("Test not pass")) should be("") 75 | } 76 | 77 | it should "throw exception when read by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | val wrap = CPoi.wrapCell(cell) 84 | val value = wrap.tryValue[String] 85 | wrap.isBlank should be(true) 86 | value.isLeft should be(true) 87 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 88 | } 89 | 90 | it should "throw exception when read by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | val wrap = CPoi.wrapCell(cell) 97 | val value = wrap.tryValue[String] 98 | wrap.isBlank should be(true) 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookBlankStringCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.exception.{CellNotExistsException, ExpectBooleanCellException, ExpectDateException, ExpectNumericCellException} 6 | import net.scalax.cpoi.api._ 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookBlankStringCellTest extends FlatSpec with Matchers { 11 | 12 | "blank string cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellValue(" ") 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isRight should be(true) 22 | value.getOrElse(throw new Exception("Test not pass")) should be(" ") 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellValue(" ") 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "throw exception when read by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellValue(" ") 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isLeft should be(true) 48 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellValue(" ") 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "read as empty string by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellValue(" ") 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isRight should be(true) 74 | value.getOrElse(throw new Exception("Test not pass")) should be(" ") 75 | } 76 | 77 | it should "read as string by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellValue(" ") 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isRight should be(true) 87 | value.getOrElse(throw new Exception("Test not pass")) should be(" ") 88 | } 89 | 90 | it should "read as string by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellValue(" ") 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookBooleanFormulaCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectDateException, ExpectNumericCellException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookBooleanFormulaCellTest extends FlatSpec with Matchers { 11 | 12 | "boolean formula cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellFormula("3 > 2") 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isLeft should be(true) 22 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellFormula("3 > 2") 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "read as boolean by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellFormula("3 > 2") 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isRight should be(true) 48 | value.getOrElse(throw new Exception("Test not pass")) should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellFormula("3 > 2") 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "throw exception when read by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellFormula("3 > 2") 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isLeft should be(true) 74 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 75 | } 76 | 77 | it should "throw exception when read by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellFormula("3 > 2") 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isLeft should be(true) 87 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 88 | } 89 | 90 | it should "throw exception when read by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellFormula("3 > 2") 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookEmptyStringCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.exception.{CellNotExistsException, ExpectBooleanCellException, ExpectDateException, ExpectNumericCellException} 6 | import net.scalax.cpoi.api._ 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookEmptyStringCellTest extends FlatSpec with Matchers { 11 | 12 | "empty string cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellValue("") 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isRight should be(true) 22 | value.getOrElse(throw new Exception("Test not pass")) should be("") 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellValue("") 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "throw exception when read by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellValue("") 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isLeft should be(true) 48 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellValue("") 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "read as empty string by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellValue("") 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isRight should be(true) 74 | value.getOrElse(throw new Exception("Test not pass")) should be("") 75 | } 76 | 77 | it should "read as string by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellValue("") 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isLeft should be(true) 87 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 88 | } 89 | 90 | it should "read as string by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellValue("") 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookFalseBooleanCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectDateException, ExpectNumericCellException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookFalseBooleanCellTest extends FlatSpec with Matchers { 11 | 12 | "boolean cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellValue(false) 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isLeft should be(true) 22 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellValue(false) 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "read as boolean by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellValue(false) 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isRight should be(true) 48 | value.getOrElse(throw new Exception("Test not pass")) should be(false) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellValue(false) 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "throw exception when read by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellValue(false) 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isLeft should be(true) 74 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 75 | } 76 | 77 | it should "throw exception when read by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellValue(false) 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isLeft should be(true) 87 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 88 | } 89 | 90 | it should "throw exception when read by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellValue(false) 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookNotBlankStringCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.exception.{ExpectBooleanCellException, ExpectDateException, ExpectNumericCellException} 6 | import net.scalax.cpoi.api._ 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookNotBlankStringCellTest extends FlatSpec with Matchers { 11 | 12 | "not blank string cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellValue("-123 ") 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isRight should be(true) 22 | value.getOrElse(throw new Exception("Test not pass")) should be("-123 ") 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellValue("-123 ") 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "throw exception when read by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellValue("-123 ") 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isLeft should be(true) 48 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellValue("-123 ") 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "read as empty string by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellValue("-123 ") 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isRight should be(true) 74 | value.getOrElse(throw new Exception("Test not pass")) should be("-123 ") 75 | } 76 | 77 | it should "read as string by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellValue("-123 ") 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isRight should be(true) 87 | value.getOrElse(throw new Exception("Test not pass")) should be("-123 ") 88 | } 89 | 90 | it should "read as trim string by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellValue("-123 ") 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isRight should be(true) 100 | value.getOrElse(throw new Exception("Test not pass")) should be("-123") 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookNullCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.CellNotExistsException 7 | import org.apache.poi.ss.usermodel.Cell 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookNullCellTest extends FlatSpec with Matchers { 11 | 12 | "null cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val wrap = CPoi.wrapCell(null: Cell) 15 | val value = wrap.tryValue[String] 16 | value.isRight should be(true) 17 | value.getOrElse(throw new Exception("Test not pass")) should be("") 18 | } 19 | 20 | it should "throw exception when read by double reader" in { 21 | import readers._ 22 | val wrap = CPoi.wrapCell(null: Cell) 23 | val value = wrap.tryValue[Double] 24 | value.isLeft should be(true) 25 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 26 | } 27 | 28 | it should "throw exception when read by boolean reader" in { 29 | import readers._ 30 | val wrap = CPoi.wrapCell(null: Cell) 31 | val value = wrap.tryValue[Boolean] 32 | value.isLeft should be(true) 33 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 34 | } 35 | 36 | it should "throw exception when read by date reader" in { 37 | import readers._ 38 | val wrap = CPoi.wrapCell(null: Cell) 39 | val value = wrap.tryValue[Date] 40 | value.isLeft should be(true) 41 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 42 | } 43 | 44 | it should "read as empty string by immutable string reader" in { 45 | import immutableReaders._ 46 | val wrap = CPoi.wrapCell(null: Cell) 47 | val value = wrap.tryValue[String] 48 | value.isRight should be(true) 49 | value.getOrElse(throw new Exception("Test not pass")) should be("") 50 | } 51 | 52 | it should "throw exception when read by non empty string reader" in { 53 | implicit val ec = readers.nonEmptyStringReader 54 | val wrap = CPoi.wrapCell(null: Cell) 55 | val value = wrap.tryValue[String] 56 | value.isLeft should be(true) 57 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 58 | } 59 | 60 | it should "throw exception when read by non blank string reader" in { 61 | implicit val ec = readers.nonBlankStringReader 62 | val wrap = CPoi.wrapCell(null: Cell) 63 | val value = wrap.tryValue[String] 64 | value.isLeft should be(true) 65 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[CellNotExistsException] should be(true) 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookNumbericCellTest1.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.{Calendar, Date} 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectBooleanCellException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.apache.poi.ss.usermodel.CellType 9 | import org.scalatest._ 10 | 11 | class HSSFWorkbookNumbericCellTest1 extends FlatSpec with Matchers { 12 | 13 | "numberic cell" should "read as empty string by common string reader" in { 14 | import readers._ 15 | val workbook = new HSSFWorkbook() 16 | val sheet = workbook.createSheet("Sheet1") 17 | val row = sheet.createRow(1) 18 | val cell = row.createCell(1) 19 | cell.setCellValue(123.321) 20 | val wrap = CPoi.wrapCell(cell) 21 | wrap.cellType should be(Option(CellType.NUMERIC)) 22 | val value = wrap.tryValue[String] 23 | wrap.cellType should be(Option(CellType.STRING)) 24 | value.isRight should be(true) 25 | value.getOrElse(throw new Exception("Test not pass")) should be("123.321") 26 | } 27 | 28 | it should "read as double by double reader" in { 29 | import readers._ 30 | val workbook = new HSSFWorkbook() 31 | val sheet = workbook.createSheet("Sheet1") 32 | val row = sheet.createRow(1) 33 | val cell = row.createCell(1) 34 | cell.setCellValue(123.321) 35 | val wrap = CPoi.wrapCell(cell) 36 | val value = wrap.tryValue[Double] 37 | value.isRight should be(true) 38 | value.getOrElse(throw new Exception("Test not pass")) should be(123.321) 39 | } 40 | 41 | it should "throw exception when read by boolean reader" in { 42 | import readers._ 43 | val workbook = new HSSFWorkbook() 44 | val sheet = workbook.createSheet("Sheet1") 45 | val row = sheet.createRow(1) 46 | val cell = row.createCell(1) 47 | cell.setCellValue(123.321) 48 | val wrap = CPoi.wrapCell(cell) 49 | val value = wrap.tryValue[Boolean] 50 | value.isLeft should be(true) 51 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 52 | } 53 | 54 | it should "read as date when read by date reader" in { 55 | import readers._ 56 | val workbook = new HSSFWorkbook() 57 | val sheet = workbook.createSheet("Sheet1") 58 | val row = sheet.createRow(1) 59 | val cell = row.createCell(1) 60 | cell.setCellValue(123.321) 61 | val wrap = CPoi.wrapCell(cell) 62 | val value = wrap.tryValue[Date] 63 | value.isRight should be(true) 64 | val calendar = Calendar.getInstance 65 | calendar.setTime(value.getOrElse(throw new Exception("Test not pass"))) 66 | calendar.get(Calendar.YEAR) should be(1900) 67 | } 68 | 69 | it should "throw exception when read by immutable string reader" in { 70 | import immutableReaders._ 71 | val workbook = new HSSFWorkbook() 72 | val sheet = workbook.createSheet("Sheet1") 73 | val row = sheet.createRow(1) 74 | val cell = row.createCell(1) 75 | cell.setCellValue(123.321) 76 | val wrap = CPoi.wrapCell(cell) 77 | wrap.cellType should be(Option(CellType.NUMERIC)) 78 | val value = wrap.tryValue[String] 79 | wrap.cellType should be(Option(CellType.NUMERIC)) 80 | value.isLeft should be(true) 81 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 82 | } 83 | 84 | it should "read as string by non empty string reader" in { 85 | implicit val ec = readers.nonEmptyStringReader 86 | val workbook = new HSSFWorkbook() 87 | val sheet = workbook.createSheet("Sheet1") 88 | val row = sheet.createRow(1) 89 | val cell = row.createCell(1) 90 | cell.setCellValue(123.321) 91 | val wrap = CPoi.wrapCell(cell) 92 | wrap.cellType should be(Option(CellType.NUMERIC)) 93 | val value = wrap.tryValue[String] 94 | wrap.cellType should be(Option(CellType.STRING)) 95 | value.isRight should be(true) 96 | value.getOrElse(throw new Exception("Test not pass")) should be("123.321") 97 | } 98 | 99 | it should "read as trim string by non blank string reader" in { 100 | implicit val ec = readers.nonBlankStringReader 101 | val workbook = new HSSFWorkbook() 102 | val sheet = workbook.createSheet("Sheet1") 103 | val row = sheet.createRow(1) 104 | val cell = row.createCell(1) 105 | cell.setCellValue(123.321) 106 | val wrap = CPoi.wrapCell(cell) 107 | wrap.cellType should be(Option(CellType.NUMERIC)) 108 | val value = wrap.tryValue[String] 109 | wrap.cellType should be(Option(CellType.STRING)) 110 | value.isRight should be(true) 111 | value.getOrElse(throw new Exception("Test not pass")) should be("123.321") 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookNumbericCellTest2.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectBooleanCellException, ExpectDateException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.apache.poi.ss.usermodel.CellType 9 | import org.scalatest._ 10 | 11 | class HSSFWorkbookNumbericCellTest2 extends FlatSpec with Matchers { 12 | 13 | "numberic cell" should "read as empty string by common string reader" in { 14 | import readers._ 15 | val workbook = new HSSFWorkbook() 16 | val sheet = workbook.createSheet("Sheet1") 17 | val row = sheet.createRow(1) 18 | val cell = row.createCell(1) 19 | cell.setCellValue(-123.321) 20 | val wrap = CPoi.wrapCell(cell) 21 | wrap.cellType should be(Option(CellType.NUMERIC)) 22 | val value = wrap.tryValue[String] 23 | wrap.cellType should be(Option(CellType.STRING)) 24 | value.isRight should be(true) 25 | value.getOrElse(throw new Exception("Test not pass")) should be("-123.321") 26 | } 27 | 28 | it should "read as double by double reader" in { 29 | import readers._ 30 | val workbook = new HSSFWorkbook() 31 | val sheet = workbook.createSheet("Sheet1") 32 | val row = sheet.createRow(1) 33 | val cell = row.createCell(1) 34 | cell.setCellValue(-123.321) 35 | val wrap = CPoi.wrapCell(cell) 36 | val value = wrap.tryValue[Double] 37 | value.isRight should be(true) 38 | value.getOrElse(throw new Exception("Test not pass")) should be(-123.321) 39 | } 40 | 41 | it should "throw exception when read by boolean reader" in { 42 | import readers._ 43 | val workbook = new HSSFWorkbook() 44 | val sheet = workbook.createSheet("Sheet1") 45 | val row = sheet.createRow(1) 46 | val cell = row.createCell(1) 47 | cell.setCellValue(-123.321) 48 | val wrap = CPoi.wrapCell(cell) 49 | val value = wrap.tryValue[Boolean] 50 | value.isLeft should be(true) 51 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 52 | } 53 | 54 | it should "read as date when read by date reader" in { 55 | import readers._ 56 | val workbook = new HSSFWorkbook() 57 | val sheet = workbook.createSheet("Sheet1") 58 | val row = sheet.createRow(1) 59 | val cell = row.createCell(1) 60 | cell.setCellValue(-123.321) 61 | val wrap = CPoi.wrapCell(cell) 62 | val value = wrap.tryValue[Date] 63 | value.isLeft should be(true) 64 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 65 | } 66 | 67 | it should "throw exception when read by immutable string reader" in { 68 | import immutableReaders._ 69 | val workbook = new HSSFWorkbook() 70 | val sheet = workbook.createSheet("Sheet1") 71 | val row = sheet.createRow(1) 72 | val cell = row.createCell(1) 73 | cell.setCellValue(-123.321) 74 | val wrap = CPoi.wrapCell(cell) 75 | wrap.cellType should be(Option(CellType.NUMERIC)) 76 | val value = wrap.tryValue[String] 77 | wrap.cellType should be(Option(CellType.NUMERIC)) 78 | value.isLeft should be(true) 79 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 80 | } 81 | 82 | it should "read as string by non empty string reader" in { 83 | implicit val ec = readers.nonEmptyStringReader 84 | val workbook = new HSSFWorkbook() 85 | val sheet = workbook.createSheet("Sheet1") 86 | val row = sheet.createRow(1) 87 | val cell = row.createCell(1) 88 | cell.setCellValue(-123.321) 89 | val wrap = CPoi.wrapCell(cell) 90 | wrap.cellType should be(Option(CellType.NUMERIC)) 91 | val value = wrap.tryValue[String] 92 | wrap.cellType should be(Option(CellType.STRING)) 93 | value.isRight should be(true) 94 | value.getOrElse(throw new Exception("Test not pass")) should be("-123.321") 95 | } 96 | 97 | it should "read as trim string by non blank string reader" in { 98 | implicit val ec = readers.nonBlankStringReader 99 | val workbook = new HSSFWorkbook() 100 | val sheet = workbook.createSheet("Sheet1") 101 | val row = sheet.createRow(1) 102 | val cell = row.createCell(1) 103 | cell.setCellValue(-123.321) 104 | val wrap = CPoi.wrapCell(cell) 105 | wrap.cellType should be(Option(CellType.NUMERIC)) 106 | val value = wrap.tryValue[String] 107 | wrap.cellType should be(Option(CellType.STRING)) 108 | value.isRight should be(true) 109 | value.getOrElse(throw new Exception("Test not pass")) should be("-123.321") 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookNumbricFormulaCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.{Calendar, Date} 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectBooleanCellException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.apache.poi.ss.usermodel.CellType 9 | import org.scalatest._ 10 | 11 | class HSSFWorkbookNumbricFormulaCellTest extends FlatSpec with Matchers { 12 | 13 | "numbric formula cell" should "read as empty string by common string reader" in { 14 | import readers._ 15 | val workbook = new HSSFWorkbook() 16 | val sheet = workbook.createSheet("Sheet1") 17 | val row = sheet.createRow(1) 18 | val cell = row.createCell(1) 19 | cell.setCellFormula("SUM(3, 4)") 20 | val wrap = CPoi.wrapCell(cell) 21 | wrap.cellType should be(Option(CellType.FORMULA)) 22 | val value = wrap.tryValue[String] 23 | wrap.cellType should be(Option(CellType.STRING)) 24 | value.isRight should be(true) 25 | value.getOrElse(throw new Exception("Test not pass")) should be("7") 26 | } 27 | 28 | it should "read as double by double reader" in { 29 | import readers._ 30 | val workbook = new HSSFWorkbook() 31 | val sheet = workbook.createSheet("Sheet1") 32 | val row = sheet.createRow(1) 33 | val cell = row.createCell(1) 34 | cell.setCellFormula("SUM(3, 4)") 35 | val wrap = CPoi.wrapCell(cell) 36 | val value = wrap.tryValue[Double] 37 | value.isRight should be(true) 38 | value.getOrElse(throw new Exception("Test not pass")) should be(7) 39 | } 40 | 41 | it should "throw exception when read by boolean reader" in { 42 | import readers._ 43 | val workbook = new HSSFWorkbook() 44 | val sheet = workbook.createSheet("Sheet1") 45 | val row = sheet.createRow(1) 46 | val cell = row.createCell(1) 47 | cell.setCellFormula("SUM(3, 4)") 48 | val wrap = CPoi.wrapCell(cell) 49 | val value = wrap.tryValue[Boolean] 50 | value.isLeft should be(true) 51 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 52 | } 53 | 54 | it should "read as date when read by date reader" in { 55 | import readers._ 56 | val workbook = new HSSFWorkbook() 57 | val sheet = workbook.createSheet("Sheet1") 58 | val row = sheet.createRow(1) 59 | val cell = row.createCell(1) 60 | cell.setCellFormula("SUM(3, 4)") 61 | val wrap = CPoi.wrapCell(cell) 62 | val value = wrap.tryValue[Date] 63 | value.isRight should be(true) 64 | val calendar = Calendar.getInstance 65 | calendar.setTime(value.getOrElse(throw new Exception("Test not pass"))) 66 | calendar.get(Calendar.YEAR) should be(1900) 67 | } 68 | 69 | it should "throw exception when read by immutable string reader" in { 70 | import immutableReaders._ 71 | val workbook = new HSSFWorkbook() 72 | val sheet = workbook.createSheet("Sheet1") 73 | val row = sheet.createRow(1) 74 | val cell = row.createCell(1) 75 | cell.setCellFormula("SUM(3, 4)") 76 | val wrap = CPoi.wrapCell(cell) 77 | wrap.cellType should be(Option(CellType.FORMULA)) 78 | val value = wrap.tryValue[String] 79 | wrap.cellType should be(Option(CellType.NUMERIC)) 80 | value.isLeft should be(true) 81 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 82 | } 83 | 84 | it should "read as string by non empty string reader" in { 85 | implicit val ec = readers.nonEmptyStringReader 86 | val workbook = new HSSFWorkbook() 87 | val sheet = workbook.createSheet("Sheet1") 88 | val row = sheet.createRow(1) 89 | val cell = row.createCell(1) 90 | cell.setCellFormula("SUM(3, 4)") 91 | val wrap = CPoi.wrapCell(cell) 92 | wrap.cellType should be(Option(CellType.FORMULA)) 93 | val value = wrap.tryValue[String] 94 | wrap.cellType should be(Option(CellType.STRING)) 95 | value.isRight should be(true) 96 | value.getOrElse(throw new Exception("Test not pass")) should be("7") 97 | } 98 | 99 | it should "read as trim string by non blank string reader" in { 100 | implicit val ec = readers.nonBlankStringReader 101 | val workbook = new HSSFWorkbook() 102 | val sheet = workbook.createSheet("Sheet1") 103 | val row = sheet.createRow(1) 104 | val cell = row.createCell(1) 105 | cell.setCellFormula("SUM(3, 4)") 106 | val wrap = CPoi.wrapCell(cell) 107 | wrap.cellType should be(Option(CellType.FORMULA)) 108 | val value = wrap.tryValue[String] 109 | wrap.cellType should be(Option(CellType.STRING)) 110 | value.isRight should be(true) 111 | value.getOrElse(throw new Exception("Test not pass")) should be("7") 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookOptionReaderTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import net.scalax.cpoi.api._ 4 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 5 | import org.scalatest._ 6 | 7 | class HSSFWorkbookOptionReaderTest extends FlatSpec with Matchers { 8 | 9 | "Non empty string cell" should "read as option string reader" in { 10 | import readers._ 11 | 12 | val testBlankStr = " " * 100 13 | val workbook = new HSSFWorkbook() 14 | val sheet = workbook.createSheet("SheetA") 15 | val row = sheet.createRow(2) 16 | val cell = row.createCell(3) 17 | cell.setCellValue(testBlankStr) 18 | val ccell = CPoi.wrapCell(cell) 19 | val value = ccell.tryValue[Option[String]] 20 | value.isRight should be(true) 21 | value.getOrElse(throw new Exception("Test not pass")) should be(Option(testBlankStr)) 22 | } 23 | 24 | "Blank string cell" should "read as None by non blank string reader" in { 25 | implicit val strReader = readers.nonBlankStringReader 26 | 27 | val testBlankStr = " " * 100 28 | val workbook = new HSSFWorkbook() 29 | val sheet = workbook.createSheet("SheetA") 30 | val row = sheet.createRow(2) 31 | val cell = row.createCell(3) 32 | cell.setCellValue(testBlankStr) 33 | val ccell = CPoi.wrapCell(cell) 34 | val value = ccell.tryValue[Option[String]] 35 | value.isRight should be(true) 36 | value.getOrElse(throw new Exception("Test not pass")) should be(Option.empty) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookStringFormulaCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.exception.{ExpectBooleanCellException, ExpectDateException, ExpectNumericCellException} 6 | import net.scalax.cpoi.api._ 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookStringFormulaCellTest extends FlatSpec with Matchers { 11 | 12 | val testUTF8Str = " 测试 " 13 | 14 | "string formula cell" should "read as empty string by common string reader" in { 15 | import readers._ 16 | val workbook = new HSSFWorkbook() 17 | val sheet = workbook.createSheet("Sheet1") 18 | val row = sheet.createRow(1) 19 | val cell = row.createCell(1) 20 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 21 | val wrap = CPoi.wrapCell(cell) 22 | val value = wrap.tryValue[String] 23 | value.isRight should be(true) 24 | value.getOrElse(throw new Exception("Test not pass")) should be(s"a${testUTF8Str}") 25 | } 26 | 27 | it should "throw exception when read by double reader" in { 28 | import readers._ 29 | val workbook = new HSSFWorkbook() 30 | val sheet = workbook.createSheet("Sheet1") 31 | val row = sheet.createRow(1) 32 | val cell = row.createCell(1) 33 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 34 | val wrap = CPoi.wrapCell(cell) 35 | val value = wrap.tryValue[Double] 36 | value.isLeft should be(true) 37 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 38 | } 39 | 40 | it should "throw exception when read by boolean reader" in { 41 | import readers._ 42 | val workbook = new HSSFWorkbook() 43 | val sheet = workbook.createSheet("Sheet1") 44 | val row = sheet.createRow(1) 45 | val cell = row.createCell(1) 46 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 47 | val wrap = CPoi.wrapCell(cell) 48 | val value = wrap.tryValue[Boolean] 49 | value.isLeft should be(true) 50 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectBooleanCellException] should be(true) 51 | } 52 | 53 | it should "throw exception when read by date reader" in { 54 | import readers._ 55 | val workbook = new HSSFWorkbook() 56 | val sheet = workbook.createSheet("Sheet1") 57 | val row = sheet.createRow(1) 58 | val cell = row.createCell(1) 59 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 60 | val wrap = CPoi.wrapCell(cell) 61 | val value = wrap.tryValue[Date] 62 | value.isLeft should be(true) 63 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 64 | } 65 | 66 | it should "read as empty string by immutable string reader" in { 67 | import immutableReaders._ 68 | val workbook = new HSSFWorkbook() 69 | val sheet = workbook.createSheet("Sheet1") 70 | val row = sheet.createRow(1) 71 | val cell = row.createCell(1) 72 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 73 | val wrap = CPoi.wrapCell(cell) 74 | val value = wrap.tryValue[String] 75 | value.isRight should be(true) 76 | value.getOrElse(throw new Exception("Test not pass")) should be(s"a${testUTF8Str}") 77 | } 78 | 79 | it should "read as string by non empty string reader" in { 80 | implicit val ec = readers.nonEmptyStringReader 81 | val workbook = new HSSFWorkbook() 82 | val sheet = workbook.createSheet("Sheet1") 83 | val row = sheet.createRow(1) 84 | val cell = row.createCell(1) 85 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 86 | val wrap = CPoi.wrapCell(cell) 87 | val value = wrap.tryValue[String] 88 | value.isRight should be(true) 89 | value.getOrElse(throw new Exception("Test not pass")) should be(s"a${testUTF8Str}") 90 | } 91 | 92 | it should "read as trim string by non blank string reader" in { 93 | implicit val ec = readers.nonBlankStringReader 94 | val workbook = new HSSFWorkbook() 95 | val sheet = workbook.createSheet("Sheet1") 96 | val row = sheet.createRow(1) 97 | val cell = row.createCell(1) 98 | cell.setCellFormula(s"""CONCATENATE("a", "${testUTF8Str}")""") 99 | val wrap = CPoi.wrapCell(cell) 100 | val value = wrap.tryValue[String] 101 | value.isRight should be(true) 102 | value.getOrElse(throw new Exception("Test not pass")) should be(s"a${testUTF8Str.reverse.dropWhile(s => s == ' ').reverse}") 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/read/HSSFWorkbookTrueBooleanCellTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.exception.{ExpectDateException, ExpectNumericCellException, ExpectStringCellException} 7 | import org.apache.poi.hssf.usermodel.HSSFWorkbook 8 | import org.scalatest._ 9 | 10 | class HSSFWorkbookTrueBooleanCellTest extends FlatSpec with Matchers { 11 | 12 | "boolean cell" should "read as empty string by common string reader" in { 13 | import readers._ 14 | val workbook = new HSSFWorkbook() 15 | val sheet = workbook.createSheet("Sheet1") 16 | val row = sheet.createRow(1) 17 | val cell = row.createCell(1) 18 | cell.setCellValue(true) 19 | val wrap = CPoi.wrapCell(cell) 20 | val value = wrap.tryValue[String] 21 | value.isLeft should be(true) 22 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 23 | } 24 | 25 | it should "throw exception when read by double reader" in { 26 | import readers._ 27 | val workbook = new HSSFWorkbook() 28 | val sheet = workbook.createSheet("Sheet1") 29 | val row = sheet.createRow(1) 30 | val cell = row.createCell(1) 31 | cell.setCellValue(true) 32 | val wrap = CPoi.wrapCell(cell) 33 | val value = wrap.tryValue[Double] 34 | value.isLeft should be(true) 35 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectNumericCellException] should be(true) 36 | } 37 | 38 | it should "read as boolean by boolean reader" in { 39 | import readers._ 40 | val workbook = new HSSFWorkbook() 41 | val sheet = workbook.createSheet("Sheet1") 42 | val row = sheet.createRow(1) 43 | val cell = row.createCell(1) 44 | cell.setCellValue(true) 45 | val wrap = CPoi.wrapCell(cell) 46 | val value = wrap.tryValue[Boolean] 47 | value.isRight should be(true) 48 | value.getOrElse(throw new Exception("Test not pass")) should be(true) 49 | } 50 | 51 | it should "throw exception when read by date reader" in { 52 | import readers._ 53 | val workbook = new HSSFWorkbook() 54 | val sheet = workbook.createSheet("Sheet1") 55 | val row = sheet.createRow(1) 56 | val cell = row.createCell(1) 57 | cell.setCellValue(true) 58 | val wrap = CPoi.wrapCell(cell) 59 | val value = wrap.tryValue[Date] 60 | value.isLeft should be(true) 61 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectDateException] should be(true) 62 | } 63 | 64 | it should "throw exception when read by immutable string reader" in { 65 | import immutableReaders._ 66 | val workbook = new HSSFWorkbook() 67 | val sheet = workbook.createSheet("Sheet1") 68 | val row = sheet.createRow(1) 69 | val cell = row.createCell(1) 70 | cell.setCellValue(true) 71 | val wrap = CPoi.wrapCell(cell) 72 | val value = wrap.tryValue[String] 73 | value.isLeft should be(true) 74 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 75 | } 76 | 77 | it should "throw exception when read by non empty string reader" in { 78 | implicit val ec = readers.nonEmptyStringReader 79 | val workbook = new HSSFWorkbook() 80 | val sheet = workbook.createSheet("Sheet1") 81 | val row = sheet.createRow(1) 82 | val cell = row.createCell(1) 83 | cell.setCellValue(true) 84 | val wrap = CPoi.wrapCell(cell) 85 | val value = wrap.tryValue[String] 86 | value.isLeft should be(true) 87 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 88 | } 89 | 90 | it should "throw exception when read by non blank string reader" in { 91 | implicit val ec = readers.nonBlankStringReader 92 | val workbook = new HSSFWorkbook() 93 | val sheet = workbook.createSheet("Sheet1") 94 | val row = sheet.createRow(1) 95 | val cell = row.createCell(1) 96 | cell.setCellValue(true) 97 | val wrap = CPoi.wrapCell(cell) 98 | val value = wrap.tryValue[String] 99 | value.isLeft should be(true) 100 | value.left.getOrElse(throw new Exception("Test not pass")).isInstanceOf[ExpectStringCellException] should be(true) 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/test/scala/net/scalax/cpoi/write/HSSFWorkbookMemoryWriterTest.scala: -------------------------------------------------------------------------------- 1 | package net.scalax.cpoi.test 2 | 3 | import java.util.Date 4 | 5 | import net.scalax.cpoi.api._ 6 | import net.scalax.cpoi.utils.compat.CollectionCompat 7 | import org.apache.poi.hssf.usermodel.{HSSFCell, HSSFWorkbook} 8 | import org.apache.poi.ss.usermodel.{CellStyle, CellType, Workbook} 9 | import org.scalatest._ 10 | 11 | import scala.util.Try 12 | import scala.collection.compat._ 13 | 14 | class HSSFWorkbookMemoryWriterTest extends FlatSpec with Matchers { 15 | 16 | case object TextStyle extends StyleTransform { 17 | override def operation(workbook: Workbook, cellStyle: CellStyle): CellStyle = { 18 | val format = workbook.createDataFormat.getFormat("@") 19 | cellStyle.setDataFormat(format) 20 | cellStyle 21 | } 22 | } 23 | 24 | case object DoubleStyle extends StyleTransform { 25 | override def operation(workbook: Workbook, cellStyle: CellStyle): CellStyle = { 26 | val format = workbook.createDataFormat.getFormat("0.00") 27 | cellStyle.setDataFormat(format) 28 | cellStyle 29 | } 30 | } 31 | 32 | case class Locked(lock: Boolean) extends StyleTransform { 33 | override def operation(workbook: Workbook, cellStyle: CellStyle): CellStyle = { 34 | cellStyle.setLocked(lock) 35 | cellStyle 36 | } 37 | } 38 | 39 | "HSSFWorkbook" should "set more than 4000 cells with their own CellStyle" in { 40 | import writers._ 41 | 42 | val testUTF8Str = " 测试 UTF8 字符 " 43 | val testDouble = 2333.2233 44 | val workbook = new HSSFWorkbook() 45 | 46 | val defaultCellStyleCount = workbook.getNumCellStyles 47 | 48 | val sheet = workbook.createSheet("SheetA") 49 | val cells = (for (rowIndex <- (1 to 8000)) yield { 50 | val row = sheet.createRow(rowIndex + 2) 51 | List( 52 | row.createCell(3) -> CPoi.wrapData(testUTF8Str).addTransform(TextStyle, Locked(false)) 53 | , row.createCell(6) -> CPoi.wrapData(testDouble).addTransform(DoubleStyle, Locked(true)) 54 | ) 55 | }).flatten.to(List) 56 | val gen = CPoi.newStyleGen 57 | CPoi.multiplySet(gen, cells): Try[StyleGen] 58 | 59 | (for (rowIndex <- (1 to 8000)) yield { 60 | val row = sheet.getRow(rowIndex + 2) 61 | val strCell = row.getCell(3) 62 | strCell.getStringCellValue should be(testUTF8Str) 63 | strCell.getCellStyle.getDataFormatString should be("@") 64 | strCell.getCellStyle.getLocked should be(false) 65 | val doubleCell = row.getCell(6) 66 | doubleCell.getNumericCellValue should be(testDouble) 67 | doubleCell.getCellStyle.getDataFormatString should be("0.00") 68 | doubleCell.getCellStyle.getLocked should be(true) 69 | }) 70 | 71 | val newCellStyleCount = workbook.getNumCellStyles 72 | (newCellStyleCount - defaultCellStyleCount) should be(2) 73 | (newCellStyleCount < 4000) should be(true) 74 | } 75 | 76 | "HSSFWorkbook" should "set more than 4000 cells with their own CellStyle by MutableStyleGen" in { 77 | import writers._ 78 | 79 | val testUTF8Str = " 测试 UTF8 字符 " 80 | val testDouble = 2333.2233 81 | val workbook = new HSSFWorkbook() 82 | 83 | val defaultCellStyleCount = workbook.getNumCellStyles 84 | 85 | val sheet = workbook.createSheet("SheetA") 86 | val cells = (for (rowIndex <- (1 to 8000)) yield { 87 | val row = sheet.createRow(rowIndex + 2) 88 | List( 89 | row.createCell(3) -> CPoi.wrapData(testUTF8Str).addTransform(TextStyle, Locked(false)) 90 | , row.createCell(6) -> CPoi.wrapData(testDouble).addTransform(DoubleStyle, Locked(true)) 91 | ) 92 | }).flatten.to(List) 93 | val gen = CPoi.newMutableStyleGen 94 | CPoi.multiplySet(gen, cells): Unit 95 | 96 | (for (rowIndex <- (1 to 8000)) yield { 97 | val row = sheet.getRow(rowIndex + 2) 98 | val strCell = row.getCell(3) 99 | strCell.getStringCellValue should be(testUTF8Str) 100 | strCell.getCellStyle.getDataFormatString should be("@") 101 | strCell.getCellStyle.getLocked should be(false) 102 | val doubleCell = row.getCell(6) 103 | doubleCell.getNumericCellValue should be(testDouble) 104 | doubleCell.getCellStyle.getDataFormatString should be("0.00") 105 | doubleCell.getCellStyle.getLocked should be(true) 106 | }) 107 | 108 | val newCellStyleCount = workbook.getNumCellStyles 109 | (newCellStyleCount - defaultCellStyleCount) should be(2) 110 | (newCellStyleCount < 4000) should be(true) 111 | } 112 | 113 | "HSSFWorkbook" should "set more than 4000 cells with their own CellStyle by StyleGen and stream" in { 114 | import writers._ 115 | 116 | val testUTF8Str = " 测试 UTF8 字符 " 117 | val testDouble = 2333.2233 118 | val workbook = new HSSFWorkbook() 119 | 120 | val defaultCellStyleCount = workbook.getNumCellStyles 121 | 122 | val sheet = workbook.createSheet("SheetA") 123 | val cells: CollectionCompat.LazyList[(HSSFCell, CellDataAbs)] = (for (rowIndex <- CollectionCompat.seqToLazyList(1 to 8000)) yield { 124 | val row = sheet.createRow(rowIndex + 2) 125 | List( 126 | row.createCell(3) -> CPoi.wrapData(testUTF8Str).addTransform(TextStyle, Locked(false)) 127 | , row.createCell(6) -> CPoi.wrapData(testDouble).addTransform(DoubleStyle, Locked(true)) 128 | ) 129 | }).flatten 130 | val gen = CPoi.newStyleGen 131 | CPoi.multiplySet(gen, cells): Try[StyleGen] 132 | 133 | (for (rowIndex <- (1 to 8000)) yield { 134 | val row = sheet.getRow(rowIndex + 2) 135 | val strCell = row.getCell(3) 136 | strCell.getStringCellValue should be(testUTF8Str) 137 | strCell.getCellStyle.getDataFormatString should be("@") 138 | strCell.getCellStyle.getLocked should be(false) 139 | val doubleCell = row.getCell(6) 140 | doubleCell.getNumericCellValue should be(testDouble) 141 | doubleCell.getCellStyle.getDataFormatString should be("0.00") 142 | doubleCell.getCellStyle.getLocked should be(true) 143 | }) 144 | 145 | val newCellStyleCount = workbook.getNumCellStyles 146 | (newCellStyleCount - defaultCellStyleCount) should be(2) 147 | (newCellStyleCount < 4000) should be(true) 148 | } 149 | 150 | "HSSFWorkbook" should "set more than 4000 cells with their own CellStyle by MutableStyleGen and stream" in { 151 | import writers._ 152 | 153 | val testUTF8Str = " 测试 UTF8 字符 " 154 | val testDouble = 2333.2233 155 | val workbook = new HSSFWorkbook() 156 | 157 | val defaultCellStyleCount = workbook.getNumCellStyles 158 | 159 | val sheet = workbook.createSheet("SheetA") 160 | val cells: CollectionCompat.LazyList[(HSSFCell, CellDataAbs)] = (for (rowIndex <- CollectionCompat.seqToLazyList(1 to 8000)) yield { 161 | val row = sheet.createRow(rowIndex + 2) 162 | List( 163 | row.createCell(3) -> CPoi.wrapData(testUTF8Str).addTransform(TextStyle, Locked(false)) 164 | , row.createCell(6) -> CPoi.wrapData(testDouble).addTransform(DoubleStyle, Locked(true)) 165 | ) 166 | }).flatten 167 | val gen = CPoi.newMutableStyleGen 168 | CPoi.multiplySet(gen, cells): Unit 169 | 170 | (for (rowIndex <- (1 to 8000)) yield { 171 | val row = sheet.getRow(rowIndex + 2) 172 | val strCell = row.getCell(3) 173 | strCell.getStringCellValue should be(testUTF8Str) 174 | strCell.getCellStyle.getDataFormatString should be("@") 175 | strCell.getCellStyle.getLocked should be(false) 176 | val doubleCell = row.getCell(6) 177 | doubleCell.getNumericCellValue should be(testDouble) 178 | doubleCell.getCellStyle.getDataFormatString should be("0.00") 179 | doubleCell.getCellStyle.getLocked should be(true) 180 | }) 181 | 182 | val newCellStyleCount = workbook.getNumCellStyles 183 | (newCellStyleCount - defaultCellStyleCount) should be(2) 184 | (newCellStyleCount < 4000) should be(true) 185 | } 186 | 187 | "HSSFWorkbook" should "throw exception when create more than 4000 cell style" in { 188 | val workbook = new HSSFWorkbook() 189 | a[IllegalStateException] should be thrownBy (for ((_: Int) <- (1 to 4010)) yield { 190 | workbook.createCellStyle 191 | }) 192 | } 193 | 194 | "HSSFWorkbook" should "not write to cell when data is None" in { 195 | import writers._ 196 | 197 | val workbook = new HSSFWorkbook() 198 | 199 | val sheet = workbook.createSheet("SheetA") 200 | 201 | val poiCell1 = sheet.createRow(1).createCell(1) 202 | val poiCell2 = sheet.createRow(1).createCell(2) 203 | val poiCell3 = sheet.createRow(1).createCell(3) 204 | val poiCell4 = sheet.createRow(1).createCell(4) 205 | 206 | val cells = List( 207 | poiCell1 -> CPoi.wrapData(Option.empty[String]) 208 | , poiCell2 -> CPoi.wrapData(Option.empty[Double]) 209 | , poiCell3 -> CPoi.wrapData(Option.empty[Boolean]) 210 | , poiCell4 -> CPoi.wrapData(Option.empty[Date]) 211 | ) 212 | 213 | val gen = CPoi.newStyleGen 214 | CPoi.multiplySet(gen, cells): Try[StyleGen] 215 | 216 | poiCell1.getCellType should be(CellType.BLANK) 217 | poiCell2.getCellType should be(CellType.BLANK) 218 | poiCell3.getCellType should be(CellType.BLANK) 219 | poiCell4.getCellType should be(CellType.BLANK) 220 | } 221 | 222 | "HSSFWorkbook" should "not write to cell with immutable style gen when there is a exception thrown" in { 223 | import writers._ 224 | 225 | val workbook = new HSSFWorkbook() 226 | 227 | val sheet = workbook.createSheet("SheetA") 228 | 229 | val poiCells = (1 to 1000).map { i => 230 | sheet.createRow(i).createCell(1) 231 | } 232 | 233 | val cellData = CPoi.wrapData("2333").addTransform(TextStyle) 234 | val cellDataList = (1 to 1000).map(_ => cellData) 235 | val gen = CPoi.newStyleGen 236 | 237 | val tuple2List = poiCells.zip(cellDataList).zipWithIndex.map { 238 | case (_, index) if index == 602 => null 239 | case (item, _) => item 240 | } 241 | 242 | CPoi.multiplySet(gen, tuple2List): Try[StyleGen] 243 | 244 | poiCells(600).getCellType should be(CellType.STRING) 245 | poiCells(601).getCellType should be(CellType.STRING) 246 | poiCells(602).getCellType should be(CellType.BLANK) 247 | poiCells(603).getCellType should be(CellType.BLANK) 248 | } 249 | 250 | "HSSFWorkbook" should "not write to cell with mutable style gen when there is a exception thrown" in { 251 | import writers._ 252 | 253 | val workbook = new HSSFWorkbook() 254 | 255 | val sheet = workbook.createSheet("SheetA") 256 | 257 | val poiCells = (1 to 1000).map { i => 258 | sheet.createRow(i).createCell(1) 259 | } 260 | 261 | val cellData = CPoi.wrapData("2333").addTransform(TextStyle) 262 | val cellDataList = (1 to 1000).map(_ => cellData) 263 | val gen = CPoi.newMutableStyleGen 264 | 265 | val tuple2List = poiCells.zip(cellDataList).zipWithIndex.map { 266 | case (_, index) if index == 602 => null 267 | case (item, _) => item 268 | } 269 | 270 | CPoi.multiplySet(gen, tuple2List): Try[CPoiDone] 271 | 272 | poiCells(600).getCellType should be(CellType.STRING) 273 | poiCells(601).getCellType should be(CellType.STRING) 274 | poiCells(602).getCellType should be(CellType.BLANK) 275 | poiCells(603).getCellType should be(CellType.BLANK) 276 | } 277 | 278 | } 279 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version := "0.4.0-M8" 2 | --------------------------------------------------------------------------------