Google DriveにCSVをアップロードしてGoogleスプレッドシートとして編集後、ダウンロードする

Table of Content

目的

今回はGoogle DriveniにCSVをアップロードしてGoogleスプレッドシートとして編集してみます。

まず、前提条件として以下のチュートリアルを実行してください。

Google Drive API- Python Quickstart
https://developers.google.com/drive/api/v3/quickstart/python

Google Sheets API- Python Quickstart
https://developers.google.com/sheets/api/quickstart/python

上記のチュートリアルで以下のことが行われると思います。

  • Google APIを使用するためのプロジェクトが作成される
  • 作成したプロジェクトにてGoogle Drive APIが有効になる。
  • 作成したプロジェクトにてGoogle SheetsのAPIが有効になる。
  • 認証用の情報を格納したJSONを取得している
  • Pythonのライブラリで下記をインストールしている。
    • google-api-python-client
    • google-auth-httplib2
    • google-auth-oauthlib

実験

Google DriveにCSVをアップロードする

コード

from __future__ import print_function
import sys
import pickle
import io
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from apiclient.http import MediaFileUpload
from googleapiclient.http import MediaIoBaseDownload

# スコープについては下記を参照してください.
# https://developers.google.com/drive/api/v3/about-auth
# 変更した場合は「token.pickle」を削除する必要があります.
SCOPES = [
    'https://www.googleapis.com/auth/drive'
]

def authenticate(client_secret_json_path):
    """QuickStartで行った認証処理と同じ認証処理を行う
    https://developers.google.com/drive/api/v3/quickstart/python
    """
    creds = None
    # ファイルtoken.pickleはユーザーのアクセストークンと更新トークンを格納し、
    # 認証フローが初めて完了すると自動的に作成されます。
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 有効な資格情報がない場合は、ユーザーにログインさせます。
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # ユーザーにブラウザーで認証URLを開くように指示し、ユーザーのURLを自動的に開こうとします。
            # ローカルWebサーバーを起動して、認証応答をリッスンします。
            # 認証が完了すると、認証サーバーはユーザーのブラウザーをローカルWebサーバーにリダイレクトします。
            # Webサーバーは、応答とシャットダウンから認証コードを取得します。その後、コードはトークンと交換されます
            flow = InstalledAppFlow.from_client_secrets_file(client_secret_json_path, SCOPES)
            creds = flow.run_local_server(port=0)
        # 次回実行のために「google.oauth2.credentials.Credentials」をシリアライズ化して保存します。
        # https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.credentials.html
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return creds

