#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:
У вас есть несколько ошибок в вашем коде.
asJsObject()
это метод, который не существует вJsValue
. Вместо этого вы должны использоватьvalue.as[JsObject]
.jsObject.fields
имеет типSeq[(String, JsValue)]
, поэтому вы не можете вызватьjsObject.fields("1. open")
. Вместо этого вы должны вызвать:jsObject("1. open").toString
- Вызов
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). Можете ли вы мне помочь, как я могу теперь изменить код, который вы отправили выше?