case class 超过 22 个字段到 Scala 中的 CSV

case class more than 22 fields to CSV in Scala

是否有任何库可以将超过 22 个字段的大小写 class 转换为 CSV? 我尝试使用 kantan 但编码器只允许 22 个字段。

P.S:我使用带有简单解码功能的 circe 将 json 字符串序列化为 27 个字段 case class。感谢 .

对此可能有多种解决方案。显然,如果您可以将 json 转换为 27 个字段 class,那么您可以先将 csv 转换为 json,然后解码 json。 您可以找到转换器库:
1. here
2. here

其次,github 回购已经关闭了问题。他们建议将大案例 class 拆分为较小的案例 classes。

import kantan.csv._

final case class RootModel(model1: Model1, model2: Model2)
final case class Model1(value: Int)
final case class Model2(value: String)

object RootModel {
  implicit val headerDecoder: HeaderDecoder[RootModel] = {

    // Decoders for Model1 and Model2
    implicit val model1Decoder: HeaderDecoder[Model1] = HeaderDecoder.decoder("Header1")(Model1)
    implicit val model2Decoder: HeaderDecoder[Model2] = HeaderDecoder.decoder("Header2")(Model2)

    new HeaderDecoder[RootModel] {

      override def fromHeader(header: Seq[String]) =
        // Turns the header into row decoders for Model1 and Model2
        for {
          model1D ← model1Decoder.fromHeader(header)
          model2D ← model2Decoder.fromHeader(header)
        } yield
            // Merge these two decoders into a single RowDecoder
          RowDecoder.from { row ⇒
            for {
              model1 ← model1D.decode(row)
              model2 ← model2D.decode(row)
            } yield RootModel(model1, model2)
          }

      // There's unfortunately nothing we can do if no header is provided.
      override def noHeader = sys.error("Attempting to decode without a header.")
    }
  }

}

使用方法:

scala> import kantan.csv._
scala> import kantan.csv.ops._
scala> "Header1,Header2\n1,foo".asCsvReader[RootModel](rfc.withHeader).foreach(println _)
// Success(RootModel(Model1(1),Model2(foo)))

Source

设法找到将所有字段写入文件的解决方案。

  1. 我将 27 个字段案例 class 拆分为两个案例 classes.
  2. 然后我为这两种情况编写了隐含的 CellEncode classes
  3. 然后 RowEncoder 隐式用于案例 class 其中包含 2 个新创建的案例 classes 作为字段
  4. 最终 Excel 将有 2 列,所有 27 列信息管道分开。然后您可以将管道分隔的内容转换为 Excel.
  5. 中的列
case class subCaseClass1 ( id: Int, name: String) //customer info
case class subCaseClass2 (paymentId: Int, itemId: Int) //payment info
case class finalCaseClass (header: subCaseClass1, payment: subCaseClass2)

//Cell encode Implicits
implicit val CustomerInfoCellEncode: CellEncoder[subCaseClass1] = CellEncoder.from(x => s"${x.asInstanceOf[subCaseClass1].id}|${x.asInstanceOf[subCaseClass1].name}")
implicit val PaymentInfoCellEncode: CellEncoder[subCaseClass2] = CellEncoder.from(x => s"${x.asInstanceOf[subCaseClass2].paymentId}|${x.asInstanceOf[subCaseClass2].itemId}")

// RowEncoder implicit
implicit val paymentTupleRowEncoder: RowEncoder[finalCaseClass]= RowEncoder.encoder(0, 1)((is: finalCaseClass) => (is.subCaseClass1, is.subCaseClass2))

//Write to CSV
new File("test.csv").writeCsv(value,rfc) //value is List(finalCaseClass)