如何从 Google Sheet API 导出 csv?

Posted

技术标签:

【中文标题】如何从 Google Sheet API 导出 csv?【英文标题】:How to export a csv from Google Sheet API? 【发布时间】:2016-10-08 21:38:48 【问题描述】:

我找不到任何对允许 Rest API 客户端将现有 Google 表格导出到 csv 文件的 API 的引用。

https://developers.google.com/sheets/

我相信应该有办法导出它们。

【问题讨论】:

【参考方案1】:

以下网址为您提供每张 Google 电子表格的 CSV。公众、知道链接的任何人(未列出)都必须可以访问该工作表。

您需要提供的参数有:

工作表 ID(即 Google 电子表格的 URL 中的 ID https://docs.google.com/spreadsheets/d/ID/edit) 工作表名称(即用户提供的工作表名称)
https://docs.google.com/spreadsheets/d/ID/gviz/tq?tqx=out:csv&sheet=sheet_name

使用该 URL,您可以运行 GET 请求来获取 CSV。 或者将其粘贴到浏览器地址栏中。

【讨论】:

太棒了。我花了好几个小时试图找到这个 URL 结构。它没有记录在任何地方。非常感谢这个答案。 如果有人想知道为什么会这样,这里有一个指向更多解释答案的链接:***.com/questions/33713084/… 有没有办法通过私人表格和身份验证来做到这一点? @Andrew 该特定 API 仅适用于公共工作表。您可以将它们设为公开但对其他人不可见。但是,它们是公开的,因此一旦链接失效,数据就会失效。绝对不建议用于敏感数据。【参考方案2】:

您现在可以使用 Drive API 来执行此操作 - 请参阅 https://developers.google.com/drive/v3/web/manage-downloads#downloading_google_documents,但这会将您限制在文档的第一页。 Sheets API 目前不支持以 CSV 格式导出,但将来可能会提供。

【讨论】:

【参考方案3】:

首先,您应该让任何人都可以访问文档。然后你会得到url。从这个url 你应该提取由大小字母和数字组成的长id。然后使用这个脚本。

#!/bin/bash

long_id="id_assigned_to_your_document"
g_id="number_assigned_to_card_in_google_sheet"

wget --output-document=temp.csv "https://docs.google.com/spreadsheets/d/$long_id/export?gid=$g_id&format=csv&id=$long_id"

如果您在文档中仅使用一张卡,则其编号为:g_id="0"

您可能遇到的问题与获得的文件中的strange spaces 有关。我使用第二个脚本来处理它

#!/bin/bash
#Delete all lines beginning with a # from a file
#http://***.com/questions/8206280/delete-all-lines-beginning-with-a-from-a-file
sed '/^#/ d' temp.csv | 
# reomve spaces
# http://***.com/questions/9953448/how-to-remove-all-white-spaces-from-a-given-text-file
tr -d "[:blank:]" |
# regexp "1,2" into 1.2
# http://www.funtoo.org/Sed_by_Example,_Part_2
sed 's/\"\([−]\?[0-9]*\),\([0-9]*\)\"/\1.\2/g' > out.csv

更新

正如 Sam 所说,api 是更好的解决方案。现在有很多关于地址的文档:

https://developers.google.com/sheets/quickstart/php

以生成具有 CSV 结构的输出为例。

【讨论】:

不错的解决方案!另外:您可以随时在 google-chrome 中使用 network-inspector(Ctrl+Shift+I,网络选项卡):当它执行 CSV 导出请求时,我们可以看到相应的 URL。我猜你以同样的方式得到上面的 URL? ;) 很多年前的事了 :) 现在不记得了。 我认为您在第一个代码块的最后部分是指 $long_id 而不是 $ling_id 是的@nikhilvj。我解决了这个问题。谢谢。【参考方案4】:

还没有人提到gspread,所以我是这样做的:

#open sheet
sheet = gc.open_by_key(sheet_id)

#select worksheet
worksheet = sheet.get_worksheet(0)

#download values into a dataframe
df = pd.DataFrame(worksheet.get_all_records())

#save dataframe as a csv, using the spreadsheet name
filename = sheet.title + '.csv'
df.to_csv(filename, index=False)

【讨论】:

【参考方案5】:

如果您不能轻松访问或熟悉 PHP,这里有一个非常简单的 Google Apps 脚本 Web 应用,一旦部署并接受调用者权限,应该允许具有适当范围的访问令牌或 api 密钥的客户端导出现有的 Google 表格到 csv 文件。它将 Google Sheets 电子表格 ID 和工作表名称(以及可选的下载文件名)作为查询参数,并返回相应的理论上符合 RFC 4180 的 CSV 文件。

