【问题标题】:Link to a specific sheet in published Google Sheet链接到已发布的 Google 表格中的特定表格
【发布时间】:2020-04-26 08:14:24
【问题描述】:

我看到以前曾多次询问过类似的问题,但我似乎无法让它们发挥作用。我还读到 Google 改变了他们的 URL 的构建方式,所以不幸的是大多数解决方案都被弃用了。

我正在寻找指向已发布工作簿特定工作表的链接。我制作了一个简单的工作簿进行测试,发布的链接如下所示: https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pubhtml

如您所见,有一个顶部菜单可以在工作表之间进行更改,但这不会影响 URL。

有什么方法可以直接获取“Sheet2”的 URL?或者这取决于拥有工作表 ID(我不是所述电子表格的所有者)?

【问题讨论】:

  • 为了直接打开除了第一个选项卡之外的工作表,需要知道工作表的工作表ID。不幸的是,2PACX-### 不是电子表格 ID。因此,为了检索工作表 ID,需要电子表格 ID。而且,从你的问题来看,电子表格似乎不是你的。在这种情况下,电子表格需要公开共享。在这种情况下,它不是网络发布。请注意这一点。那么您可以检索电子表格 ID 吗?
  • 我只能访问网络发布,而不是电子表格 ID。所以这似乎是不可能的,即使我可以访问有问题的工作表,但我无法直接链接到它/直接访问它。
  • 感谢您的回复。在这种情况下,我认为无法检索工作表 ID。这样,我认为无法检索除第一个选项卡以外的工作表的直接链接。对于尚未提出其他解决方法,我深表歉意。
  • 感谢您回复我。这很不幸,在我看来是一种奇怪的限制。
  • 感谢您的回复。我想出了一个解决方法来实现你的目标。我将其发布为答案。你能确认一下吗?如果这不是您想要的方向,我很抱歉。

标签: google-sheets


【解决方案1】:

我相信你的目标如下。

  • 您想从https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pubhtml 的 URL 中检索来自 Sheet2 的值。
  • 此电子表格的所有者不是您。
  • 您不知道电子表格 ID 和电子表格中的每个表格 ID。你只知道https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml的网址。
  • 在上述情况下,您要检索工作表 2 的直接 URL。

对于以上目标,这个答案怎么样?

问题和解决方法:

不幸的是,在现阶段,似乎无法从https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml的URL中直接检索到Spreadsheet ID和每个sheet ID。我认为这是当前的规范。我也认为这个原因可能是由于安全性。因此,为了实现您的目标,需要考虑解决方法。

在此答案中,作为一种解决方法,我想使用由 Google Apps 脚本创建的 Web 应用程序来实现您的目标。使用Web Apps时,可以检索到Sheet2的直连。

流程:

此变通方法的流程如下。

  1. https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml 的 URL 下载 Google 电子表格作为 XLSX 数据。
  2. 将 XLSX 数据转换为 Google 电子表格。
  3. 将转换后的 Google 电子表格发布到网络。
  4. 检索每张工作表的 URL。

用法:

请执行以下流程。

1。创建 Google Apps 脚本的新项目。

Web Apps 的示例脚本是 Google Apps 脚本。所以请创建一个 Google Apps Script 项目。

如果要直接创建,请访问https://script.new/。在这种情况下,如果您没有登录 Google,则会打开登录屏幕。所以请登录谷歌。这样,Google Apps Script 的脚本编辑器就打开了。

2。准备脚本。

请将以下脚本(Google Apps 脚本)复制并粘贴到脚本编辑器中。还有please enable Google Drive API at Advanced Google services。此脚本适用于 Web 应用程序。

