获取 combined/merged 个单元格值
Get combined/merged cells value
我正在编写一个新的 python 脚本,需要从 google 工作表中提取数据,但是有很多单元格是 merged/combined,而且只有左上角的单元格从此合并中具有价值。在所有合并的单元格上都具有该值很重要。
我该怎么做?
Python 3.8.5 + gspread 3.6.0
注意:每条评论“trying to get...”,其正下方的代码应return与前面代码相同的值。
电子表格测试: 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 处理合并的单元格。
我相信你的目标如下。
- 您想使用 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
. 中检索它们
参考:
我正在编写一个新的 python 脚本,需要从 google 工作表中提取数据,但是有很多单元格是 merged/combined,而且只有左上角的单元格从此合并中具有价值。在所有合并的单元格上都具有该值很重要。
我该怎么做?
Python 3.8.5 + gspread 3.6.0
注意:每条评论“trying to get...”,其正下方的代码应return与前面代码相同的值。
电子表格测试: 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 处理合并的单元格。
我相信你的目标如下。
- 您想使用 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
. 中检索它们