通过 Gspread 将 .csv 上传到 Google 表格

Uploading .csv to Google Sheets via Gspread

我正在使用 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 以便能够 post 到表格?

关于我的 .CSV 文件的一些信息是它有 9 列,但我需要代码来处理行数的任何变化。非常感谢任何帮助!

首先,如果您对第一个传播A1 中的数据没问题sheet,您可以使用gspread.Client.import_csv() 作为一个非常简单的选项。

否则,继续阅读。

要使用 update_cells(), pass it a list of Cell() 个对象。

您从 worksheet.range(), worksheet.cell() , worksheet.find(), or 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 传播 sheet 将反映您的更改。

您可以在此处查看其他参考 material:https://github.com/burnash/gspread#updating-cells

Also,过去不得不解决一个非常相似的挑战(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