使用 Google Sheets API 将图像插入 Google Sheets 单元格

Posted

技术标签:

【中文标题】使用 Google Sheets API 将图像插入 Google Sheets 单元格【英文标题】:Insert image into Google Sheets cell using Google Sheets API 【发布时间】:2017-09-25 15:27:51 【问题描述】:

在 google apps Script 中,您可以使用 insertImage 函数 (https://developers.google.com/apps-script/reference/spreadsheet/sheet#insertimageblob-column-row) 将图像插入到 Google 电子表格中。

但我没有使用 appscript。我正在使用 Google Sheets API (https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets),但我似乎找不到这样做的方法。有没有可能的实现方式?

【问题讨论】:

【参考方案1】:

V4 API 无法像 Apps 脚本那样插入图像 blob(其中图像是工作表上的叠加层,不与任何单元格关联)。您可以使用 =IMAGE 函数解决此问题。我们知道功能上的差距,并正在考虑增加对图像 blob 的支持。

【讨论】:

是的,我编写了 Sheets V4 API。 @SamBerlin 知道什么时候可以实现这个功能吗? 抱歉,没有时间线可以分享。 嗨@SamBerlin,有计划将此功能添加到api吗? gsuiteupdates.googleblog.com/2019/03/… 我也有同样的需求。我有一个blob数据。我需要使用 Google Sheet API v4 在 google sheet 中插入 blob。您提到了使用 =IMAGE 函数的解决方法。我们如何做到这一点?我不想将 blob 转换为可以通过 URL 访问的图像【参考方案2】:

用这样的脚本设置公式:

function showImage() 
 var ss=SpreadsheetApp.getActiveSpreadsheet() 
 var formulaSheet = ss.getSheetByName("Sheet1");
 var formulaCell = formulaSheet.getRange("B5");
 formulaCell.setFormula('=IMAGE("http://finviz.com/fut_chart.ashx?t=ES&p&p=m5&s=m",4,100,200)')

【讨论】:

何 Nelson,非常感谢您提供的代码 sn-p。这太有价值了……如果您有一个可以共享 Google 表格内容的网站。让我知道...这太棒了!!! 此图像公式不会导出为 XLS 格式。最好使用 Google Apps Script Web App gateway。【参考方案3】:

在此期间,此 Google Apps Script Web App 会执行此操作(出于隐私和安全考虑,我建议您托管自己的而不是使用这个)。

这适用于 JSON 或 application/x-www-form-urlencoded,以及传递的 URL 是链接还是实际的 base64 编码图像 URL,就像您可能从 https://www.base64-image.de/ 获得的一样。

function doGet(e) 
  return ContentService.createTextOutput("Authorization: Bearer " + ScriptApp.getOAuthToken())


//
// Example curl command to insert an image:
// 
// curl -L -d ' "spreadsheetid": "1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E","sheetname": "Sheet1", "imageurl": "https://www.google.com/images/srpr/logo3w.png", "column": 1, "row": 1 ' \
// -H "Authorization: Bearer <INSERT TOKEN RETURNED FROM GET HERE>" \
// -H 'Content-Type: application/json' \
// https://script.google.com/a/tillerhq.com/macros/s/AKfycbzjFgIrgCfZTvOHImuX54G90VuAgmyfz2cmaKjrsNFrTzcLpNk0/exec
//

var REQUIRED_PARAMS = [
  'spreadsheetid', // example: "1xNDWJXOekpBBV2hPseQwCRR8Qs4LcLOcSLDadVqDA0E"
  'sheetname',     // Case-sensitive; example: "Sheet1"
  'imageurl',      // Can be an url such as "https://www.google.com/images/srpr/logo3w.png"
                   // or alternately "data:image/png;base64,iVBOR...<snip>...gg=="
  'column', // 1-based (i.e. top left corner is column 1)
  'row'     // 1-based (i.e. top left corner is row 1)
];

function doPost(e) 

  var result = 
    status: "ok",
    defaultMessage: "Image inserted."
  

  try 
    var params = (e.postData && e.postData.type == "application/x-www-form-urlencoded") ? e.parameter
    : (e.postData && e.postData.type == "application/json") ? JSON.parse(e.postData.contents)
    : undefined;


    if (!params) throw new Error('Unsupported content-type, must be either application/x-www-form-urlencoded or application/json.');

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

    SpreadsheetApp.openById(params.spreadsheetid).getSheetByName(params.sheetname).insertImage(params.imageurl, params.column, params.row);  

   catch(e) 

    console.error(e); 

    result.status = "error";
    result.error = e;
    result.defaultMessage = e.message;

    

  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON)  

