Создание csv-файла в Scala

#json #scala #opencsv

#json #scala #opencsv

Вопрос:

Я пытаюсь создать csv файл в Scala, получая данные в виде JsValue из API третьей части. Мой метод сохранения данных в CSV-файл :

 def saveToCSV(str:Seq[JsValue]) = {
  val outputFile = new BufferedWriter(new FileWriter("Result.csv"))
  val csvWriter = new CSVWriter(outputFile)
    val data = str.head
    data match {
      case JsObject(fields) => {
        var listOfRecords = new ListBuffer[Array[String]]()
        //val csvFields = Array("Open","High","Low","Close","Volume")
        //listOfRecords  = csvFields
        fields.values.foreach(value => {
          val jsObject = value.asJsObject()
          val nameList = List(jsObject.fields("1. open").toString,jsObject.fields("2. high").toString,jsObject.fields("3. low").toString,jsObject.fields("4. close").toString,jsObject.fields("5. volume").toString)
          listOfRecords  = Array(nameList.toString)
          csvWriter.writeAll(listOfRecords.toList.asInstanceOf)
          println("Written!")
          outputFile.close()
        })
      }
      case JsNull => println("Null")
    }
 

В приведенном выше коде в строке **csvWriter.writeAll(listOfRecords.toList.asInstanceOf)** я получаю это исключение.

 Exception in thread "main" java.lang.ClassCastException: class scala.collection.immutable.$colon$colon cannot be cast to class scala.runtime.Nothing$ (scala.collection.immutable.$colon$colon and scala.runtime.Nothing$ are in unnamed module of loader 'app')
 

При удалении asInstanceOf из csvWriter.writeAll(listOfRecords.toList.asInstanceOf) этой строки я получаю ошибку времени компиляции в методе writeAll(), в которой говорится, что он ожидает параметр типа util .Список[Массив[Строка]]

Может ли кто-нибудь, пожалуйста, помочь мне решить эту проблему?

Ответ №1:

У вас есть несколько ошибок в вашем коде.

  1. asJsObject() это метод, который не существует в JsValue . Вместо этого вы должны использовать value.as[JsObject] .
  2. jsObject.fields имеет тип Seq[(String, JsValue)] , поэтому вы не можете вызвать jsObject.fields("1. open") . Вместо этого вы должны вызвать: jsObject("1. open").toString
  3. Вызов listOfRecords.toList.asInstanceOf возвращает null результат. Вы должны указать, во что вы хотите его преобразовать. Но для того, чтобы преобразовать его в тип java, вы можете просто вызвать: listOfRecords.toList.asJava . Не забывайте: import scala.jdk.CollectionConverters._

Полный метод:

 import com.opencsv.CSVWriter
import play.api.libs.json.{JsNull, JsObject, JsValue}

import java.io.{BufferedWriter, FileWriter}
import scala.collection.mutable.ListBuffer
import scala.jdk.CollectionConverters._

def saveToCSV(str: Seq[JsValue]) = {
  val outputFile = new BufferedWriter(new FileWriter("Result.csv"))
  val csvWriter = new CSVWriter(outputFile)
  val data = str.head
  data match {
    case JsObject(fields) => {
      var listOfRecords = new ListBuffer[Array[String]]()
      //val csvFields = Array("Open","High","Low","Close","Volume")
      //listOfRecords  = csvFields
      fields.values.foreach(value => {
        val jsObject = value.as[JsObject]
        val nameList = List(jsObject("1. open").toString, jsObject("2. high").toString, jsObject("3. low").toString, jsObject("4. close").toString, jsObject("5. volume").toString)
        listOfRecords  = Array(nameList.toString)
        csvWriter.writeAll(listOfRecords.toList.asJava)
        println("Written!")
        outputFile.close()
      })
    }
    case JsNull => println("Null")
  }
}
 

Это будет работать в предположении, что заголовок str содержит JSObject с полями:

  • «1. открыть»
  • «2. высокий»
  • «3. низкий»
  • «4. закрыть»

Вы намеренно используете только первый элемент входных данных для этой функции? Пожалуйста, обратите внимание, что str.head это небезопасно, если последовательность пуста.

Комментарии:

1. Спасибо. Теперь при вызове этого метода я использую следующий код: val str = EntityUtils . toString(entity,»UTF-8″) val JsonParser = Json.parse(str) SaveService.saveToCSV(jsonParser.as [JSObject].поля(1). Можете ли вы мне помочь, как я могу теперь изменить код, который вы отправили выше?