Skip to content

Commit

Permalink
Merge pull request #1215 from burnash/700-fill-merged-cells
Browse files Browse the repository at this point in the history
700-fill-merged-cells
  • Loading branch information
alifeee authored Jun 14, 2023
2 parents 2bef750 + 787cd40 commit 20a2209
Show file tree
Hide file tree
Showing 5 changed files with 1,128 additions and 2 deletions.
35 changes: 35 additions & 0 deletions gspread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,41 @@ def wrapper(*args, **kwargs):
return decorate


def combined_merge_values(worksheet_metadata, values):
"""For each merged region, replace all values with the value of the top-left cell of the region.
e.g., replaces
[
[1, None, None],
[None, None, None],
]
with
[
[1, 1, None],
[1, 1, None],
]
if the top-left four cells are merged.
:param worksheet_metadata: The metadata returned by the Google API for the worksheet. Should have a "merges" key.
:param values: The values returned by the Google API for the worksheet. 2D array.
"""
merges = worksheet_metadata.get("merges", [])
# each merge has "startRowIndex", "endRowIndex", "startColumnIndex", "endColumnIndex
new_values = [[v for v in row] for row in values]

for merge in merges:
start_row, end_row = merge["startRowIndex"], merge["endRowIndex"]
start_col, end_col = merge["startColumnIndex"], merge["endColumnIndex"]
top_left_value = values[start_row][start_col]
row_indices = range(start_row, end_row)
col_indices = range(start_col, end_col)
for row_index in row_indices:
for col_index in col_indices:
new_values[row_index][col_index] = top_left_value

return new_values


if __name__ == "__main__":
import doctest

Expand Down
24 changes: 22 additions & 2 deletions gspread/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
accepted_kwargs,
cast_to_a1_notation,
cell_list_to_rect,
combined_merge_values,
fill_gaps,
filter_dict_values,
finditem,
Expand Down Expand Up @@ -344,10 +345,11 @@ def range(self, name=""):

@accepted_kwargs(
major_dimension=None,
combine_merged_cells=False,
value_render_option=None,
date_time_render_option=None,
)
def get_values(self, range_name=None, **kwargs):
def get_values(self, range_name=None, combine_merged_cells=False, **kwargs):
"""Returns a list of lists containing all values from specified range.
By default values are returned as strings. See ``value_render_option``
Expand All @@ -362,6 +364,16 @@ def get_values(self, range_name=None, **kwargs):
Defaults to Dimension.rows
:type major_dimension: :namedtuple:`~gspread.utils.Dimension`
:param bool combine_merged_cells: (optional) If True, then all cells that
are part of a merged cell will have the same value as the top-left
cell of the merged cell. Defaults to False.
.. warning::
Setting this to True will cause an additional API request to be
made to retrieve the values of all merged cells.
:param str value_render_option: (optional) Determines how values should
be rendered in the output. See `ValueRenderOption`_ in
the Sheets API.
Expand Down Expand Up @@ -434,7 +446,15 @@ def get_values(self, range_name=None, **kwargs):
worksheet.get_values('A2:B4', value_render_option=ValueRenderOption.formula)
"""
try:
return fill_gaps(self.get(range_name, **kwargs))
vals = fill_gaps(self.get(range_name, **kwargs))
if combine_merged_cells is True:
spreadsheet_meta = self.spreadsheet.fetch_sheet_metadata()
worksheet_meta = finditem(
lambda x: x["properties"]["title"] == self.title,
spreadsheet_meta["sheets"],
)
return combined_merge_values(worksheet_meta, vals)
return vals
except KeyError:
return []

Expand Down
Loading

0 comments on commit 20a2209

Please sign in to comment.