【问题标题】:Creating a Basic Filter创建基本过滤器
【发布时间】:2018-07-14 21:57:32
【问题描述】:

在 pygsheets 中,是否可以打开和关闭过滤?我能够将数据框放入工作表中,但如果不手动转到工作表本身,我无法弄清楚如何打开过滤器。

我的数据框将改变大小,并且默认过滤器不够智能,无法随数据增长,因此需要我关闭过滤器然后重新打开。

感谢您的帮助!

【问题讨论】:

  • 这是pygsheets 的问题吗?还是gspread 的问题?还是Sheets REST API 的问题?
  • 这是一个 pysheets 问题。我在其他 Google Sheet 相关主题中看到了另一个问题标签,以防 pygsheets 不是可行的解决方案并且需要 REST。如果这些标签令人困惑,我可以删除这些标签。

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


【解决方案1】:

在 Sheets REST API 中,删除和/或恢复过滤器非常简单 - 可以在调用 spreadsheets#batchUpdate 时提供两个 Requests

  1. clearBasicFilter 包括要删除过滤器的工作表 ID,例如
    {clearBasicFilter: {sheetId: "someWorkSheetGridId"}}
  2. setBasicFilter

避免在标准规范中引入错误的一种简单方法是首先查询现有过滤器,然后在以下setBasicFilter 请求中使用它。如果不这样做,则需要重新指定过滤条件(如果恢复活动过滤器)。要简单地恢复 UI 过滤的能力,您不需要提供 criteria 属性。

要查询现有的基本过滤器数据,请使用spreadsheets#get,并使用适当的fields 参数将响应限制为仅需要的信息:fields: "sheets(properties(sheetId,title),basicFilter)"

使用 Google API Python 客户端(并忽略任何响应、错误处理等):

def get_existing_basic_filters(wkbkId: str) -> dict:
    params = {'spreadsheetId': wkbkId,
              'fields': 'sheets(properties(sheetId,title),basicFilter)'}
    response = service.spreadsheets().get(**params).execute()
    # Create a sheetId-indexed dict from the result
    filters = {}
    for sheet in response['sheets']:
        if 'basicFilter' in sheet:
            filters[sheet['properties']['sheetId']] = sheet['basicFilter']
    return filters

def clear_filters(wkbkId: str, known_filters: dict):
    requests = []
    for sheetId, filter in known_filters.items():
        requests.append({'clearBasicFilter': {'sheetId': sheetId}})
    if not requests:
        return
    params = {'spreadsheetId': wkbkId,
              'body': {'requests': requests}}
    service.spreadsheets().batchUpdate(**params).execute()

def apply_filters(wkbkId: str, filters: dict):
    # All requests are validated before any are applied, so bundling the set and clear filter
    # operations in the same request would fail: only 1 basic filter can exist at a time.
    clear_filters(wkbkId, filters)

    requests = []
    for sheetId, filter in filters.items():
        # By removing the starting and ending indices from the 'range' property,
        # we ensure the basicFilter will apply to the entire sheet bounds. If one knows the 
        # desired values for startColumnIndex, startRowIndex, endRowIndex, endColumnIndex,
        # then they can be used to create a range-specific basic filter.
        # The 'range' property is a `GridRange`: 
        filter['range'] = {'sheetId': sheetId}
        requests.append({'setBasicFilter': {'filter': filter}})
    if not requests:
        return
    params = {'spreadsheetId': wkbkId,
              'body': {'requests': requests}}
    service.spreadsheets().batchUpdate(**params).execute()

service = get_authed_sheets_service_somehow()
fileId = "some valid Sheets file id"
my_filters = get_existing_basic_filters(fileId)
pprint(my_filters)
###
# do stuff to `my_filters`
###
apply_filters(fileId, my_filters) 

如果有updateBasicFilter 请求,您可以避免此过程,只需使用数据框的新大小修改现有BasicFilter 的范围,但没有这样的请求。您可以根据数据框的大小确定适合过滤器GridRange 的新范围索引。

您可以考虑尝试Filter Views,看看他们是否提供了对您的情况有用的东西。

资源:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 2018-05-20
    相关资源
    最近更新 更多