function doGet(e) {
  const prop = PropertiesService.getScriptProperties();
  const ssId = prop.getProperty("ssId");
  if (ssId) {
    DriveApp.getFileById(ssId).setTrashed(true);
    prop.deleteProperty("ssId");
  }
  const inputUrl = e.parameter.url;
  const re = new RegExp("(https?:\\/\\/docs\\.google\\.com\\/spreadsheets\\/d\\/e\\/2PACX-.+?\\/)");
  if (!re.test(inputUrl)) return ContentService.createTextOutput("Wrong URL.");
  const url = `${inputUrl.match(re)[1]}pub?output=xlsx`;
  const blob = UrlFetchApp.fetch(url).getBlob();
  const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "temp"}, blob).id;
  prop.setProperty("ssId", id);
  Drive.Revisions.update({published: true, publishedOutsideDomain: true, publishAuto: true}, id, 1);
  const sheets = SpreadsheetApp.openById(id).getSheets();
  const pubUrls = sheets.map(s => ({[s.getSheetName()]: `https://docs.google.com/spreadsheets/d/${id}/pubhtml?gid=${s.getSheetId()}`}));
  return ContentService.createTextOutput(JSON.stringify(pubUrls)).setMimeType(ContentService.MimeType.JSON);
}
  • 在这种情况下,使用 GET 方法。
  • 在此脚本中,当运行以下 curl 命令时,Google 电子表格将下载为 XLSX 数据,并将 XLSX 数据转换为 Google 电子表格。然后,将转换后的电子表格发布到 Web。这样,可以检索每个工作表的直接链接。
    • 此外,在此脚本中,它假设原始电子表格已更改。因此,如果再次运行 curl 命令,则会删除现有的电子表格,并通过从原始电子表格下载来创建新的电子表格。在这种情况下,会更新 URL。
    • 因此,如果电子表格未更改,您可以继续使用检索到的 URL。当然,您也可以直接使用下载并转换后的电子表格。

3。部署 Web 应用程序。

  1. 在脚本编辑器上,通过“发布”->“部署为 Web 应用”打开一个对话框。
  2. “执行应用程序为:”选择“我”
    • 由此,脚本以所有者身份运行。
  3. “谁有权访问应用程序:”选择“任何人,甚至匿名”
    • 在这种情况下,不需要请求访问令牌。我认为我建议您使用此设置来实现您的目标。
    • 当然,您也可以使用访问令牌。届时,请将其设为“任何人”
  4. 单击“部署”按钮作为新的“项目版本”。
  5. 自动打开“需要授权”对话框。
    1. 点击“查看权限”。
    2. 选择自己的帐户。
    3. 点击“此应用未验证”中的“高级”。
    4. 点击“转到###项目名称###(不安全)”
    5. 点击“允许”按钮。
  6. 点击“确定”。
  7. 复制 Web 应用程序的 URL。就像https://script.google.com/macros/s/###/exec
    • 当您修改 Google Apps 脚本时,请重新部署为新版本。这样,修改后的脚本就会反映到 Web 应用程序中。请注意这一点。

4。使用 Web 应用程序运行函数。

这是一个用于请求 Web 应用程序的示例 curl 命令。请设置您的网络应用 URL。

curl -L "https://script.google.com/macros/s/###/exec?url=https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pubhtml"
  • 在这种情况下,在 Web 应用端使用 GET 方法。所以您也可以使用浏览器直接访问上述网址。

注意:

  • 当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
  • 在这个答案中,我认为您可以从外部使用它。所以我使用了网络应用程序。如果要直接从 Google Apps Script 中检索,也可以使用以下脚本。

    function myFunction() {
      const inputUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pubhtml";
    
      const prop = PropertiesService.getScriptProperties();
      const ssId = prop.getProperty("ssId");
      if (ssId) {
        DriveApp.getFileById(ssId).setTrashed(true);
        prop.deleteProperty("ssId");
      }
      const re = new RegExp("(https?:\\/\\/docs\\.google\\.com\\/spreadsheets\\/d\\/e\\/2PACX-.+?\\/)");
      if (!re.test(inputUrl)) throw new Error("Wrong URL.");
      const url = `${inputUrl.match(re)[1]}pub?output=xlsx`;
      const blob = UrlFetchApp.fetch(url).getBlob();
      const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "temp"}, blob).id;
      prop.setProperty("ssId", id);
      Drive.Revisions.update({published: true, publishedOutsideDomain: true, publishAuto: true}, id, 1);
      const sheets = SpreadsheetApp.openById(id).getSheets();
      const pubUrls = sheets.map(s => ({[s.getSheetName()]: `https://docs.google.com/spreadsheets/d/${id}/pubhtml?gid=${s.getSheetId()}`}));
      console.log(pubUrls);  // You can see the URLs for each sheet at the log.
    }
    

