LoginSignup
9
9

More than 1 year has passed since last update.

kotlinでCSVファイル(金沢のオープンデータ)を読み取る

Last updated at Posted at 2019-12-04

はじめに

今回はkotlinでCSVを読み取る機会があったので、この記事にまとめます。
最初はライブラリを使おうと思いopenCSVなど使ってみたのですが、途中でエラーが出て断念。
他にもライブラリはいくつかあったんですが今回使わずやってみました。
ちなみに環境はAndroidStudioです。
もしかしたら今度ライブラリを使ってみた記事をあげるかもしれません。

調べたライブラリ

最初にやること

  1. AndroidStudioでプロジェクトを立ち上げる。
  2. 今回はKanazawaオープンデータのCSVを読み取ります。下記からCSVを適当に取ってきます。
    https://www4.city.kanazawa.lg.jp/13021/opendata/renkei.html
  3. CSVをプロジェクトの/app/src/assets/配下に置く。assetsフォルダがなかったら作りましょう。 (File -> new -> Directory -> assetsフォルダを作成)
    今回使うCSVファイルは避難所のやつです。 スクリーンショット 2019-12-04 15.59.26.png

今回主にいじるファイル

layout

  • activity_main.xml

kotlinファイル

  • MainActivity.kt
  • Shelter.kt(今回は避難所データを持ってくるのでShelterにしてみました。)

ListViewを作る

まずactivity_mainにListViewを配置します。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/title"
        android:textAlignment="center"
        />
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>

data classを作る

次にCSVのデータを格納するデータクラスを作ります。
データクラスについては下の記事がとても参考になったので記させていただきます。
https://blog.y-yuki.net/entry/2019/05/30/003000
避難所なのでShelter.ktにしました。ここはcsvのデータによってお好みでどうぞ
今回は名称と概略のみ表示させるのでnameとoverviewカラムのみ作成します。

Shelter.kt
data class Shelter (
    //名称,概略
    var name: String? = null,
    var overview: String? = null
){}

MainActivity.ktを作る

このファイルでCSVの読み取りと表示をします。

MainActivity.ktclass
class MainActivity : AppCompatActivity() {
    //1行目が格納される。
    var column: Array<String> = emptyArray<String>()
    //shelterインスタンスが格納される
    var shelters: Array<Shelter> = emptyArray()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //csvの読み取り
        readCsv("shisetsu_hinan.csv")
        // ListViewの表示
        val listView: ListView = findViewById(R.id.listView)
        val listItems: Array<String> = setItem(shelters)
        val adapter = ArrayAdapter(this,android.R.layout.simple_listItem_1,listItems)
        listView.adapter = adapter
    }

    //assetsからshisetsu_hinan.csvを持ってくる
    fun readCsv(filename: String){
        try {
            val file = resources.assets.open(filename)
            val fileReader = BufferedReader(InputStreamReader(file))
            var i: Int = 0
            fileReader.forEachLine {
                if (it.isNotBlank()) {
                    if (i == 0) {
                        //1行目だけ別の配列に読み取る。
                        column = it.split(",").toTypedArray()
                    } else {
                        //2行目以降
                        val line = it.split(",").toTypedArray()
                        fetchCSV(line)
                    }
                }
                i++;
            }
        }catch (e: IOException) {
            //例外処理
            print(e)
        }
    }
    //Shelters配列にshelterインスタンスを格納
    fun fetchCSV(line: Array<String>){
            val shelter = Shelter(
                name = line[10],
                overview = line[11]
            )
            //sheltersに全ての避難所を格納
            shelters += shelter
    }
    //リストに表示する文字列をセット
    fun setItem(shelters: Array<Shelter>): Array<String>{
        var items: Array<String> = emptyArray()
        shelters.forEach {
            items += """
                |避難所名:{${it.name}}
                |概要:{${it.overview}}""".trimMargin()
        }
        return items

    }
}

やってること
1. readCSV関数でCSVの読み取りをしています。1行ずつ読み取って最終的にSheltersに格納されます。
2. listViewに表示する文字列をセット。setItems関数でリストに表示する文字列を設定しています。
3. 最後にlistviewにアイテムをセットしています。

まとめ

今回はライブラリを使わずにやってみました。めんどくさくて全てのカラムを格納とはいきませんでしたがまたdataクラスとCSVを関連づけしてくれるライブラリの記事を時間があったら書こうと思います。
いいライブラリや記事があったら教えてください。

9
9
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9