Google Sheets API v4 - 如何获取最后一行的值?

Google Sheets API v4 - How to get the last row with value?

如何在新的 Google 工作表 API v4 中获取最后一行的值?

我用它从 sheet:

中获取范围
mService.spreadsheets().values().get("ID_SHEET", "Sheet1!A2:B50").execute();

如何检测 sheet 中具有值的最后一行?

你不需要。设置一个很大的范围(例如 A2:D5000)以保证您的所有行都位于其中。不知道会不会有什么进一步的影响,可能是内存消耗增加什么的,不过目前还可以。

private List<String> getDataFromApi() throws IOException {
        String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"; 
        String range = "A2:D5000";
        List<String> results = new ArrayList<String>();
        ValueRange response = this.mService.spreadsheets().values()
                .get(spreadsheetId, range)
                .execute();
        List<List<Object>> values = response.getValues();
        if (values != null) {
            results.add("Name, Major");
            for (List row : values) {
                results.add(row.get(0) + ", " + row.get(3));
            }
        }
        return results;
    }

查看循环 for (List row : values)。如果您的 table 中有两行,您将在 values 列表中得到两个元素。

您可以将范围设置为 "A2:D",这将获取到 sheet 中的最后一行数据。

我设法通过计算当前工作表中的总行数来获得它。 然后将数据追加到下一行。

rowcount = this.mService.spreadsheets().values().get(spreadsheetId, range).execute().getValues().size()

Google Sheets API v4 没有帮助您获取 sheet 中最后写入行的索引的响应(该行下方的所有单元格均为空).可悲的是,您必须解决问题并将所有 sheet 行都提取到内存中(如果我弄错了,请您发表评论)

示例:

spreadsheet_id = '1TfWKWaWypbq7wc4gbe2eavRBjzuOcpAD028CH4esgKw'
range = 'Sheet1!A:Z'

rows = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range).execute().get('values', [])
last_row = rows[-1] if rows else None
last_row_id = len(rows)
print(last_row_id, last_row)

输出:

13 ['this', 'is ', 'my', 'last', 'row']


如果您希望将更多行附加到最后一行,

与其将所有行检索到内存中只是为了获取最后一行中的值,不如使用追加 API 将空 table 追加到 sheet,然后解析响应中返回的范围。然后您可以使用最后一行的索引来请求您想要的数据。

这个例子在Python:

#empty table
table = {
    'majorDimension': 'ROWS',
    'values': []
}

# append the empty table
request = service.spreadsheets().values().append(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE_NAME,
    valueInputOption='USER_ENTERED',
    insertDataOption='INSERT_ROWS',
    body=table)

result = request.execute()

# get last row index
p = re.compile('^.*![A-Z]+\d+:[A-Z]+(\d+)$')
match = p.match(result['tableRange'])
lastrow = match.group(1)

# lookup the data on the last row
result = service.spreadsheets().values().get(
    spreadsheetId=SPREADSHEET_ID,
    range=f'Sheetname!A{lastrow}:ZZ{lastrow}'
).execute()

print(result)

使用 =COUNTA(A:A) 公式在某个地方创建一个不会干扰您的数据范围的单元格并获取该值。 你的情况

=MAX(COUNTA(A:A50),COUNTA(B:B50))

?

如果公式之间可以有空单元格会有点棘手,但我相信它可以为您节省一些记忆。

2022 年更新

我不知道这是否与 2022 年的某个人相关,但现在你可以用不同的方式来做。 您可以将下一个值设置为范围:

const column = "A"
const startIndex = 2
const range = column + startIndex + ":" + column

在 resolve 中,您将获得具有最后一个索引的列和范围中的所有数据。 我在 js 和 php

上测试了它

根据 Mark B 的回答,我创建了一个函数来执行虚拟追加,然后从虚拟追加的响应中提取最后一行信息。

def get_last_row_with_data(service, value_input_option="USER_ENTERED"):
    last_row_with_data = '1'
    try:

        dummy_request_append = service.spreadsheets().values().append(
            spreadsheetId='<spreadsheet id>',
            range="{0}!A:{1}".format('Tab Name', 'ZZZ'),
            valueInputOption='USER_ENTERED',
            includeValuesInResponse=True,
            responseValueRenderOption='UNFORMATTED_VALUE',
            body={
                "values": [['']]
            }
        ).execute()

        a1_range = dummy_request_append.get('updates', {}).get('updatedRange', 'dummy_tab!a1')
        bottom_right_range = a1_range.split('!')[1]
        number_chars = [i for i in list(bottom_right_range) if i.isdigit()]
        last_row_with_data = ''.join(number_chars)

    except Exception as e:
        last_row_with_data = '1'

    return last_row_with_data