1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

spreadsheetのURLだけから内容を取得してみた。

Posted at

今回はシート名が不明な状態で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からは色々な情報が取得できるので困ったら見てみると助かるかもしれません。

よかったらいいねお願いします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?