我正在使用gspread用来自.CSV文件的数据刷新Google表格中的工作表。在网上浏览的过程中,我一直很难找到我认为应该是我的问题的明确答案。
我的项目目录中有.CSV文件。到目前为止,这是我的代码:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import csv
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
sheet = client.open_by_key('Spreadsheet Key')
worksheet = sheet.worksheet('Worksheet Name')
worksheet.clear()
目前,我不确定应该使用哪种方法来批量上传.CSV中的所有数据。我已经读过gspread中的.update_cells()只会使用一次对Google Sheets API的调用,并且是最快的方法,所以我的问题是这样的:
使用.update_cells(),如何遍历.CSV以能够发布到表格中?
关于.CSV文件的一些信息是它有9列,但是我需要代码来处理行数的任何更改。任何帮助将不胜感激!
答案 0 :(得分:1)
首先,如果您对第一张电子表格中进入A1
的数据没问题,可以使用gspread.Client.import_csv()
作为一个非常简单的选项。
否则,请继续阅读。
要使用update_cells()
,请向其传递Cell()
对象的列表。
您可以从worksheet.range()
,worksheet.cell()
,worksheet.find()
或worksheet.findall()
获得gspread对象。
(访问这些功能时,每个功能都会进行网络通话,因此请尽量减少通话次数。)
然后,对于每个单元格对象,将cell.value
字段更改为csv数据。
for data,cell in zip(csv_data,worksheet.range()): # Whatever range you need.
cell.value=data # Sets the cell in *local* sheet to the specified data. (String)
因此,这将更改该单元格的所有 local 引用,以显示您的csv数据。 (值得指出的是,您的数据在上传后会转换为字符串。
如果您想将单元格数据读取为数字,我记得cell.numeric_value
出现了,尽管在docs中看不到引用。
然后,您将所有现在修改的单元格项目传递给update_cells()
,然后Google电子表格将反映您的更改。
您可以在此处查看其他参考资料:https://github.com/burnash/gspread#updating-cells
也,过去不得不解决一个非常相似的挑战(json,不是csv,但足够接近),这是一个很好的辅助函数,它将占用很多列,并且获取单元对象然后发送update_cells()
请求的繁忙工作。
可以在GitHub.com here上找到该代码。
def update_columns(sheet, row, col, columns, execute = True):
"""Update the specified columns. Row and col are the starting most top left
cell. Each column should be a list of values. Each list should be the
same length.
"""
# Step one, no columns is an error.
if not columns:
raise ValueError("Please specify at least one column to update.")
# Otherwise, get that column length.
r_len = len(columns[0])
# First check that all columns are the same length.
for column in columns[1:]:
if len(column) != r_len:
# Variable length.
raise ValueError("Columns are of varying length.")
# Start making lists.
update_cells = []
# Expand the sheet size if needed.
if col + len(columns) > sheet.col_count:
sheet.add_cols(col + len(columns) - sheet.col_count)
if row + r_len > sheet.row_count:
sheet.add_rows(row + r_len - sheet.row_count)
# Get the range of cells to be updated.
print("Range %s %s %s %s" % (row, col, row + r_len - 1 , col + len(columns) - 1))
update_range = sheet.range (row, col, row + r_len - 1 , col + len(columns) - 1)
for c, column in enumerate(columns):
# Get the range on the sheet for the column.
## column_range = sheet.range(row, col + c, row + len(column), col + c)
column_range = (update_range[i] for i in range(c, len(update_range), len(columns)))
for cell, value in zip(column_range, column):
# Boolean rational.
if isinstance(value, bool):
if str(value).upper() != cell.value:
# So its NOT the same.
cell.value = value
update_cells.append(cell)
# Use numerical_value for numbers.
elif isinstance(value, (int, float)):
# For whatever reason, it looks like gsheets
# truncates to the 10th place.
# It seems that 11th & 12th place is almost always correct but
# can actually differ slightly???
if cell.numeric_value is None or \
truncate(value, 10) != truncate(cell.numeric_value, 10):
cell.value = value
update_cells.append(cell)
# And for everything else, string handling.
elif isinstance(value, basestring):
if value != cell.value:
cell.value = value
update_cells.append(cell)
# Handle None
elif value is None:
if '' != cell.value:
# Set to ''
cell.value = ''
update_cells.append(cell)
else:
# Other type, error.
raise ValueError("Cell value %r must be of type string, number, "
"or boolean. Not %s." % (value, type(value)))
# Now take the list of cells and call an update.
if execute:
print("Updating %d cells." % len(update_cells))
if update_cells:
sheet.update_cells(update_cells)
return len(update_cells)
else:
return update_cells