今回はシート名が不明な状態でURLだけからシートを取得する方法を書きます。
まずよくあるシートを取得するサンプルコードを紹介します。
読むとわかりますが、spreadsheetのIDとシート名を使って取得しています。
package main
import (
"context"
"fmt"
"log"
"google.golang.org/api/option"
"google.golang.org/api/sheets/v4"
)
func main() {
spreadsheetID := "1zrqghzR3UJdrS70JLKLgujCnmGFN93vIf1B7XmtblOM"
credential := option.WithCredentialsFile("test.json")
srv, err := sheets.NewService(context.TODO(), credential)
if err != nil {
log.Fatal(err)
}
// シート名と参照範囲をくっつけた文字列を使う(シート名だけでもおk)
readRange := "シート1!A1"
resp, err := srv.Spreadsheets.Values.Get(spreadsheetID, readRange).Do()
if err != nil {
log.Fatalln(err)
}
for _, row := range resp.Values {
fmt.Println(row)
}
}
それでは https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxx/edit#gid=1891750325
のようなURLだけで内容を取得するにはどうすればいいでしょうか。
調べた限りだと、シート名が分からないとシートを取得できないようなのでシート名は探す必要があります。
まずspreadsheetのURLについて解説します。構成は下記になります。
https://docs.google.com/spreadsheets/d/{スプレッドシートID}/edit#gid={シートID}
gid以降の数字のようなものがシートIDで今回の処理に必要になります。
シートIDは最初に作成されたページでは必ず0になるようです。
下記のコードはシートIDからシート名を取得しています。
package main
import (
"context"
"fmt"
"log"
"google.golang.org/api/option"
"google.golang.org/api/sheets/v4"
)
var spreadsheetID = "1zrqghzR3UJdrS70JLKLgujCnmGFN93vIf1B7XmtblOM"
func main() {
credential := option.WithCredentialsFile("test.json")
srv, err := sheets.NewService(context.TODO(), credential)
if err != nil {
log.Fatal(err)
}
resp, err := srv.Spreadsheets.Get(spreadsheetID).Do()
if err != nil {
log.Fatalln(err)
}
for _, v := range resp.Sheets {
fmt.Printf("title: %s, sheet_id(gid): %d\n", v.Properties.Title, v.Properties.SheetId)
}
}
このように出力されます。
title: シート1, sheet_id(gid): 0
title: シート2, sheet_id(gid): 680451458
title: シート3, sheet_id(gid): 1891750325
title: シート4, sheet_id(gid): 317507870
全探索して一致するシートIDからシート名を取得できそうです。
このロジックを使ってURLからシートの内容を取得する処理を一通り書きます。
今までと違って必要な手順ごとに関数で分けてます。
package main
import (
"context"
"fmt"
"log"
"net/url"
"regexp"
"strconv"
"google.golang.org/api/option"
"google.golang.org/api/sheets/v4"
)
func createService(ctx context.Context) (srv *sheets.Service, err error) {
credential := option.WithCredentialsFile("test.json")
srv, err = sheets.NewService(ctx, credential)
if err != nil {
return
}
return
}
//regex使ってみた
func getID(spreadSheetURL string) (spreadsheetID string, sheetID int64, err error) {
u, err := url.Parse(spreadSheetURL)
if err != nil {
return
}
repPath := regexp.MustCompile(`/`)
spreadsheetID = repPath.Split(u.Path, -1)[3]
repFragment := regexp.MustCompile(`gid=`)
tmp := repFragment.Split(u.Fragment, -1)[1]
sheetID, err = strconv.ParseInt(tmp, 10, 64)
if err != nil {
return "", 0, err
}
return
}
// ここ重要
func getSheetName(srv *sheets.Service, spreadsheetID string, sheetID int64) (sheetName string, err error) {
resp, err := srv.Spreadsheets.Get(spreadsheetID).Do()
if err != nil {
return
}
for _, v := range resp.Sheets {
fmt.Printf("title: %s, sheet_id: (gid)%d\n", v.Properties.Title, v.Properties.SheetId)
if sheetID == v.Properties.SheetId {
sheetName = v.Properties.Title
break
}
}
return
}
func getSheetContent(srv *sheets.Service, sheetName string, spreadsheetID string) (content *sheets.ValueRange, err error) {
readRange := fmt.Sprintf("%s%s", sheetName, "!A1")
content, err = srv.Spreadsheets.Values.Get(spreadsheetID, readRange).Do()
if err != nil {
return
}
return
}
func main() {
spreadSheetURL := "https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxx/edit#gid=1891750325"
ctx := context.Background()
srv, err := createService(ctx)
if err != nil {
log.Fatalln(err)
}
spreadsheetID, sheetID, err := getID(spreadSheetURL)
if err != nil {
log.Fatalln(err)
}
sheetName, err := getSheetName(srv, spreadsheetID, sheetID)
if err != nil {
log.Fatalln(err)
}
content, err := getSheetContent(srv, sheetName, spreadsheetID)
if err != nil {s
log.Fatalln(err)
}
fmt.Println(content.Values)
}
シートIDから取得する方法はサンプルコードやブログでは書かれていなかったのでリファレンスを読み込んだところヒントを見つけました。需要ないのかな…
Sheetsからは色々な情報が取得できるので困ったら見てみると助かるかもしれません。
よかったらいいねお願いします。