[Python]gspreadでCSVをスプレッドシートへインポート

#目的
作成したCSVファイルをスプレッドシートへ自動でインポートしたい。

Pythonのgspreadを使用して実際にやってみた。

#前提条件
・Googleアカウント作成
・プロジェクト作成
・API有効化
・サービスアカウントキーの取得

こちらが全て完了している事が前提です。
筆者は下記リンクを参考にしました。

[pythonでGoogle Driveの任意のフォルダにスプレッドシートを作成・編集する](https://qiita.com/koshitake2m2/items/9843ca8e38f425af4896)
[PythonでGoogleスプレッドシートを編集](https://qiita.com/akabei/items/0eac37cb852ad476c6b9)

#CSVをインポート

```:インポートテスト用CSVファイル
a,b,c
1,2,3
```

#####コード

```import_test.py
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
import csv

# GoogleAPI
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
# 認証用キー
json_keyfile_path = '認証用キーのファイルパス'
# サービスアカウントキーを読み込む
credentials = ServiceAccountCredentials.from_json_keyfile_name(json_keyfile_path, scope)
# pydrive用の認証
gauth = GoogleAuth()
gauth.credentials = credentials
drive = GoogleDrive(gauth)
# インポートするCSVファイル
csv_path = 'CSVファイルパス'
# スプレッドシート格納フォルダ（https://drive.google.com/drive/folders/<フォルダのID>）
folder_id = 'フォルダID'
# スプレッドシート新規作成
f = drive.CreateFile({
    'title': 'test',
    'mimeType': 'application/vnd.google-apps.spreadsheet',
    "parents": [{"id": folder_id}]})
f.Upload()
# gspread用の認証
gc = gspread.authorize(credentials)
# 作成したスプレッドシートのIDを取得
sheet_id = f['id']
# スプレッドシートを開く
workbook = gc.open_by_key(sheet_id)
# 作成したスプレッドシートにCSVをインポート
workbook.values_update(
    'Sheet1',
    params={'valueInputOption': 'USER_ENTERED'},
    body={'values': list(csv.reader(open(csv_path, encoding='utf_8_sig')))}
)
```

#####実行結果
![test_spreadsheets.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658292/396c2377-fe4e-40fd-93df-b6bdfe926175.png)

無事にインポート出来ました。

ドライブ用の認証処理
↓
作成したいフォルダの指定
↓
空のスプレッドシート作成
↓
スプレッドシート用の認証処理
↓
CSVインポート

という流れです。

#既存のブックにシートを追加→CSVインポート

```:インポートテスト用CSVファイル
d,e,f
4,5,6
```

#####コード

```import_test.py
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
import csv

# GoogleAPI
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
# 認証用キー
json_keyfile_path = '認証用キーのファイルパス'
# サービスアカウントキーを読み込む
credentials = ServiceAccountCredentials.from_json_keyfile_name(json_keyfile_path, scope)
# pydrive用の認証
gauth = GoogleAuth()
gauth.credentials = credentials
drive = GoogleDrive(gauth)
# インポートするCSVファイル
csv_path = 'CSVファイルパス'
# スプレッドシート格納フォルダ（https://drive.google.com/drive/folders/<フォルダのID>）
folder_id = 'フォルダID'
# スプレッドシート格納フォルダ内のファイル一覧取得
file_list = drive.ListFile({'q': "'%s' in parents and trashed=false" % folder_id}).GetList()
# gspread用の認証
gc = gspread.authorize(credentials)
# スプレッドシートIDを取得
book_name = 'test'
sheet_id = [file['id'] for file in file_list if file['title'] == book_name]
sheet_id = sheet_id[0]
# スプレッドシートを開く
workbook = gc.open_by_key(sheet_id)
# ワークシート追加
sheet_name = 'Sheet2'
workbook.add_worksheet(title=sheet_name, rows=1000, cols=26)
# スプレッドシートにCSVをインポート
workbook.values_update(
    sheet_name,
    params={'valueInputOption': 'USER_ENTERED'},
    body={'values': list(csv.reader(open(csv_path, encoding='utf_8_sig')))}
)
```

#####実行結果

![test_spreadsheets2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658292/cccec06d-38f5-1310-0993-ff9cd147381e.png)

新たなシートを作成してCSVをインポートする手順はこんな感じになります。

フォルダ内に存在するファイル一覧を作成
↓
ファイル一覧からCSVインポートしたいブックを検索してシートIDを取得
↓
CSVインポート

という流れ。

#ブックが既に存在する場合は新規ワークシートを作成、存在しない場合は新規ブックを作成してCSVをインポート

```import_test.py
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
import csv
import sys

# GoogleAPI
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
# 認証用キー
json_keyfile_path = '認証用キーのファイルパス'
# サービスアカウントキーを読み込む
credentials = ServiceAccountCredentials.from_json_keyfile_name(json_keyfile_path, scope)
# pydrive用の認証
gauth = GoogleAuth()
gauth.credentials = credentials
drive = GoogleDrive(gauth)
# インポートするCSVファイル
csv_path = 'CSVファイルパス'
# スプレッドシート格納フォルダ（https://drive.google.com/drive/folders/<フォルダのID>）
folder_id = 'フォルダID'
# スプレッドシート格納フォルダ内のファイル一覧取得
file_list = drive.ListFile({'q': "'%s' in parents and trashed=false" % folder_id}).GetList()
# ファイル一覧からファイル名のみを抽出
title_list = [file['title'] for file in file_list]
# 任意のブック名
book_name = '任意のブック名'
# ブックの存在判定
if book_name not in title_list:
    # ブック新規作成
    f = drive.CreateFile({
        'title': book_name,
        'mimeType': 'application/vnd.google-apps.spreadsheet',
        "parents": [{"id": folder_id}]})
    f.Upload()
    # gspread用に認証
    gc = gspread.authorize(credentials)
    # スプレッドシートIDを取得
    sheet_id = f['id']
    # ブックを開く
    workbook = gc.open_by_key(sheet_id)
    # ワークシート名を任意のシート名に変更
    worksheet = workbook.worksheet('Sheet1')
    sheet_name = '任意のワークシート名'
    worksheet.update_title(sheet_name)
else:
    # gspread用の認証
    gc = gspread.authorize(credentials)
    # スプレッドシートIDを取得
    sheet_id = [file['id'] for file in file_list if file['title'] == book_name]
    sheet_id = sheet_id[0]
    # ブックを開く
    workbook = gc.open_by_key(sheet_id)
    # 存在するワークシートの情報を全て取得
    worksheets = workbook.worksheets()
    # ワークシート名のみをリストへ格納
    worksheets_title_list = [sheet.title for sheet in worksheets]
    # 任意のワークシート名
    sheet_name = '任意のワークシート名'
    # 同一ワークシート名の存在判定
    if sheet_name == worksheets_title_list:
        # 同一のワークシート名が既に存在する場合はシートを作成せずに処理終了
        sys.exit()
    else:       
        # ワークシート追加
        workbook.add_worksheet(title=sheet_name, rows=1000, cols=26)
# スプレッドシートにCSVをインポート
workbook.values_update(
    sheet_name,
    params={'valueInputOption': 'USER_ENTERED'},
    body={'values': list(csv.reader(open(csv_path, encoding='utf_8_sig')))}
)
```

先程紹介した新規ブック作成パターンと新規ワークシート追加パターンを組み合わせた例。

ブックの新規作成が必要な場合と既存ブックへ書き込む場合のどちらにも対応出来る。

日次処理等で定期的にデータを追加する場合に便利。

同一ワークシート名の存在判定も追加する事によってエラーを回避。

#最後に

お手軽にCSVをインポート出来てめちゃ便利。