如何使用 Google Sheets API V4 导入 CSV 文件
Posted
技术标签:
【中文标题】如何使用 Google Sheets API V4 导入 CSV 文件【英文标题】:How to import a CSV file using Google Sheets API V4 【发布时间】:2017-07-10 19:16:28 【问题描述】:背景
我正在开发一个 Python 2.7
脚本,该脚本分析来自 SQL 表的数据,最后生成一个 CSV 文件。
文件生成后,我将登录我的 google sheet 帐户并使用导入选项将我的 CSV 文件导入到 google 电子表格中
体力劳动有点愚蠢,我希望将这种能力添加到我的脚本中。
Google 表格 API V4
所以,我按照本指南Python Quickstart 完成了所有步骤。
然后我关注Google Sheets API reference 并查看Method: spreadsheets.create。如果我理解正确,它不提供从文件导入的选项。
似乎没有用于导入功能的 API。
问题
?他们是我缺少的示例/参考吗?
【问题讨论】:
【参考方案1】:您有两个用于导入 g CSV 文件的选项。您可以使用 Drive API 从 CSV 创建电子表格,也可以使用表格 API 来 create 一个空电子表格,然后使用 spreadsheets.batchUpdate 和 PasteDataRequest 添加 CSV 数据。
【讨论】:
希望了解更多有关如何使用 PasteDataRequest 进行批处理更新的信息!文档稀缺:/ 令人沮丧的是,这些信息 - “使用 PasteDataRequest” - 没有包含在工作表 API 的文档中。 Codelabs 有一个完整的示例展示了如何使用粘贴请求,这与其他响应类似,但是是一个完整的云功能示例:codelabs.developers.google.com/codelabs/cloud-function2sheet/#8【参考方案2】:我花了几个小时试图使其他任何答案都起作用。库不能很好地解释身份验证,也不能使用谷歌提供的处理凭据的方式。 另一方面,Sam 的回答没有详细说明使用 API 的细节,这有时可能会让人感到困惑。 因此,这是将 CSV 上传到 gSheets 的完整方法。它使用了 Sam 和 CapoChino 的答案以及我自己的一些研究。
-
验证/设置。一般参考docs
蓝色大按钮无需额外步骤即可获得
credentials.json
quickstart.py
可以很容易地适应 authenticate.py
范围应包含https://www.googleapis.com/auth/spreadsheets
希望现在您已经存储了您的凭据,所以让我们转到实际代码
-
开箱即用的配方:
import pickle
from googleapiclient.discovery import build
SPREADSHEET_ID = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms' # Get this one from the link in browser
worksheet_name = 'Sheet2'
path_to_csv = 'New Folder/much_data.csv'
path_to_credentials = 'Credentials/token.pickle'
# convenience routines
def find_sheet_id_by_name(sheet_name):
# ugly, but works
sheets_with_properties = API \
.spreadsheets() \
.get(spreadsheetId=SPREADSHEET_ID, fields='sheets.properties') \
.execute() \
.get('sheets')
for sheet in sheets_with_properties:
if 'title' in sheet['properties'].keys():
if sheet['properties']['title'] == sheet_name:
return sheet['properties']['sheetId']
def push_csv_to_gsheet(csv_path, sheet_id):
with open(csv_path, 'r') as csv_file:
csvContents = csv_file.read()
body =
'requests': [
'pasteData':
"coordinate":
"sheetId": sheet_id,
"rowIndex": "0", # adapt this if you need different positioning
"columnIndex": "0", # adapt this if you need different positioning
,
"data": csvContents,
"type": 'PASTE_NORMAL',
"delimiter": ',',
]
request = API.spreadsheets().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body)
response = request.execute()
return response
# upload
with open(path_to_credentials, 'rb') as token:
credentials = pickle.load(token)
API = build('sheets', 'v4', credentials=credentials)
push_csv_to_gsheet(
csv_path=path_to_csv,
sheet_id=find_sheet_id_by_name(worksheet_name)
)
直接使用batchUpdate
的好处是它可以在一秒钟内上传数千行。在低级别 gspread
做同样的事情并且应该是高性能的。还有gspread-pandas。
附言代码用 python 3.5
测试,但这个线程似乎最适合提交它。
【讨论】:
感谢您提供的出色示例。遗憾的是,您的代码覆盖了工作表上所有现有的.csv
数据。有没有办法只添加新项目并跳过重复项?
@BenjaminK 这意味着您正在执行合并。我怀疑,您需要一些更复杂的逻辑而不是跳过重复项,因为覆盖旧条目的重复项不会影响您的数据。我建议,如果您需要一些更复杂的逻辑,请不要使用 gSheet API 作为数据库引擎。取而代之的是:提取数据,在本地处理,然后再次上传整个内容。
不过,为了解决您的问题。 This 会有所帮助。打算使用上面示例中的pasteData
,您必须使用validate
、update
和append
的组合。
谢谢!我的问题是 "rowIndex"
和 "columnIndex"
必须作为整数发送 within 字符串。谢谢!!【参考方案3】:
山姆柏林答案的另一种选择。如果您使用的是 Python,则可以通过 gspread 使用 Drive API 来导入 CSV 文件。这是一个例子:
import gspread
# Check how to get `credentials`:
# https://github.com/burnash/gspread
gc = gspread.authorize(credentials)
# Read CSV file contents
content = open('file_to_import.csv', 'r').read()
gc.import_csv('<SPREADSHEET_ID>', content)
相关问题:Upload CSV to Google Sheets using gspread
【讨论】:
注意此方法删除所有其他工作表,然后完全替换第一个工作表的内容。 @BenjaminK 没错。它实际上使用 Drive API 将 CSV 文件直接上传到 Google Drive。不涉及本地处理。 @BenjaminK 我没有意识到您已经从import_csv
docs 中的注释中逐字复制了文本:)
是的,因为我自己也在寻找解决方案,但还没有找到一种简单的方法来更新数据并忽略重复项 :)
我发现的一种解决方法是,如果可以将数据加载到 Pandas 数据框中,而不是直接使用 CSV,gspread 允许您 write the dataframe to a worksheet 并且您可以创建多个这样的工作表。【参考方案4】:
我喜欢 Burnash 的 gspread 库,但他的答案中的 import_csv
功能有限。它总是从第一个工作表(选项卡)的A1
开始粘贴并删除所有其他选项卡。
我需要从特定选项卡和单元格开始粘贴,因此我接受了 Sam Berlin 的建议,使用 PasteDataRequest。这是我的功能:
def pasteCsv(csvFile, sheet, cell):
'''
csvFile - path to csv file to upload
sheet - a gspread.Spreadsheet object
cell - string giving starting cell, optionally including sheet/tab name
ex: 'A1', 'MySheet!C3', etc.
'''
if '!' in cell:
(tabName, cell) = cell.split('!')
wks = sheet.worksheet(tabName)
else:
wks = sheet.sheet1
(firstRow, firstColumn) = gspread.utils.a1_to_rowcol(cell)
with open(csvFile, 'r') as f:
csvContents = f.read()
body =
'requests': [
'pasteData':
"coordinate":
"sheetId": wks.id,
"rowIndex": firstRow-1,
"columnIndex": firstColumn-1,
,
"data": csvContents,
"type": 'PASTE_NORMAL',
"delimiter": ',',
]
return sheet.batch_update(body)
请注意,我使用原始 pasteData 请求而不是更高级别的 update_cells
方法来利用 Google 对包含引号字符串(可能包含非分隔符逗号)的输入数据的自动(正确)处理。
【讨论】:
太棒了,正是我想要的。奇迹般有效!非常感谢@CapoChino。 @CapoChino 你有兴趣将此方法贡献给 gspread 吗? @CapoChino 你在 GitHub 上有一个帐户,所以我可以信任你的工作吗? 是的,@Burnash,它是CapoChino。谢谢。【参考方案5】:作为 Sam Berlin 答案的替代方案,您可以将 CSV 转换为列表列表并将其设置为您的 POST 有效负载。
这样的函数看起来像这样:
def preprocess(table):
table.to_csv('pivoted.csv') # I use Pandas but use whatever you'd like
_file = open('pivoted.csv')
contents = _file.read()
array = contents.split('\n')
master_array = []
for row in array:
master_array.append(row.split(','))
return master_array
那个主数组被扔到下面:
body =
'values': newValues
result2 = service.spreadsheets().values().update(spreadsheetId=spreadsheetId, range=rangeName + str(len(values) + start + 1), valueInputOption="USER_ENTERED", body=body).execute()
它对我来说很好用。
【讨论】:
以上是关于如何使用 Google Sheets API V4 导入 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章
Google Sheets API v4 - 如何获得最后一行的价值?
使用Sheets API v4获取与Google帐户关联的所有电子表格列表
使用 Sheets API v4 (Java) 获取 Google 表格上次编辑日期