【GAS】スプレッドシートのデータをGASでJSONファイルにしてダウンロードする

# GASとは
Googleが提供しているプログラミング言語「Google Apps Script」のことです。
GmailやGoogleカレンダー、Googleドライブなど、Googleが提供している様々なサービスと連携できます。
JavaScriptをベースにしているみたいです。

業務の効率化で活用できる場面が多々あると思うので、以降では、特にスプレッドシートでのGASの使い方を説明します。

# スプレッドシートでGASを使うには
スプレッドシートのメニューから、[ツール] -> [スクリプト エディタ]を選択してスクリプトエディタを開くとGASが書けます。
ExcelのVBAみたなイメージで、シートやセルの情報を扱って処理するようなプログラムが書けます。

# スプレッドシートから指定した範囲のデータを取得する

**スプレッドシート（社員シート）**
<img width="270" alt="スクリーンショット 2020-06-30 12.24.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322782/bc82eb58-b8bf-9795-54c9-83a722126a1e.png">

上記のデータをGASで取得したい場合、以下のように書きます。

```javascript:gas
var sheet = SpreadsheetApp.getActive().getSheetByName('社員シート');
var sheet_values = sheet.getRange(2, 1, 4, 2).getValues();

// sheet_values
// => [ [ 1, 'sato' ],[ 2, 'suzuki' ],[ 3, 'takahashi' ],[ 4, 'tanaka' ] ]
```

指定した範囲のデータが配列で取得されます。

# スプレッドシートのデータをJSONファイルにしてダウンロードする
スプレッドシートのデータをJSONファイルにしてダウンロードし、システムに読み込ませる機会があったので、その時に作ったプログラムのサンプルを記載します。
上記の**社員シート**を以下のようなJSONファイルにしてダウンロードします。

```json:json
[
	{
		"id": 1,
		"name": "sato"
	},
	{
		"id": 2,
		"name": "suzuki"
	},
	{
		"id": 3,
		"name": "takahashi"
	},
	{
		"id": 4,
		"name": "tanaka"
	}
]
```


## 実装

以下のプログラムでは、`main()`が実行されると、dialog.htmlが表示され、dialog.html内のリンクをクリックすることでJSONファイルをダウンロードできます。
GASはサーバー上で動くので、ローカルにファイルをダウンロードするためにプロジェクトにhtmlファイルを追加して、htmlの`a`タグを使ってダウンロードします。

下記のhtml内の`a`タグをクリックすると、`<?= =>`で埋め込んだGASスクリプト`getJson()`が実行されてスプレッドシートのデータをJSONにしてJavaScriptに返します。
JavaScriptはJSONを受け取るとファイルに変換して`a`タグの機能でダウンロードが行われる仕組みです。

```javascript:gas
function main() {
  var html = HtmlService.createTemplateFromFile("dialog").evaluate();
  SpreadsheetApp.getUi().showModalDialog(html, "JSONダウンロード");
}

function getJson() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('社員シート');
  var sheet_values = sheet.getRange(2, 1, 4, 2).getValues();
  // => [ [ 1, 'sato' ],[ 2, 'suzuki' ],[ 3, 'takahashi' ],[ 4, 'tanaka' ] ]

  var keys = ['id','name'];
  var json_array = [];
  
  // シートから取得したデータを一つずつ処理する
  sheet_values.forEach(function(item, i){
    var item_dictionary = getItemDictionary(keys, item);
    json_array[i] = item_dictionary;
  });

  // 配列をJSON文字列に変換して返す
  return JSON.stringify(json_array, null, '\t');

  // データをDictionaryにする
  function getItemDictionary(keys, item){
    var reuslt = {};
    keys.forEach(function(key, i){
      reuslt[key] = item[i];
    });
    return reuslt;
  }
}
```

```html:dialog.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script type='text/javascript'>
      function downloadJson(elm) {
        var content = <?= getJson(); ?>;
        var blob = new Blob([content], {"type": "application/json"});
        elm.href = window.URL.createObjectURL(blob);
      }
    </script>
  </head>
  <body>
    <p><a href="#" download="employee.json" onclick="downloadJson(this)">employee.json</a></p>
  </body>
</html>
```

## ボタンにイベントを割り当てる
さらに**社員シート**にボタンを作って、ボタンをクリックすると `main()` が実行されるようにすると便利です。
ボタンは、[挿入] -> [図形を描画]で簡単に作れます。
<img width="174" alt="スクリーンショット 2020-06-30 12.56.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322782/ec9c4b67-6471-b9bc-39d5-c076a0fc68eb.png">

ボタンを選択して、右上の点マークをクリックし、[スクリプトを割り当て]を選択すると、ボタンのクリックイベントにGASの関数を割り当てることができます。

## 動作イメージ
<img width="1440" alt="スクリーンショット 2020-06-30 12.38.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322782/e3e60f3f-56ce-621d-2ca3-e3d855d430c2.png">

ボタンをクリックするとダイアログが表示され、ダイアログ内のリンクをクリックするとJSONファイルをダウンロードできます。

※2020/06/30現在、Chromeを使うとGASでファイルのダウンロードができなくなっています。
この挙動は[IssueTracker](https://issuetracker.google.com/issues/157368720)にも挙げられています。
お試しの際は、他のブラウザを使用してください。