Googleスプレッドシートのデータを表示させてリッチな静的サイトを作る

# 背景

こんなサイトを作りました

[https://meatup.love/](https://meatup.love/) 🍖

どうやっていい感じにデータを取得してきたのか気になる、という方がいたので、ここに書いてみます！

# 概要

[Google SpreadSheet のデータを JSON 形式で取得する Web API をサクッと作る](https://qiita.com/takatama/items/7aa1097aac453fff1d53)
ほとんどは上記の記事の内容です。

ただこの記事では、「GoogleスプレッドシートをAPIサーバー化し」てフロントでデータを受け取るところまで記載します。

# この記事に書いてあること

こんなデータが
<img width="539" alt="Screen Shot 2018-07-13 at 17.59.00 copy.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/913945b6-56c9-8e80-fc90-0294cdd732e8.png">

こんなデータ形式に変換され

```json

[
  {
    "title": "1973年のピンボール",
    "review": "ウイスキー飲みたくなる",
    "rate": 4
  },
  {
    "title": "風の歌を聴け",
    "review": "忘れた",
    "rate": 3
  },
  {
    "title": "ノルウェイの森",
    "review": "まだ途中",
    "rate": 4
  },
  {
    "title": "青の炎",
    "review": "ニノちゃん主演で映画化",
    "rate": 5
  },
  {
    "title": "心が雨漏りする日には ",
    "review": "エモい",
    "rate": 5
  },
  {
    "title": "成りあがり",
    "review": "ビッグ",
    "rate": 100
  }
]
```

最終的にこうなるまでのすべてが書かれています:ramen:

<p data-height="321" data-theme-id="29715" data-slug-hash="qyOZWe" data-default-tab="js,result" data-user="ksyunnnn" data-embed-version="2" data-pen-title="BookList" class="codepen">See the Pen <a href="https://codepen.io/ksyunnnn/pen/qyOZWe/">BookList</a> by Kobashi syunsuke (<a href="https://codepen.io/ksyunnnn">@ksyunnnn</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


今回はフロントサイドではVue.jsを使用します。JavaScriptの知識があれば、jQueryでもなんでも応用はできるかと :ok_woman: 

# 手順

## データを用意

<img width="724" alt="Screen Shot 2018-07-13 at 17.59.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/ec1a90f4-3e0d-9fd3-a993-205abd12b8cf.png">

こんな感じのデータを用意します。
今回の例では、本のレビューコメントと評価レートをデータとして扱います。

## Google Apps Scriptを利用してデータをjson化

1. メニューバーの「ツール」よりスクリプトエディタを開く

<img width="380" alt="Screen Shot 2018-07-13 at 17.59.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/d3e14a67-b72d-d4de-2784-eb369ef87a77.png">


2. スクリプトを追加指定していく

こんな画面で追加します。
<img width="867" alt="Screen Shot 2018-07-13 at 17.59.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/75235da3-c651-774a-9983-2ee8e188999a.png">

コードの中身はこちら

```javascript
function getData(id, sheetName) {
  var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
  var rows = sheet.getDataRange().getValues();
  var keys = rows.splice(0, 1)[0];
  return rows.map(function(row) {
    var obj = {}
    row.map(function(item, index) {
      obj[keys[index]] = item;
    });
    return obj;
  });
}

function doGet(e) {
  // getDataの第1引数のハッシュ値は、スプレッドシートのURLの
　// https://docs.google.com/spreadsheets/d/｛この部分｝/edit#gid=0
　// です 
 
 //　第2引数はデータのある表のシート名です！
  var data = getData('1pxAIGBFP7-UUC16dm9tZ6HYdbN6zyVkYpZSqnZI3DAg', 'BookList');
  var output = ContentService.createTextOutput(JSON.stringify(data, null, 2));
  output.setMimeType(ContentService.MimeType.TEXT);
  return output;
}
```

3. プロジェクトをWebアプリケーションとして公開する

メニューより選択

<img width="659" alt="Screen Shot 2018-07-13 at 18.00.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/c54aa48e-7ea1-4264-9c38-e6b014746685.png">


公開範囲を全員に変更

<img width="528" alt="Screen Shot 2018-07-13 at 18.00.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/f991aa23-1818-3184-8e07-47b36eb3d867.png">

承認が必要だったり、ブラウザ環境によっては危ないアクセスと言われたりしますが
無視して進みます。

公開するとURLが表示されるので、アクセスしてみます。

<img width="430" alt="Screen Shot 2018-07-18 at 16.14.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/117615/22149cd6-f33a-6938-7887-0446ef86143d.png">

[こんな感じ](https://script.googleusercontent.com/macros/echo?user_content_key=e6l-RXKwF6Rp3TUFxIaD_RD_9YTt8ybtt5ArCtljhWwc3dNjV5u-Mxq4THW_ouKvj6hYmf_G0khq87Ei9nbFgvTkxkgjhiP7m5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnIS-ADVFeIHCgVFYvBGU6jYpzJogkp2puk1Wsy6wpPqpshFenyrFRaRcusYi7XJgQef-XyRORxDO&lib=MzmQHtdNADhhZL7MJ9Lc1DkjsOTksYyEw)でデータが表示されれば完了！

# フロント側でデータを受け取って表示

受け取り確認

```javascript
  fetch('https://script.google.com/macros/s/AKfycbzdU4Md20DUSfQFcqJJbUG81LIFGh42WmAQZN_9r3wh3SKSJknB/exec')
      .then(res => res.json())
      .then(
      result => {
       console.log(result)
      },
      error => {
       console.log("errorらしい")
      },
```

これは[CodePen](http://codepen.io/)とかつかって確認すると楽です。コンソールに値が表示されれば受け取りOK :ok_woman: 

Vue.jsで実装

あとは最初に掲載したCodepenのまま
取得したデータをJavaScriptを利用してhtmlに差し込んでいます:pizza:

```javascript:index.js

new Vue({
  el: '#app',
  data () {
    return {
      message: 'Book List',
      books: null,
    }
  },
  mounted () {
    fetch(
      'https://script.google.com/macros/s/AKfycbzdU4Md20DUSfQFcqJJbUG81LIFGh42WmAQZN_9r3wh3SKSJknB/exec',
    )
      .then(res => res.json())
      .then(
      result => {
        this.books = result
      },
      error => {

      },
    );
  }
})
```

```html:index.html

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <h1>{{ message }}</h1>
  <div class="books">

    <div class="book" v-for="book in books">
      <div class="info">
        <div class="title"><i class="book icon"></i> {{book.title}}</div>
        <div class="review">{{book.review}}</div>
      </div>
      <div class="rate">
        <div class="ui statistics">
          <div class="statistic">
            <div class="value"><i class="star icon"></i> {{book.rate}} </div>
          </div>
        </div>
      </div>
    </div>

  </div>
</div>

```

```scss:style.scss

@import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500');
* {
  margin: 0;
  padding: 0;
}

#app {
  font-size: 16px;
  font-family: 'Roboto', sans-serif;
  padding: 16px 48px;
}

h1 {
  font-weight: 100;
  margin-bottom: 48px;
  position: fixed;
  background: rgba(#fff,.8);
}

.books {
  max-width: 720px;
  margin: 80px auto;
}

.book {
  display: flex;
  justify-content: space-between;
  font-weight: 300;
  padding: 8px;
  margin-bottom: 24px;
  &:hover {
    background: darken(#fff,5%);
    i.star {
      color: #FECA42;
    }
  }
  .title {
    font-size: 24px;
    line-hetght: 48px;
    margin-bottom: 24px;
  }
}
```

そしてこうなるはず

<p data-height="321" data-theme-id="29715" data-slug-hash="qyOZWe" data-default-tab="js,result" data-user="ksyunnnn" data-embed-version="2" data-pen-title="BookList" class="codepen">See the Pen <a href="https://codepen.io/ksyunnnn/pen/qyOZWe/">BookList</a> by Kobashi syunsuke (<a href="https://codepen.io/ksyunnnn">@ksyunnnn</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


まとめてみたけど、意外と難しいのかな、、、

以上ですｗ

気軽に質問とか指摘あればください〜〜〜〜〜 :meat_on_bone: