【问题标题】:Get combined/merged cells value获取合并/合并的单元格值
【发布时间】:2020-11-18 21:03:21
【问题描述】:

我正在编写一个新的 python 脚本,该脚本需要从谷歌表格中提取数据,但是有许多单元格被合并/组合,并且只有来自此合并的左上角单元格具有值。在所有合并的单元格上都有该值很重要。

我该怎么做?

Python 3.8.5 + gspread 3.6.0

注意:每条评论“试图获取...”,其下方的代码应返回与之前代码相同的值。

电子表格测试: https://docs.google.com/spreadsheets/d/17Dyxufu1y1ouBCPkf5Y7Vt1UW70WroK0Moy_DD7bZKc/edit?usp=sharing

重现问题的代码:

import gspread
from oauth2client.service_account import ServiceAccountCredentials
import os
import pprint

here = os.path.dirname(os.path.abspath(__file__))
secret = os.path.join(here, 'credentials.json')

scope = ['https://spreadsheets.google.com/feeds']
creds = ServiceAccountCredentials.from_json_keyfile_name(secret, scope)

client = gspread.authorize(creds)

sheet = client.open_by_key('17Dyxufu1y1ouBCPkf5Y7Vt1UW70WroK0Moy_DD7bZKc')
ws = sheet.sheet1
pp = pprint.PrettyPrinter()

#getting the FIRST text
result = ws.acell('A1')
pp.pprint('A1: '+result.value)

#trying to get the SAME text on the cell col+1
result = ws.acell('A2')
pp.pprint('A2: '+result.value)

#getting the 'simple_cell'
result = ws.acell('C2')
pp.pprint('C2: '+result.value)

#getting the 'row_merged'
result = ws.acell('D2')
pp.pprint('D2: '+result.value)

#trying to get 'row_merged' on row+1
result = ws.acell('E2')
pp.pprint('E2: '+result.value)

#getting the 'col_merged'
result = ws.acell('D6')
pp.pprint('D6: '+result.value)

#trying to get 'col_merged' on col+1
result = ws.acell('D7')
pp.pprint('D7: '+result.value)

输出是这样的:

('A1: just to confirm, the value "row_merged" has been put to cell D2 originally. Value "col_merged" is in D6 initially. Since it's merged, the expected result should be found on all merged cells')
'A2: '
'C2: simple cell'
'D2: row_merged'
'E2: '
'D6: col_merged'
'D7: '
PS C:\Users\joaov\Desktop>

重点是:A2 必须等于 A1...E2=D2,D7==D6...但是似乎没有办法用 gspread 处理合并的单元格。

【问题讨论】:

  • 你有机会发minimal reproducible example吗?
  • @RandomDavis 确定测试电子表格是:docs.google.com/spreadsheets/d/… 代码是:hastebin.com/umuvecajir.apache 输出:hastebin.com/wuliqihasa.rust 注意:每条评论“试图获得...”,它下面的代码应该返回与前面代码相同的值。
  • 我应该澄清一下,您的示例应该是独立的,即不像您那样托管在外部站点上。输出也是如此,它必须在您的问题本身中。它应该是一些 Python 代码,我们可以粘贴到 IDE 中,运行它,然后查看问题。如果您必须伪造或“模拟”任何传入数据,那很好,只要它向我们展示了同样的问题。我建议使用tour 以更好地了解该网站希望问题的格式。
  • 我很抱歉,@RandomDavis,我没想过用代码等来编辑我的主要问题。我现在就去编辑它,希望你能帮忙我的问题:)
  • 那很好,因为我或其他人可能会在这种情况下提供帮助。

标签: python google-sheets google-sheets-api gspread


【解决方案1】:

我相信你的目标如下。

  • 您想使用 python 的 gspread 从合并单元格中检索值。

例如,在您的示例电子表格中,单元格“A1:L12”被合并。在这种情况下,当使用 Sheets API 从“A1:L12”的合并单元格中检索值时,just to confirm, the value "row_merged" has been put to cell D2 originally. Value "col_merged" is in D6 initially. Since it's merged, the expected result should be found on all merged cells 仅检索到单元格“A1”。因此,为了从“A1:L12”的所有单元格中检索相同的值,需要将这些值放入单元格“A2:L12”中。不幸的是,Sheets API 中似乎没有直接实现这种情况的方法。所以,在这个答案中,我想使用脚本来提出这个建议。