有关将 Apps 脚本项目部署为 Web 应用的更多说明如下:https://developers.google.com/apps-script/guides/web#deploying_a_script_as_a_web_app。

您只需访问“当前 Web 应用程序 URL”(当您从脚本编辑器作为 Web 应用程序发布时提供)并接受同意屏幕,甚至只是访问我在示例 URL 中部署的那个(配置为作为访问用户执行,并且未经验证/可怕的同意)。

棘手的部分(像往常一样)是设置 OAuth 令牌或 API 密钥,但如果您已经在调用 Google Sheets V4 API,那么您可能已经拨入了。我使用 CURL 来确保它的行为类似于 REST api,但是我用来获取 OAuth 令牌的技术会让人分心,坦率地说,在这里包含它有点吓人,因为它真的很容易搞砸。如果您还没有办法获得一个,那么无论如何这可能是一个单独的 SO 问题的好话题。

一个相关的(也是重要的!)警告:我不是 100% 确定同意和验证如何与纯 Rest 客户端交互(即,如果您不先在浏览器中访问它,它是如何工作的......) ,和/或此脚本是否需要与使用 Sheets API 的其他代码位于同一 GCP 项目中。如果有兴趣,和/或开箱即用,请告诉我,我会很乐意深入挖掘并跟进。

// Example URL, assuming:
// "Current web app URL": https://script.google.com/a/tillerhq.com/macros/s/AKfycbyZlWAW6bpCpnFoPjbdjznDomFRbTNluG4siCBMgOy2qU2AGoA/exec
// spreadsheetId: 1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E
// sheet name: Sheet1
// (optional) filename: mycsv.csv
//
// https://script.google.com/a/tillerhq.com/macros/s/AKfycbyZlWAW6bpCpnFoPjbdjznDomFRbTNluG4siCBMgOy2qU2AGoA/exec?spreadsheetid=1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E&sheetname=Sheet1&filename=mycsv.csv?spreadsheetid=1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E&sheetname=Sheet1&filename=mycsv.csv
//


var REQUIRED_PARAMS = [
  'spreadsheetid', // example: "1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E"
  'sheetname'      // Case-sensitive; example: "Sheet1"
];

// Returns an RFC 4180 compliant CSV for the specified sheet in the specified spreadsheet
function doGet(e) 

  REQUIRED_PARAMS.forEach(function(requiredParam) 
    if (!e.parameters[requiredParam]) throw new Error('Missing required parameter ' + requiredParam);
  );

  var spreadsheet = SpreadsheetApp.openById(e.parameters.spreadsheetid);
  var sheet = spreadsheet.getSheetByName(e.parameters.sheetname);
  if (!sheet) throw new Error("Could not find sheet " + e.parameters.sheetname + " in spreadsheet " + e.parameters.spreadsheetid);

  var filename = e.parameters.filename || (spreadsheet.getName() + "_" + e.parameters.sheetname + ".csv");


  var numRows = sheet.getLastRow();
  var numColumns = sheet.getLastColumn();

  var values = sheet.getSheetValues(1, 1, numRows, numColumns);

  function quote(s) 

    s = s.toString();

    if ((s.indexOf("\r") == -1)
       && (s.indexOf("\n") == -1)
       && (s.indexOf(",") == -1)
       && (s.indexOf("\"") == -1)) return s;

    // Fields containing line breaks (CRLF)*, double quotes, and commas should be enclosed in double-quotes;
    // anything other than that we already returned, so if we get here -- escape it and quote it.

    // *That's what the text of the RFC says, but the ABNF (...and Excel) treat EITHER CR or LF as requiring quotes.

    // Replace any double quote with a double double quote, and wrap the whole thing in quotes
    return "\"" + s.replace(/"/g, '""') + "\"";
  ;

  var csv = values.map(function(row) 
    return row.map(quote).join();
  ).join("\r\n") + "\r\n";


  return ContentService
  .createTextOutput(csv)
  .setMimeType(ContentService.MimeType.CSV)
  .downloadAsFile(filename);

【讨论】:

以上是关于如何从 Google Sheet API 导出 csv?的主要内容,如果未能解决你的问题,请参考以下文章

从 Google Sheet API v4 追加数据不再起作用

如何使用 Google Sheets API python 将下拉列表添加到 google sheet

如何使用API编辑google sheet而不需要手动登录?

如何以编程方式将 Google Sheet 脚本发布/部署为 API 可执行文件?

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

如何在 google sheet api 中获取列标题及其名称的映射?