GoでGoogleスプレッドシートを操作する
SheetsAPI を利用してGoからスプレッドシートの操作(参照・更新)を行う
CLIで動かすためサービスアカウントを利用して操作を行う
実行環境はMac、Goの利用バージョンは1.13
プロジェクトの作成
Google Cloud Platform からプロジェクトを作成しておく
(すでに作成済みのプロジェクトを利用する場合はこの手順は不要)
今回はテスト用に「MyTestProject」という名前で作成しておいた
SheetsAPIの有効化
作成したプロジェクトからSheetsAPIを利用できるように有効化を行う
「+APIとサービスを有効化」をクリック
検索フォームに「sheets」などと入力すればGoogle Sheets APIが出てくるので選択する
「有効にする」を選択
サービスアカウントの作成
サイドメニューの「認証情報」を選択
「認証情報を作成」から「サービスアカウントキー」を選択
サービスアカウントは「新しいサービスアカウント」を選択し、サービスアカウント名を入力する
今回はテスト用に「sheets-test-account」とした
作成後、秘密鍵を含む認証情報のJSONファイルがDLされるので保管しておく(ロジック部分で使うよ)
スプレッドシートの設定
操作を行う対象のスプレッドシートを用意する
作成後、サービスアカウントからの操作を受け付けるための設定を行う
まず、サービスアカウントのメールアドレスをコピっておく
「認証情報」から「サービスアカウントの管理」をクリック
作成したサービスアカウントのメールアドレスをコピー
対象のスプレッドシートを開き、右上の「共有」からコピったメールアドレスを入力し、「送信」を選択
これでSheetsAPI経由で操作する事前準備が整ったので、Goでの操作プログラムを書いていく(長い)
Goでのスプレッドシート操作
今回テスト用に使うスプレッドシートは以下のようなやつ B列に更新日時を入れていて、今回のロジックではここの日時の更新を行う
作ったロジックは↓
取得した情報の出力と、B列の時刻を現在時刻に更新する
実行方法
実行する際にはサービスアカウントを作成した際にDLした認証情報のJSONファイルをsecret.json
という名前でmain.go
と同じディレクトリに置いておく
(gitなどにpushしないこと)
実行時にスプレッドシートIDを環境変数として渡すようにしていて、スプレッドシートのURLの以下の部分を指定する
https://docs.google.com/spreadsheets/d/<スプレッドシートID>/
実行
$ SHEET_ID=<スプレッドシートID> go run main.go
ロジック詳細
参照には
srv.Spreadsheets.Values.Get(spreadsheetID, readRange).Do()
更新には
srv.Spreadsheets.Values.Update(spreadsheetID, updateRange, &vr).ValueInputOption("RAW").Do()
を利用している
それぞれ第2引数に指定するreadRange
、updateRange
は文字列で、
GoDoc や、公式のサンプル が参考になる
!
の前にはシート名を指定しているが、日本版?のスプレッドシートで作成すると「シート1」のようになるため、
指定する際は日本語でシート1!A:B
のようにしてあげる必要がある(今回は事前に「Sheet1」に変えておいた)
参照時の戻り値および、更新の際に指定する値(&vr
)は、ValueRange
型で、
ValueRange.Values
は[][]interface{}
となっている
A列も一緒に合わせて更新する場合は以下のようになる(A列の後ろに"-test"を追加)
var vr sheets.ValueRange now := time.Now().Format("2006/01/02 15:04:05") for i := 0; i < len(resp.Values); i++ { - vr.Values = append(vr.Values, []interface{}{now}) + vr.Values = append(vr.Values, []interface{}{fmt.Sprintf("%s-test", resp.Values[i][0]), now}) } - updateRange := "Sheet1!B1:B" + updateRange := "Sheet1!A1:B" if _, err = srv.Spreadsheets.Values.Update(spreadsheetID, updateRange, &vr).ValueInputOption("RAW").Do(); err != nil { log.Fatal(err) }
まとめ
事前準備がちょっとめんどくさいけど、ロジックは割とシンプル