顺便说一句,关于您的脚本中的result = ws.acell('A2'),这个单元格没有合并,它是空的。所以在这种情况下,我认为空值是正确的。我认为您可能想检查单元格“B1”。在这个答案中,也考虑了这一点。

示例脚本:

spreadsheet_id = '###'  # Please set the Spreadsheet ID.
sheet_name = 'Sheet1'  # Please set the sheet name.

client = gspread.authorize(credentials)
access_token = client.auth.token
url = "https://sheets.googleapis.com/v4/spreadsheets/" + \
    spreadsheet_id + "?fields=sheets&ranges=" + sheet_name
res = requests.get(url, headers={"Authorization": "Bearer " + access_token})
obj = res.json()
# print(obj['sheets'][0]['merges'])

sheet = client.open_by_key(spreadsheet_id)
ws = sheet.worksheet(sheet_name)

# 1. All values are retrieved.
values = ws.get_all_values()

# 2. Put the values to the merged cells.
if 'merges' in obj['sheets'][0].keys():
    for e in obj['sheets'][0]['merges']:
        value = values[e['startRowIndex']][e['startColumnIndex']]
        rows = len(values)
        if rows < e['endRowIndex']:
            for i in range(0, e['endRowIndex'] - rows):
                values.append([''])
        for r in range(e['startRowIndex'], e['endRowIndex']):
            cols = len(values[r])
            if cols < e['endColumnIndex']:
                values[r].extend([''] * (e['endColumnIndex'] - cols))
            for c in range(e['startColumnIndex'], e['endColumnIndex']):
                values[r][c] = value

# For A1
print('A1: '+values[0][0])

# For B1
# output: just to confirm, the value "row_merged" has been put to cell D2 originally. Value "col_merged" is in D6 initially. Since it's merged, the expected result should be found on all merged cells
print('B1: '+values[0][1])

# For C2
# output: simple cell
print('C2: '+values[1][2])

# For D2
# output: row_merged
print('D2: '+values[1][3])

# For E2
# output: row_merged
print('E2: '+values[1][4])

# For D6
# output: col_merged
print('D6: '+values[5][3])

# For D7
# output: col_merged
print('D7: '+values[6][3])

注意:

  • 在此示例脚本中,Sheets API 中的“spreadsheets.get”方法与requests 一起使用,使用从gspread 的client = gspread.authorize(credentials) 检索到的访问令牌。
  • 在此示例脚本中,值在列表中进行处理。因此,当您从合并单元格中检索值时,请从列表values 中检索它们。

参考:

【讨论】:

  • 提前感谢您的帮助!但我能问点什么吗?在您的解释中,您的意思是A1:L1 而不是A1:A12,对吧?而且,分析脚本,似乎我需要获取合并范围 URL 对吗?每次都需要获取此网址是不可行的:/
  • 此外,此功能将与您帮助我的其他问题一起实现,通过其 GID 打开工作表
  • @João Casarin 感谢您的回复。我不得不为我糟糕的英语水平道歉。很遗憾,我无法理解您的回复。如果我的回答对您的情况没有用,您能否告诉我它的详细信息?借此,我想确认一下。
  • 别担心英语,完全没问题,我也不会说英语。你说在我的电子表格中有一个在A1:A12 范围内的合并,但它实际上是A1:L1,对吧?并分析您的脚本,我想我需要获取合并的单元格 URL,对吗?就像这样:docs.google.com/spreadsheets/d/… 如果是,这会很困难,因为它不应该是输入,明白了吗?
  • @João Casarin 感谢您的回复。是的。我误解了。我为此道歉。那是“A1:L12”。所以我更新了我的答案。而且,我必须为我糟糕的英语水平道歉。不幸的是,我无法理解And analyzing your script, I think I'll need to get the merged cells URL, will I?。在上面的示例脚本中,URL 包括电子表格 ID 和工作表名称。找到合并的单元格后,将检索值。
猜你喜欢
  • 2011-07-02
  • 2023-03-12
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多