我从来没有弄清楚的两个令人费解的事情:

在访问 Web 应用程序的 URL 并接受权限后,它在 Postman 中一直运行良好(可能使用 cookie 进行身份验证)。不幸的是,直到我在清单中手动添加https://www.googleapis.com/auth/drive 之前,我无法使用 ScriptApp.getOAuthToken() 中返回的 Oauth 令牌从 curl 中运行它——这对我来说仍然有点令人头疼。

这是我生成的清单:


  "timeZone": "America/Los_Angeles",
  "dependencies": 
  ,
  "webapp": 
    "access": "ANYONE",
    "executeAs": "USER_ACCESSING"
  ,
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive"]

我也无法让它转换为 Blob 并将其传递给 insertImage(),但 insertImage 的 URL 风格适用于完整的 Base 64 编码图像 URL,所以这有点烦人,但这似乎在 Sheets API 获得该功能之前合理可行。

脚本(源代码)本身在此处以只读方式与世界共享:

https://script.google.com/d/1JvFwemL45x3orxFiJf_Gye-JWXaFlzA_MysJsQx06LsH8M2psa9i1H99/edit?usp=sharing

而且它也在这里公开部署,如果你想在不部署自己的情况下对其进行测试,那就去吧:

https://script.google.com/a/tillerhq.com/macros/s/AKfycbzjFgIrgCfZTvOHImuX54G90VuAgmyfz2cmaKjrsNFrTzcLpNk0/exec

蒂姆

【讨论】:

这里还有一点需要注意——如果你确实部署了自己的而不是仅仅使用这个,那么保持executeAs“USER_ACCESSING”是绝对必要的——否则doGet路由是一个方便的花花公子您的访问令牌的提供者,可以访问大多数 Drive 和 Sheets API。 如何使用rest API双击特定列来显示日期选择器?什么是自定义验证规则? 当我们为 imageURL 发送 blob 时,我们收到以下错误 - 结果:200 内容:"status":"error","defaultMessage":"从 URL 或错误 URL 检索图像时出错:数据:图像/png;base64, dropoff_signature = "ZGF0YT WVhSaA==" web_app_url = "script.google.com/macros/s/A y/exec" image_data = "data:image/png;base64 ," + dropoff_signature data_to_post = 'spreadsheetid' : spreadsheet_Id, 'sheetname' : 'Sheet1', 'imageurl' : image_data, 'column' : 5, 'row' : 5 encoded_data = urllib.urlencode(data_to_post) # 发送编码数据到 application-2 url_result = urlfetch.fetch(web_app_url, encoded_data, method='POST') 这就是我们调用 webapp 脚本的方式 服务账号可以调用do post方法吗?怎么称呼它?什么是必要的凭据/权限等?

以上是关于使用 Google Sheets API 将图像插入 Google Sheets 单元格的主要内容,如果未能解决你的问题,请参考以下文章

如何将此调用缓存到 Google Sheets API?

如何使用 Google Sheets API V4 导入 CSV 文件

Google Sheets API:创建电子表格或将电子表格移动到文件夹中

如何使用 Python 中的 API 重命名 Google Sheets 电子表格中的(工作)表?

Google Sheets API:如何为可嵌入工作表“发布到网络”?

使用 Sheets API v4 (Java) 获取 Google 表格上次编辑日期