【问题标题】:How to use sheet ID in Google Sheets API?如何在 Google Sheets API 中使用工作表 ID?
【发布时间】:2018-10-22 17:15:35
【问题描述】:

Google 表格文档可以包含一些表格。首先是默认值和“0”。通常对于任何工作表都有这样的地址:

https://docs.google.com/spreadsheets/d/(spreadsheetId)/edit#gid=(sheetId)

spreadsheetIdsheetId

但是在API documentation 中没有提到如何使用sheetId。我只能阅读和编辑给定 spreadsheetId 的默认工作表。

如果在示例链接中提供的代码中的request 中,我添加了sheetId 属性,我得到了错误:

{ 
    message: 'Invalid JSON payload received. Unknown name "sheetId": Cannot bind query parameter. Field \'sheetId\' could not be found in request message.',
    domain: 'global',
    reason: 'badRequest' 
}

如何在 Google Sheets API 中访问默认以外的其他工作表并读取或更新其中的字段?

【问题讨论】:

标签: google-sheets google-api google-sheets-api


【解决方案1】:

工作表名称是访问特定工作表的最简单方法。如here 所写,range 参数可以包括工作表名称,如,

Sheet1!A1

如果您必须使用工作表 ID 而不是工作表名称,您可以使用任何使用 dataFilter 的替代端点,例如 spreadsheets.values.batchUpdateByDataFilter 而不是 spreadsheets.values.batchUpdate。然后,您可以在data.dataFilter.gridRange.sheetId 的请求正文中使用 sheetId。 another answer here by ztrat4dkyle 提供了一个使用带有 sheetId 的过滤器的示例。

但是,developer metadata 是将对象(工作表/范围/列)永久关联到变量的首选方法,用户需要对这些对象进行修改。

【讨论】:

  • 投了反对票,因为问题是关于工作表 ID 的。通过重命名工作表,您可能会在不知不觉中打破基于名称的范围。
  • 无关答案。
  • @Rahul 怎么样?尽管我认为 Calin 的反对票是不合理的,但我确实编辑了我的答案以显示其他可能性。你投反对票的理由是什么?
  • Sheet id 可能不固定,但可以从 url 轻松找到。谷歌文档也提供正则表达式来获得它。这不是公认的答案。
  • 很好的答案!而不是使用 ID。我喜欢名称而不是 ID 的想法,也适用于 ID。我投了赞成票
【解决方案2】:

在创建新的 Google 表格时始终存在的初始空白选项卡始终分配有 sheetId 0。

随后创建的 sheetId 是随机的十位数字。只有第一个选项卡的 sheetId 为 0。即使重命名工作表,它的 ID 也保持不变。 ID 永远不会重复使用 - 它们在给定的工作表中保持唯一。

使用 Google Drive API,对 Google Sheet 的访问是使用工作表的 Google Drive 文件 ID 实例化的。

一旦您实例化了对特定 Google 表格文件的访问权限,您就可以通过使用“sheetId”命名法来引用表格选项卡中的每个选项卡并在表格的选项卡中操作信息、格式等。

这是一个使用 sheetId 0 重命名 Google 表格的选项卡名称的 PHP 示例。

<?php
/*
 *   Google Sheets API V4 / Drive API V3, rename existing sheet tab example
 *
 */
$fileID = '/* pass your Google Sheet Google Drive file ID here */';
$client = new Google_Client();
$client->useApplicationDefaultCredentials(); // the JSON service account key location as defined in $_SERVER
$client->setApplicationName('API Name');
$client->addScope(Google_Service_Drive::DRIVE);
$client->setAccessType('offline');
$client->setSubject('API Instance Subject');
$sheet = new Google_Service_Sheets($client);
$sheetList = $sheet->spreadsheets->get($fileID);

/*
 *   iterate through all Google Sheet tabs in this sheet
 */
 $homeFlag = FALSE;
 foreach($sheetList->getSheets() as $sheetRecord) {
        /*
         *   if match, save $sheetTabID from Google Sheet tab 
         */
         if ($sheetRecord['properties']['sheetId'] == 0) {
                 $sheetTabID = $sheetRecord['properties']['sheetId'];
                 $sheetTabTitle = $sheetRecord['properties']['title'];
                 $homeFlag = TRUE;
            }
    }

/*
 *   if $homeFlag is TRUE, you found your desired tab, so rename tab in Google Sheet
 */
 if ($homeFlag) {
         $newTabName = 'NotTabZero';
         $sheetRenameTab = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(array('requests' => array('updateSheetProperties' => array('properties' => array('sheetId' => $sheetTabID, 'title' => $newTabName), 'fields' => 'title'))));
         $sheetResult = $sheet->spreadsheets->batchUpdate($sheetID,$sheetRenameTab);
    }
?>

