どん底から這い上がるまでの記録

どん底から這い上がりたいけど這い上がれない人がいろいろ書くブログ(主にプログラミング)

pythonを使ってGoogle Spreadsheetのデータを読み込んだり書き込んだりする。

Google Sheets APIを使ってGoogle Spreadsheetのデータを読み込んだり、データを書き込んだりしてみました。

この記事では、pythonを使ったやり方を紹介していきます。

 

環境

関連リンク

Authorize Requests  |  Sheets API  |  Google Developers

ValueInputOption  |  Sheets API  |  Google Developers

Google Sheet APIの有効化

Google Spreadsheetにデータを書き込んだり、データを読み込んだりするにはGoogle Sheet APIを使います。Google Sheet APIの導入については以前書いた記事で紹介しています。

www.pytry3g.com

Google Sheet APIを使う

以前書いた記事Google Sheets APIを使う用意をします。Google Sheets APIを使う作業ディレクトリの構成は下の通りです。

google_sheets/
    token.json
    credentials.json
  read.py
write.py

read.pywrite.pyについてはこれから説明していきます。

read.pyはデータを読み込むためのプログラム、write.pyはデータを書き込むためのプログラムです。2つのプログラムに共通する部分をこれから書きます。

まずは必要なモジュールをインポート。

from __future__ import print_function
import argparse
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

次にやることは認証です。

以下のdef get_authentication()で認証をします。

# Setup the Sheets API
def get_authentication():
    SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('sheets', 'v4', http=creds.authorize(Http()))
    return service

前回書いたプログラムとほとんど同じですが、ひとつだけ異なるところがあります。

それはSCOPESです。前回はhttps://www.googleapis.com/auth/spreadsheets.readonlyとしていましたが、今回はhttps://www.googleapis.com/auth/spreadsheetsにします。

前回のままだとデータの読み込みしかできませんが、変更することによりデータの読み書きができるようになります。

SCOPES(認証)の注意点

認証のプログラムを実行するとtoken.jsonが生成されます。

ここで気をつけなければいけないことがあります。前回SCOPEShttps://www.googleapis.com/auth/spreadsheets.readonlyにして認証をしていました。token.jsonの中身を見れば分かりますが、scopeshttps://www.googleapis.com/auth/spreadsheets.readonlyになっています。この場合、データの読み込みしかできないようになっています。

データを書き込みたい場合、すでに生成されているtoken.json削除してSCOPESの部分をhttps://www.googleapis.com/auth/spreadsheetsに変更してから再度認証しましょう。

データを読み込む

データを読み込むための関数です。

# Call the Sheets API
def read_data(spreadId, rangeName, service):
    SPREADSHEET_ID = spreadId
    RANGE_NAME = rangeName
    result = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID,
                                                 range=RANGE_NAME).execute()
    print(result)

読み込むシートのIDとセルの範囲をspreadsheets().values().get()に渡すことによりデータの中身を取得しています。

下のmainget_authentication()read_data()と一緒に書いて、実行すると指定したセルの中身を取得できます。

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-s',
        '--spreadId',
        type=str,
        default="{spreadsheetId}"
    )

    parser.add_argument(
        '-r',
        '--rangeName',
        type=str,
        default="A1:A32"
    )

    args = parser.parse_args()
    service = get_authentication()
    read_data(args.spreadId, args.rangeName, service)

{spreadsheetId}についてですが、以前書いた記事にも書きましたがこれはスプレッドシートの識別に使われるIDです。このIDはスプレッドシートのURLの/d//editの間にあります。スプレッドシートを開いてみると以下のようなURLになっているはずです。

https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit#gid=0

この{spreadsheetId}defaultのところに置き換えるか、プログラムを実行するときにオプションで指定するかしてください。

結果

f:id:pytry3g:20180801194724p:plain

上の画像のスプレッドシートのセルA1からA32までの中身を取得した結果です。

{'range': "'シート1'!A1:A32", 'majorDimension': 'ROWS', 'values': [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], ['0']]}

データを書き込む

データを書き込むための関数です。

# Call the Sheets API
def write_data(spreadId, rangeName, values, service):
    SPREADSHEET_ID = spreadId
    RANGE_NAME = rangeName
    body = {
        'values': [[values]],
    }
    service.spreadsheets().values().update(
        spreadsheetId=SPREADSHEET_ID,
        range=RANGE_NAME,
        valueInputOption="USER_ENTERED",
        body=body
    ).execute()

spreadsheets().values().update()でデータを書き込みます。

スプレッドシートのID,セルの範囲、書き込むデータを渡しています。

ソースコード

データを読み込む - read.py

from __future__ import print_function
import argparse
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

# Setup the Sheets API
def get_authentication():
    SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('sheets', 'v4', http=creds.authorize(Http()))
    return service

# Call the Sheets API
def read_data(spreadId, rangeName, service):
    SPREADSHEET_ID = spreadId
    RANGE_NAME = rangeName
    result = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID,
                                                 range=RANGE_NAME).execute()
    print(result)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-s',
        '--spreadId',
        type=str,
        default="{spreadsheetId}"
    )

    parser.add_argument(
        '-r',
        '--rangeName',
        type=str,
        default="A1:A32"
    )

    args = parser.parse_args()
    service = get_authentication()
    read_data(args.spreadId, args.rangeName, service)

データを書き込む - write.py

from __future__ import print_function
import argparse
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

# Setup the Sheets API
def get_authentication():
    SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
    store = file.Storage('token.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
        creds = tools.run_flow(flow, store)
    service = build('sheets', 'v4', http=creds.authorize(Http()))
    return service

# Call the Sheets API
def write_data(spreadId, rangeName, values, service):
    SPREADSHEET_ID = spreadId
    RANGE_NAME = rangeName
    body = {
        'values': [[values]],
    }
    service.spreadsheets().values().update(
        spreadsheetId=SPREADSHEET_ID,
        range=RANGE_NAME,
        valueInputOption="USER_ENTERED",
        body=body
    ).execute()


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-s',
        '--spreadId',
        type=str,
        default="{spreadsheetId}"
    )

    parser.add_argument(
        '-r',
        '--rangeName',
        type=str,
        required=True
    )

    parser.add_argument(
        '-v',
        '--values',
        type=int,
        default=0
    )

    args = parser.parse_args()
    service = get_authentication()
    write_data(args.spreadId, args.rangeName, args.values, service)