首页 > 解决方案 > 创建基本过滤器

问题描述

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

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

谢谢你的帮助!

标签: pythongoogle-sheetsgoogle-sheets-apigspreadpygsheets

解决方案


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

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

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

要查询现有的基本过滤器数据,请使用spreadsheets#get和适当的字段参数以将响应限制为仅需要的信息: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数据框的大小确定适合过滤器的新范围索引。

您可以考虑尝试过滤视图,看看它们是否对您的情况有用。

资源:


推荐阅读