【讨论】:

    【解决方案3】:

    这是我的“通过 sheetId 重命名电子表格中的工作表”函数的工作示例。 您可以以相同的方式使用 Google Spreadsheets API Docs 中的其他方法。希望对某人有所帮助

    
        <?php
    function getClient()   //standard auth function for google sheets API
    {
        $clientConfigPath = __DIR__ . '/google_credentials/client_secret.json';
        $client = new Google_Client();
        $client->setApplicationName('Google Sheets API PHP Quickstart');
        $client->setScopes(Google_Service_Sheets::SPREADSHEETS);
        $client->setAuthConfig($clientConfigPath);
        $client->setAccessType('offline');
    
        // Load previously authorized credentials from a file.
        $credentialsPath = (__DIR__ . '/google_credentials/credentials.json');
        if (file_exists($credentialsPath)) {
            $accessToken = json_decode(file_get_contents($credentialsPath), true);
        } else {
            // Request authorization from the user.
            $authUrl = $client->createAuthUrl();
            printf("Open the following link in your browser:\n%s\n", $authUrl);
            print 'Enter verification code: ';
            $authCode = trim(fgets(STDIN));
    
            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
    
            // Store the credentials to disk.
            if (!file_exists(dirname($credentialsPath))) {
                mkdir(dirname($credentialsPath), 0700, true);
            }
            file_put_contents($credentialsPath, json_encode($accessToken));
            printf("Credentials saved to %s\n", $credentialsPath);
        }
        $client->setAccessToken($accessToken);
    
        // Refresh the token if it's expired.
        if ($client->isAccessTokenExpired()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
            file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
        }
        return $client;
    }
    
    
    function renameSheet(string $sheetId, string $newTitle, string $spreadsheetId)
    {
        // Get the API client and construct the service object.
        $client = getClient();
        $service = new Google_Service_Sheets($client);
    
        $requests = [
            new Google_Service_Sheets_Request([
                'updateSheetProperties' => [
                    'properties' => [
                        'sheetId' => $sheetId,
                        'title' => $newTitle,
                    ],
                    'fields' => 'title'
                ]
            ])
        ];
    
        $batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([
            'requests' => $requests
        ]);
    
        return $service->spreadsheets->batchUpdate($spreadsheetId, $batchUpdateRequest);
    }
    
    

    更新 如果要通过 sheetId 获取工作表标题,可以使用以下函数

    function getSpreadsheetInfo($spreadsheetId)  
    {
        $client = getClient();
        $service = new Google_Service_Sheets($client);
    
        $response = $service->spreadsheets->get($spreadsheetId);
        return $response;
    }
    
    function getSheets($spreadsheetId)  
    {
        $spreadsheet_info = getSpreadsheetInfo($spreadsheetId);
        $sheets_info = [];
        foreach ($spreadsheet_info as $item) {
            $sheet_id = $item['properties']['sheetId'];
            $sheet_title = $item['properties']['title'];
            $sheets_info[$sheet_id] = $sheet_title;
        }
        return $sheets_info;
    }
    
    $sheets_info_array = getSheets($YOUR_SPREADSHEET_ID_HERE);
    

    $sheets_info_array 将相等

    array (
        "sheet_id1(int)" => 'sheet_title1',
        "sheet_id2(int)" => 'sheet_title3',
    )
    

    所以你可以得到 $your_sheet_id 的标题为 $sheets_info_array[$your_sheet_id]

    【讨论】:

      【解决方案4】:

      基本上我们需要使用dataFilters to target a specific sheet by ID

      @TheMaster 为我指出了正确的方向,但我发现答案令人困惑,所以我只想分享我的 Node.js 工作示例。

      下面是如何从 ID 为 0123456789 的工作表中获取单元格 B2 的值

      const getValueFromCellB2 = async () => {
        const SPREADSHEET_ID = 'INSERT_SPREADSHEET_ID';
        const SHEET_ID = 0123456789;
        // TODO: replace above values with real IDs.
        const google = await googleConnection();
        const sheetData = await google.spreadsheets.values
          .batchGetByDataFilter({
            spreadsheetId: SPREADSHEET_ID,
            resource: {
              dataFilters: [
                {
                  gridRange: {
                    sheetId: SHEET_ID,
                    startRowIndex: 1,
                    endRowIndex: 2,
                    startColumnIndex: 1,
                    endColumnIndex: 2,
                  },
                },
              ],
            },
          })
          .then((res) => res.data.valueRanges[0].valueRange.values);
      
        return sheetData[0][0];
      }
      
      // There are many ways to auth with Google... Here's one:
      const googleConnection = async () => {
        const auth = await google.auth.getClient({
          keyFilename: path.join(__dirname, '../../secrets.json'),
          scopes: 'https://www.googleapis.com/auth/spreadsheets',
        });
      
        return google.sheets({version: 'v4', auth});
      }
      
      

      为了简单地读取数据,我们使用batchGetByDataFilter,其中dataFilters 是一个单独的过滤器对象数组。 gridRange filter (one of many) 允许我们指定 sheetId 和要返回的单元格范围。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多