nodejsのObjectをGoogleSpreadsheetで見る方法

私はNodejsでコンソールアプリ等をよく作っています。  
結果をconsoleに出力する時に、読みにくい場合が多々あります。
とはいえHtmlで見やすい形にするのも面倒です。  
そういえば確かGoogleSpreadsheetってAPIあるよね、と思い使ってみました。

## 目標

```coffee
items = [
  ['Alex',17,'1234-5678']
  ['Billy',33,'1357-2468']
  ['Charlie',28,'3333-3333']
  ['Daniel',15,'5555-5555']
  ['Edward',63,'9999-9999']
]
```
↑こんな感じの配列を
↓こうしたい。
![ss9.png](https://qiita-image-store.s3.amazonaws.com/0/4784/ae045a1d-4f47-29ba-301a-6f9904e1f1dc.png "ss9.png")

## 前準備

Google SpreadsheetのAPIを使うための前準備です。webで行います。
大きく分けて２つのSTEPがあります。

1. developers-consoleでアカウントを作成して認証用のJSONファイルをダウンロードする
2. Spreadsheetを開いて(1)のアカウントを共有リストに加える

### Google developers consoleの設定

[console.developers.google.com](https://console.developers.google.com/iam-admin/projects)にアクセスして[プロジェクトを作成]をクリック

プロジェクト名を適当に入力して[作成]するとこんなページに移動します。
(もし違う場合は一覧から作成したプロジェクトを選択して移動してください)

[Drive API]をクリック -> [有効にする]

![ss1_1.png](https://qiita-image-store.s3.amazonaws.com/0/4784/6573dd62-31ec-7135-6640-43b86cbbe7c5.png "ss1_1.png")



画面左のタブから[認証情報]をクリック -> [認証情報を作成] -> [サービスアカウントキー]

![ss3.png](https://qiita-image-store.s3.amazonaws.com/0/4784/e701131f-48e2-fcc1-14aa-fa892ca74bcc.png "ss3.png")

![ss4.png](https://qiita-image-store.s3.amazonaws.com/0/4784/8ab577df-6312-5ade-850a-02dc6f12efc9.png "ss4.png")


サービスアカウントキーの作成画面になります。[サービスアカウント] -> [新しいサービスアカウント]からサービスアカウント名を入力

[役割を選択] -> [プロジェクト] -> [オーナー]

[キーのタイプ]を[JSON]にして[作成]

以上で認証情報が入ったJSONファイルがダウンロードされますので、Nodejsのプロジェクトに移動しておきます。

### Spreadsheet側の設定

#### 1.認証用メールアドレスを控えておく
まず先程ダウンロードしたJSONファイルを開いて、client_emailの部分に入っているメールアドレスを控えておいてください。

`"client_email": "myname@gss-test-xxxxxx.iam.gserviceaccount.com"`


#### 2.スプレッドシートIDを控えておく
[Google スプレッドシート](https://docs.google.com/spreadsheets/u/0/)を開いて新規のスプレッドシートを作成します。

URL欄からSpreadsheet-IDを控えておいてください。Nodejsで使います。
`https://docs.google.com/spreadsheets/d/[Spreadsheet-ID]/edit#gid=0`


#### 3.(1)の認証用メールアドレスを使って共有する
画面右の[共有]のボタンをクリック。スプレッドシート名がデフォルトの状態のままなら[名前をつけてください]と言われるので設定します。

(1)のメールアドレスをコピペして[送信]

これで準備は終わりです。


## Nodejs

いよいよNodeでコードを書いていきます。  
ここではcoffee-scriptで書いています。  

npmにいい感じのラッパーがあるのでこれを使います。

> [Google Spreadsheets Data API for Node\.js](https://github.com/theoephraim/node-google-spreadsheet)


コールバック関数を処理するのに便利な[async](http://caolan.github.io/async/)も使います。


```shell-session
npm install -S google-spreadsheet async
```

node-google-spreadsheetのREADMEを見れば使い方はわかると思いますが、簡単に紹介します。

今回、node-google-spreadsheetで使うのは主に３つです。

###`GoogleSpreadsheet.useServiceAccountAuth(account_info, callback)`

このメソッドは認証部分を担当します。といっても先程の認証JSONファイルを渡すだけです。

###`GoogleSpreadsheet.addWorksheet(options, callback)`
新しいワークシートを追加します。
オプションでワークシートのタイトルや行数、列数を指定できます。

> options (optional)
title - title for the new sheet, must be unique in the doc (default = 'Worksheet {timestamp}')
rowCount - number of rows (default = 50)
colCount - number of columns (default = 20)
headers - array of string keys to put in the first row

ポイントはheadersの部分です。  
例えば
```
headers: ['name','age','phone']
```
という感じで設定すると、ワークシートの１行目にこの項目が並びます。  
そして次項のaddRow関数などを使う時にheadersで設定した項目がそのままプロパティになります。  

コールバックは`(error,sheet)`と引数があり、第二引数のsheetは`SpreadsheetWorksheet`クラスになります。

###`SpreadsheetWorksheet.addRow(new_row, callback)`
ワークシートに新しい行を追加します。  
先程のaddWorksheet関数で設定したheadersがプロパティとして使えます。

```
        rowData =
          name: item[0]
          age: item[1]
          phone: item[2]
        sheet.addRow(rowData, callback)
```

## example

「CoffeeScriptとかマジありえねぇ」という方は[こちら](http://coffeescript.org/#try:settings%20%3D%0A%20%20%23%20%E8%A7%A3%E8%AA%AC%E3%81%AE%E9%83%BD%E5%90%88%E4%B8%8A%E5%88%A5%E3%81%AB%E3%81%97%E3%81%A6%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8C%E3%80%81%E3%82%82%E3%81%A1%E3%82%8D%E3%82%93%E3%82%B3%E3%83%BC%E3%83%89%E5%86%85%E3%81%AB%E3%83%99%E3%82%BF%E6%9B%B8%E3%81%8D%E3%81%A7%E3%82%82%E6%A7%8B%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%0A%20%20spreadsheetID%3A%20'xxxxxx_xxxxxxxxxxxxx__xxx_xxxxxxxxxx'%0A%20%20jsonFilePath%3A%20'..%2F..%2Fgss-test-xxxxxxxxxx.json'%0A%0Aitems%20%3D%20%5B%0A%20%20%5B'Alex'%2C17%2C'1234-5678'%5D%0A%20%20%5B'Billy'%2C33%2C'1357-2468'%5D%0A%20%20%5B'Charlie'%2C28%2C'3333-3333'%5D%0A%20%20%5B'Daniel'%2C15%2C'5555-5555'%5D%0A%20%20%5B'Edward'%2C63%2C'9999-9999'%5D%0A%5D%0AGoogleSpreadsheet%20%3D%20require('google-spreadsheet')%0Aasync%20%3D%20require('async')%0Adoc%20%3D%20new%20GoogleSpreadsheet(settings.spreadsheetID)%0Acreds%20%3D%20require(settings.jsonFilePath)%0A%0Adoc.useServiceAccountAuth%20creds%2C%20(err)-%3E%0A%20%20throw%20err%20if%20err%0A%20%20opt%20%3D%0A%20%20%20%20title%3A%20'sample%20sheet'%0A%20%20%20%20headers%3A%20%5B'name'%2C'age'%2C'phone'%5D%0A%20%20doc.addWorksheet%20opt%2C%20(err%2C%20sheet)%20-%3E%0A%20%20%20%20throw%20err%20if%20err%0A%20%20%20%20async.eachSeries%20items%2C%20(item%2C%20next)%20-%3E%0A%20%20%20%20%20%20console.log%20item%0A%20%20%20%20%20%20rowData%20%3D%0A%20%20%20%20%20%20%20%20name%3A%20item%5B0%5D%0A%20%20%20%20%20%20%20%20age%3A%20item%5B1%5D%0A%20%20%20%20%20%20%20%20phone%3A%20item%5B2%5D%0A%20%20%20%20%20%20sheet.addRow(rowData%2C%20next)%0A%20%20%20%20%2C(err)-%3E%0A%20%20%20%20%20%20console.log%20'complete')

```coffee
settings =
  # 解説の都合上別にしてありますが、もちろんコード内にベタ書きでも構いません。
  spreadsheetID: 'xxxxxx_xxxxxxxxxxxxx__xxx_xxxxxxxxxx'
  jsonFilePath: '../../gss-test-xxxxxxxxxx.json'

items = [
  ['Alex',17,'1234-5678']
  ['Billy',33,'1357-2468']
  ['Charlie',28,'3333-3333']
  ['Daniel',15,'5555-5555']
  ['Edward',63,'9999-9999']
]
GoogleSpreadsheet = require('google-spreadsheet')
async = require('async')
doc = new GoogleSpreadsheet(settings.spreadsheetID)
creds = require(settings.jsonFilePath)

doc.useServiceAccountAuth creds, (err)->
  throw err if err
  opt =
    title: 'sample sheet'
    headers: ['name','age','phone']
  doc.addWorksheet opt, (err, sheet) ->
    throw err if err
    async.eachSeries items, (item, next) ->
      console.log item
      rowData =
        name: item[0]
        age: item[1]
        phone: item[2]
      sheet.addRow(rowData, next)
    ,(err)->
      console.log 'complete'

```

このコードを走らせるとSpreadsheetに新規シートが作成されて、冒頭の画像のように書き込むことができました。