参考资料:

补充:

作为另一种解决方法,当原始电子表格经常更改,并且原始电子表格中的工作表数量是恒定的,然后,您只想检索值,您也可以使用以下脚本。在此脚本中,即使再次运行脚本,URL 也不会更改。这样您就可以继续使用该 URL。

示例脚本:

function myFunction() {
  const inputUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pubhtml";

  const re = new RegExp("(https?:\\/\\/docs\\.google\\.com\\/spreadsheets\\/d\\/e\\/2PACX-.+?\\/)");
  if (!re.test(inputUrl)) throw new Error("Wrong URL.");
  const url = `${inputUrl.match(re)[1]}pub?output=xlsx`;
  const blob = UrlFetchApp.fetch(url).getBlob();
  const prop = PropertiesService.getScriptProperties();
  let sheets;
  let ssId = prop.getProperty("ssId");
  if (ssId) {
    const temp = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, blob).id;
    const tempSheets = SpreadsheetApp.openById(temp).getSheets();
    sheets = SpreadsheetApp.openById(ssId).getSheets();
    tempSheets.forEach((e, i) => {
      const values = e.getDataRange().getValues();
      sheets[i].getRange(1, 1, values.length, values[0].length).setValues(values);
    });
    DriveApp.getFileById(temp).setTrashed(true);
  } else {
    ssId = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "copiedSpreadsheet"}, blob).id;
    Drive.Revisions.update({published: true, publishedOutsideDomain: true, publishAuto: true}, ssId, 1);
    prop.setProperty("ssId", ssId);
    sheets = SpreadsheetApp.openById(ssId).getSheets();
  }
  const pubUrls = sheets.map(s => ({[s.getSheetName()]: `https://docs.google.com/spreadsheets/d/${ssId}/pubhtml?gid=${s.getSheetId()}`}));
  console.log(pubUrls);  // You can see the URLs for each sheet at the log.
}

【讨论】:

  • 哇,非常感谢您的详尽回答!不幸的是,尽管最初的假设和目标是正确的,但我认为我不能从“2-PACKX-##/pubhtml” URL 下载 xlsx。没有顶部菜单。即使我可以说这个解决方案比我想要的诚实更先进。尽管我可以理解其中的大部分内容,但这似乎是一个非常繁重的解决方法。再次感谢,如果这令人失望,对不起。
  • @Mixy 感谢您的回复。我想你可能误解了我的回答。为了将2-PACKX-## 的URL 的Google 电子表格下载为XLSX 数据,这可以通过修改URL 来实现。这可以在我的脚本中看到。在您的 URL 中,您可以通过访问 https://docs.google.com/spreadsheets/d/e/2PACX-1vRrmEbjecLvXhbm409pa6JJXZd_ZXTG8Zt6OevIUs5Axq5oxlCZKU0QXk-2lW05HyXJ2B4Bzy3bG-4L/pub?output=xlsx 将其下载为 XLSX 数据。这样,所有的工作表都被包含在内。所以我提出了这个解决方法。
  • 我明白了。这适用于我为模拟问题而创建的电子表格,但不适用于我试图抓取的原始电子表格。希望您理解我不想在这里发布原始链接。使用链接格式 /pub?output=xlsx 获取文件未找到错误毕竟看起来我必须找到一个新的解决方案。 Excel 因我添加的所有查询而崩溃,所以我必须找到我认为更有效的方法
  • @Mixy 感谢您的回复。我带来的不便表示歉意。我无法理解Getting a File not found error with the link format /pub?output=xlsx。可以问一下具体情况吗?
  • 我为原始工作表创建了一个临时 URL。 temporary-url.com/0A266E 请您检查一个端点以从该表中获取 xlsx-download 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 2021-03-01
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多