React + TypeScript + vte.cxで簡単なWebアプリを作ってみた④CSV出力編

#はじめに
この記事はvte.cx(ブイテックス)というBaaSを使って登録した情報をCSV出力機能を実装してみた記事です。

# 今回実装した機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/ac399701-ee9f-e0a6-fe56-bd8c0ac50b65.png)

今回実装したのは特定のURLにアクセスすると上記のようなCSVが出力される機能です。

## 今回出てくる難しいIT用語録(分かる人は読み飛ばして大丈夫です)

### CSV　is 何
名前と見た目はなんとなく知っていたのですがそれがどういうものかうまく説明できなかったので調べてみました。
>comma-separated values（略称：CSV）は、いくつかのフィールド（項目）をカンマ「,」で区切ったテキストデータおよびテキストファイル。拡張子は .csv、MIMEタイプは text/csv。
「comma-separated variables」とも言う。広く普及した訳語はないが、「カンマ区切り」などとも呼ばれる。Microsoft Excelでは「CSV (カンマ区切り)」としている。
(中略)
引用：[Wikipedia｜Comma-Separated Values](https://ja.wikipedia.org/wiki/Comma-Separated_Values)

カンマ区切りされたファイルらしいですね。

ちなみにExcelで開けるそうなのですが、
> CSVファイルはExcelでも参照・編集が可能です。しかし、CSVファイルをExcelで編集する時には注意が必要です。
CSVファイルには、ExcelやDBなどにあるデータ型の情報が入っていません。抽出元のシステムのデータ型が文字列型、数値型、日付型などに関係なく全て文字情報として出力されています。この様なCSVファイルをExcelで普通に開いた場合、Excelの解釈でデータ型が設定され、結果、下記のような元のCSVファイルの情報と違う形で表示されてしまいます。(例は上記のCSVファイルをExcelで開いた場合の例です)

型は全て文字列なのでExcelに合わせる際に不具合がでる可能性があるそうです。

## api is 何
> 「API」とは、「Application Programming Interface」の頭文字です。

> 大雑把に言うと「アプリケーションをプログラミングするためのインターフェース」という意味です。

> インターフェイスとは、コンピュータ用語でいうと、「何か」と「何か」をつなぐものという意味を持ちます。例えば、USBも「パソコン」と「周辺機器」をつなぐものですので、インターフェイスの一つです。

> つまり、APIとは、この「何か」と「何か」が「アプリケーション、ソフトウェア」と「プログラム」をつなぐもの、という意味になります。

>アプリとアプリを繋げることによって、機能性を拡張させ、さらに便利に使えるようにし、欲を言えば両方のアプリにとってウィン・ウィンの状態を生み出すのがAPIの狙いです。

出典:[データのじかん](https://data.wingarc.com/what-is-api-16084)

簡単にいうと外部の人が作ったプログラムをとってきて自分のコードのなかで使うといったものです。

## サーバーサイドレンダリング　is 何

> 本来JavaScriptで行う画面の書き換え処理などをサーバー側で実行させて、ユーザーの待機時間を短くすること。

> PHPなどを使ってwebアプリケーションを作成した場合もSSRではあるが、
> あえて「SSR」と呼ぶときは、上記のようにJavaScriptと対比させて表現することが多い。

出典:[SSR（サーバーサイドレンダリング）とは](https://qiita.com/negi524/items/40166176a8fb7186c9b2)

画面表示など、ブラウザでやると時間のかかる処理を見えないところでやっちゃおうとったものですね。

# 手順
ではCSV出力の仕方を説明していきます。

vtecxを使ったcsv出力ではサーバーサイドJavascriptを使用する必要があります。

[vte.cxによるバックエンドを不要にする開発(7.サーバサイドJavaScript)](https://qiita.com/stakezaki/items/d596afd085988d76983c)

こちらの記事を参考に進めていきます。

大まかな流れとしては

####①プロジェクト直下のserverフォルダの中に{ファイル名}.csv.tsxという名前のファイルを作る。
####②以下のコマンドでサーバにデプロイする。

```
npm run watch:server -- --env.entry=/server/ファイル名.tsx
```
#### ③ブラウザから```http://{サービス名}/s/ファイル名.csv```を開く

では実際作ったコードを使って一連の流れを進めていきます。

# get-csv-users-information.csv.tsx(csv出力をするファイル)

```server/get-csv-users-information.csv.tsx
import * as vtecxapi from 'vtecxapi'

const feed_data = vtecxapi.getFeed('/users')
// 配列で帰ってくる

const users_info_body = feed_data.map((entry: any) => {
    console.log(JSON.stringify(entry.users))
    // 名前
    const name = entry.users.name || '未登録'
    // 性別
    const gender = entry.users.gender || '未登録'
    // 年齢
    const age = entry.users.name || '未登録'
    // 住所
    const address = entry.users.address || '未登録'
    // パスワード
    const password = entry.users.password || '未登録'
    // メールアドレス
    const email = entry.users.email || '未登録'
    // 郵便番号
    const post_number = entry.users.post_number || '未登録'
    // 好きな住居形態
    const like_residence_type = entry.users.like_residence_type || '未登録'
    // 役職
    const position = entry.users.position || '未登録'
    // 使用言語
    const language = entry.users.language ? `"${entry.users.language}"` : '未登録'

    const array: string[] = []
    array.push(name)
    array.push(gender)
    array.push(age)
    array.push(address)
    array.push(password)
    array.push(email)
    array.push(post_number)
    array.push(like_residence_type)
    array.push(position)
    array.push(language)

    return array
})

//ヘッダー
const user_info_header = ['名前', '性別', '年齢', '住所', 'パスワード', 'メールアドレス', '郵便番号', '好きな住居形態', '役職', '使用言語']

let body: any = [user_info_header, ...users_info_body]

// CSV出力
vtecxapi.doResponseCsv(body, 'summary_index_' + '.csv')

```

まず最初に

```server/get-csv-users-information.csv.tsx
import * as vtecxapi from 'vtecxapi'

const feed_data = vtecxapi.getFeed('/users'
```

としてサーバーサイドレンダリングするためのapiをimportし、vtecxapi.getFeed()というメソッドを使い、エンドポイントに登録されているデータを取得します。

今回サーバーサイドJSということでブラウザの開発者ツールでconsole.logできなく、「どうすれば登録しているデータを確認することができるんだ...」と思っていましたが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/4e1a4df2-ddb4-38ba-9335-897879d909cf.png)

vtecxの管理画面に入り、ログを見ることで確認できました。

```server/get-csv-users-information.csv.tsx
const users_info_body = feed_data.map((entry: any) => {

    // 名前
    const name = entry.users.name || '未登録'
    // 性別
    const gender = entry.users.gender || '未登録'
    // 年齢
    const age = entry.users.name || '未登録'
    // 住所
    const address = entry.users.address || '未登録'
    // パスワード
    const password = entry.users.password || '未登録'
    // メールアドレス
    const email = entry.users.email || '未登録'
    // 郵便番号
    const post_number = entry.users.post_number || '未登録'
    // 好きな住居形態
    const like_residence_type = entry.users.like_residence_type || '未登録'
    // 役職
    const position = entry.users.position || '未登録'
    // 使用言語
    const language = entry.users.language ? `"${entry.users.language}"` : '未登録'

    const array: string[] = []
    array.push(name)
    array.push(gender)
    array.push(age)
    array.push(address)
    array.push(password)
    array.push(email)
    array.push(post_number)
    array.push(like_residence_type)
    array.push(position)
    array.push(language)

    return array
})

//ヘッダー
const user_info_header = ['名前', '性別', '年齢', '住所', 'パスワード', 'メールアドレス', '郵便番号', '好きな住居形態', '役職', '使用言語']

let body: any = [user_info_header, ...users_info_body]

// CSV出力
vtecxapi.doResponseCsv(body, 'summary_index_' + '.csv')

```
次に先ほど取得したデータをmapメソッドを使って必要なデータを配列に格納していきます。

[mapメソッド　Javascript公式サイト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

(mapメソッドは取得したデータを自分の意図した通りにすることができるフロントエンド開発に必須のものなのでしっかりマスターしたいものです。)

取得したデータはmapメソッドによって

```tsx
users_info_body = [['name','gender','age',.....'language'],['名前','未登録',.....'日本語']]
```

といった構造になります。

それでここからがCSV出力の本題です。

```tsx
vtecxapi.doResponseCsv(出力したい配列,CSVのファイル名)
```
というメソッドを使うことでurlアクセス時にCSVを出力することができます。

出力したい配列なのですが、例えば

```tsx
const date_array: any = ['集計期間']
let body: any = [date_array, ['a', 'b', 'c'], ['aa', 'bb', 'cc']]
// CSV出力
vtecxapi.doResponseCsv(body, 'summary_index_' + '.csv')
```
とすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/511ca7ae-1f07-4474-2afe-b489e9ad0a13.png)

このようなCSVファイルを出力することができます

配列一つが1行になって左づめで入力されていきます。
また第二引数のファイルネームはsummary_index.csvという名前で指定しているのでちゃんとその名前の通り出力されました。

# 感想
登録された情報を取得してCSVに出力する機能はfirebaseにはない機能で、vte.cxというサービス内で用意されているのでかなり使い勝手が良いなと思いました。
集計処理をするアプリなどとても作りやすそうです。