【GAS】SpreadSheet を csv にして Drive に保存する

今まで GAS でトーク Bot を動かしてトーク履歴を残したり、健康調査をする Bot を作ってきました。

[LINEWORKS BOT とのやり取りを Google スプレッドシートに残す](https://qiita.com/kunihiros/items/570846dcbde2037394c2)
[毎日の健康調査をする仕組みを BOT で作ってみたよ](https://qiita.com/kunihiros/items/8861e4cb9fc9a7e9d1fb)

SpreadSheet に情報が残ってるんだから自分はそれを見ればいいわけですが、他の人に見せるときにはそうはいきません。
Google Drive からダウンロードして Excel データに変換して添付して渡すとかするわけです。

でも、どうせなら一定期間分を定期的にログデータとして csv で保管しといた方がいいのではと思ったわけですよ。

そこで、SpreadSheet を csv に変換し、Drive に保存する方法を調べてみました。

# SpreadSheet を csv するには

以下の 3STEP で実現します。
1. SpreadSheet のデータを読み込んで string にする
2. string データを csv 形式の blob にする
3. blob データを Google Drive に書き込む

blob は GAS 独自のオブジェクトで、ファイル名と MIME タイプの指定がついています。
Google Drive などの Google API を利用してファイルをやりとりするときによく使います。
JavaScript の Blob とは似ていますが違うものなので注意です。(｀・ω・´)

## SpreadSheet のデータを読み込んで string にする

csv データはカンマで区切られた一行の文字列です。
Comma-Separated Values (カンマ・セパレイテッド・バリューズ) の略ですね。
なので、SpreadSheet のデータを読み込んだら列の値ごとに `,` (カンマ) を入れて、行が変わるときは `\r\n` (改行コード) を入れていきます。

```js
function loadData() {
  const data = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  let csv = '';
  for(let i = 0; i < data.length; i++) {
    csv += data[i].join(',') + "\r\n";
  }
  return csv;
}
```

これで csv っぽい String が作成できました。

## string データを csv 形式の blob にする

次に、先ほど作成した String データを元に blob データを作ります。

```js
function createBlob(csv) {
  const fileName = 'テスト.csv'
  const contentType = 'text/csv';
  const charset = 'utf-8';
  const blob = Utilities.newBlob('', contentType, fileName).setDataFromString(csv, charset);
  return blob;
}
```

csv 形式で保存するため、fileName の最後には必ず拡張子の `.csv` をつけます。
contentType には `text/csv` を指定します。

blob! blob!(*‘∀‘)

## blob データを Google Drive に書き込む

blob データができたら、あとは Google Drive に書き込むだけですね～♪
これは Drive API を使えば簡単にできます。

```js
function writeDrive(blob) {
  const folderId = 'folderIdxxxyyyzzz';
  const drive = DriveApp.getFolderById(folderId);
  drive.createFile(blob);
}
```

Drive の folderId は予め調べておきましょう。
Google Drive の保存したいフォルダをブラウザで開くと、URL の最後が folderId になっています。

![1602753862.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/7e9694d2-9360-8e56-c31b-5b24a730f87f.png)

# プログラムを実行！

では、今までのプログラムをすべてまとめて実行してみましょう！

```js
function createCsv() {
  const csv = loadData();
  const blob = createBlob(csv);
  writeDrive(blob);
}
```

![1602754204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/4da6bab9-66a4-9ab3-4594-7c7cca377ae9.png)

はい！Drive 上に csv データが作成されましたね！
完成～！(*‘∀‘)

### コード全体

```js
function createCsv() {
  const csv = loadData();
  const blob = createBlob(csv);
  writeDrive(blob);
}

function loadData() {
  const data = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  let csv = '';
  for(let i = 0; i < data.length; i++) {
    csv += data[i].join(',') + "\r\n";
  }
  return csv;
}

function createBlob(csv) {
  const fileName = 'テスト.csv'
  const contentType = 'text/csv';
  const charset = 'utf-8';
  const blob = Utilities.newBlob('', contentType, fileName).setDataFromString(csv, charset);
  return blob;
}

function writeDrive(blob) {
  const folderId = 'folderIdxxxyyyzzz';
  const drive = DriveApp.getFolderById(folderId);
  drive.createFile(blob);
}
```
# おわりに
ここまでお付き合いいただきありがとうございました。

ふっふっふ。
実は csv データを作れるようになったら、やりたいことがあるのですよ。
前の記事でも書きましたが、LINEWORKS のトーク Bot がファイルの送受信に対応になったので、定期的に Bot に csv を送信してもらうのです！
[【LINEWORKS API】新機能！BOT でファイルを送受信！](https://qiita.com/kunihiros/items/725b917b2952c5978d3f)

なので、次回は csv をトーク Bot に送信させてみたいと思います！
楽しみだな～♪

ではまた！(^^)/

# 参考にさせていただきましたm(_ _)m


[スプレッドシートのデータをGASを使って1クリックでCSVに吐き出すものを作る。](https://www.pnkts.net/2018/04/27/spreadsheet-gas-csv/)
[GAS の Blob とファイル変換まとめ](https://qiita.com/a_eau_/items/01bc14bfc5cb5ef12e64)