def main(client_secret_json_path):
    """CSVのアップロードを行う"""
    creds = authenticate(client_secret_json_path)
    service_drive = build('drive', 'v3', credentials=creds)

    # CSVをGoogleスプレッドシートで編集できるようにUploadします.
    # https://developers.google.com/drive/api/v3/manage-uploads#python
    file_metadata = {
        'name': 'Test',
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    media = MediaFileUpload('test.csv',
                            mimetype='text/csv',
                            resumable=True)
    file = service_drive.files().create(body=file_metadata,
                                    media_body=media,
                                    fields='id').execute()
    print('File ID: %s' % file.get('id'))

if __name__ == '__main__':
    # 第1引数にQuickStartで作成したcredentials.jsonのパスを指定してください.
    main(sys.argv[1])

結果

コンソール
以下のように作成したファイルIDが出力されます

>python hello1.py client_secret.json
File ID: 1iJAdUMkXraufM3Wu0bsbzZvXZLxQQPNYaDvwd6nj97w

Google Drive
「Test」という名称のSheetsが追加されます。

スプレッドシートを開くと「Test」というシートにCSVの内容が表示されています。

Google DriveにアップロードしたCSVをGoogle Sheets APIで編集する

B列とC列を全て変更するサンプルです。
C列はGOOGLETRANSLATEを使用してB列の内容を日本語から英語に翻訳しています。

コード

from __future__ import print_function
import sys
import pickle
import io
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# スコープについては下記を参照してください.
# https://developers.google.com/drive/api/v3/about-auth
# 変更した場合は「token.pickle」を削除する必要があります.
SCOPES = [
    'https://www.googleapis.com/auth/drive'
]

def authenticate(client_secret_json_path):
    """QuickStartで行った認証処理と同じ認証処理を行う
    https://developers.google.com/drive/api/v3/quickstart/python
    """
    creds = None
    # ファイルtoken.pickleはユーザーのアクセストークンと更新トークンを格納し、
    # 認証フローが初めて完了すると自動的に作成されます。
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 有効な資格情報がない場合は、ユーザーにログインさせます。
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # ユーザーにブラウザーで認証URLを開くように指示し、ユーザーのURLを自動的に開こうとします。
            # ローカルWebサーバーを起動して、認証応答をリッスンします。
            # 認証が完了すると、認証サーバーはユーザーのブラウザーをローカルWebサーバーにリダイレクトします。
            # Webサーバーは、応答とシャットダウンから認証コードを取得します。その後、コードはトークンと交換されます
            flow = InstalledAppFlow.from_client_secrets_file(client_secret_json_path, SCOPES)
            creds = flow.run_local_server(port=0)
        # 次回実行のために「google.oauth2.credentials.Credentials」をシリアライズ化して保存します。
        # https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.credentials.html
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return creds

def main(client_secret_json_path, file_id):
    """Googleスプレッドシートの更新を行う"""
    creds = authenticate(client_secret_json_path)
    service_sheets = build('sheets', 'v4', credentials=creds)
    result = service_sheets.spreadsheets().values().get(
        spreadsheetId=file_id,
        range="Test!A1:A").execute()
    print("行数", len(result.get('values')))

    # 全ての行のB列とC列を書き換える
    values = []
    for i in range(len(result.get('values'))):
        values.append(
            [
                # A列に文字を追加した内容をB列に埋め込む
                'こんにちわ ' + result.get('values')[i][0],
                # B列を日本語から英語に翻訳する数式をC列に埋め込む
                '=GOOGLETRANSLATE(indirect("RC[-1]", false),"ja","en")'
            ]
        )

    body = {
        'values': values
    }
    result = service_sheets.spreadsheets().values().update(
        spreadsheetId=file_id,
        range="Test!B1:C",
        valueInputOption='USER_ENTERED',
        body=body
    ).execute()
    print('{0} cells updated.'.format(result.get('updatedCells')))

if __name__ == '__main__':
    # 第1引数にQuickStartで作成したcredentials.jsonのパスを指定してください.
    # 第2引数に編集対象のGoogleスプレッドシートのFile IDを指定してください。
    # https://docs.google.com/spreadsheets/d/[ここの値を入力]/edit#gid=XXXXX
    main(sys.argv[1], sys.argv[2])

結果

すべての行のB列とC列が変更されていることが確認できます。
また、C列の数式も機能しています。

編集したCSVのダウンロード方法

指定のGoogle Drive中のファイルをローカルPCにダウンロードします。

コード

from __future__ import print_function
import sys
import pickle
import io
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaIoBaseDownload

# スコープについては下記を参照してください.
# https://developers.google.com/drive/api/v3/about-auth
# 変更した場合は「token.pickle」を削除する必要があります.
SCOPES = [
    'https://www.googleapis.com/auth/drive'
]

def authenticate(client_secret_json_path):
    """QuickStartで行った認証処理と同じ認証処理を行う
    https://developers.google.com/drive/api/v3/quickstart/python
    """
    creds = None
    # ファイルtoken.pickleはユーザーのアクセストークンと更新トークンを格納し、
    # 認証フローが初めて完了すると自動的に作成されます。
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 有効な資格情報がない場合は、ユーザーにログインさせます。
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # ユーザーにブラウザーで認証URLを開くように指示し、ユーザーのURLを自動的に開こうとします。
            # ローカルWebサーバーを起動して、認証応答をリッスンします。
            # 認証が完了すると、認証サーバーはユーザーのブラウザーをローカルWebサーバーにリダイレクトします。
            # Webサーバーは、応答とシャットダウンから認証コードを取得します。その後、コードはトークンと交換されます
            flow = InstalledAppFlow.from_client_secrets_file(client_secret_json_path, SCOPES)
            creds = flow.run_local_server(port=0)
        # 次回実行のために「google.oauth2.credentials.Credentials」をシリアライズ化して保存します。
        # https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.credentials.html
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return creds

def main(client_secret_json_path, file_id):
    """Googleスプレッドシートのダウンロードを行う"""
    creds = authenticate(client_secret_json_path)
    service_drive = build('drive', 'v3', credentials=creds)

    # download
    request = service_drive.files().export_media(fileId=file_id, mimeType='text/csv')
    fh = io.BytesIO()
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print ("Download %d%%." % int(status.progress() * 100))
    with open('download.csv', 'wb') as f:
        f.write(fh.getvalue())

if __name__ == '__main__':
    # 第1引数にQuickStartで作成したcredentials.jsonのパスを指定してください.
    # 第2引数に編集対象のGoogleスプレッドシートのFile IDを指定してください。
    # https://docs.google.com/spreadsheets/d/[ここの値を入力]/edit#gid=XXXXX
    main(sys.argv[1], sys.argv[2])

注意

元ファイルの行数によってはダウンロード時に翻訳が完了していない場合があります。
もし翻訳が完了するまで待つ場合は以下のようにします。

https://github.com/mima3/pdf_translate/blob/master/translate_google_sheets.py#L45

「Google DriveにCSVをアップロードしてGoogleスプレッドシートとして編集後、ダウンロードする」への1件の返信

コメントは受け付けていません。