Google可视化API(gviz)查询并从电子表格中提取数据

时间:2015-03-23 03:03:41

标签: sql google-apps-script google-sheets google-visualization urlfetch

我使用Google Visualization API查询电子表格。如果我在浏览器中粘贴网址:

https://docs.google.com/spreadsheets/d/14dIMLkVwHRo-bkvdIhaDwC-rGBHLefftlC6CCCs5YrWSc/gviz/tq?sheet=customers&tq=select+*+Where+A='27938'

A是客户ID列。我把这个JSON看起来回来了: google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"7671558882","table":{"cols":[{"id":"A","label":"ID","type":"string"},{"id":"B","label":"FirstName",.....

1)我如何在谷歌脚本功能中做同样的事情(而不是从客户端javascript函数)?

我尝试使用URLFetchApp.fetc():

var url = 'https://docs.google.com/spreadsheets/d/14dIMLkVwHRo-bkvdIhaDwC-rGBHLefftlC6CCCs5YrWSc/gviz/tq?sheet=customers&tq=select+*+Where+A=27938'
var result = URLFetchApp.fetch(url);
var out = JSON.parse(result.getContentText());
Logger.log(out);

记录器显示了一长串CSS样式定义和HTML标记。如果我可以获得JSON响应并解析它,我计划在函数中做一些业务逻辑,向客户端返回一个值。

3 个答案:

答案 0 :(得分:2)

我发现google sheet / gvis查询也存在问题 - 由于未知原因Google表格返回的不是纯JSON,而是添加了一些s ***,因此在使用JSON.parse()之前我们需要剪切它(或裁剪)响应中有用的部分):

var httpresponse = UrlFetchApp.fetch(urlrequest, options).getContentText();

var from = httpresponse.indexOf("{");
var to   = httpresponse.lastIndexOf("}")+1;

var jsonText = httpresponse.slice(from, to);

var parsedText = JSON.parse(jsonText);

答案 1 :(得分:0)

我认为您需要在apss脚本(documentation)中调用函数openByID然后调用方法getRange(),然后您将收到一个带有工作表信息的二维数组。

然后您可以创建JSON以使用图表服务(docs

可能已经有一些库了。查看this网站,您可能会找到所需的网站。 希望这会有所帮助。

答案 2 :(得分:0)

获取“ CSS样式定义和HTML标签”的原因是请求中的错误。

这是错误文本:

  

此电子表格无法公开查看,并且需要OAuth   凭据。有关更多信息,请参见   https://support.google.com/docs/?p=gviz_tq_auth

共享文件以解决该问题:

enter image description here

这是我用来获取2D数组查询结果的示例代码:

用法

function test_getSheetsQueryResult()
{
  var fileId = '1WO3PEycHGtfG-yd4V-B6EfKkVYMC73EqDBPqgAqcz3k';
  var sheetName = 'Data';
  var rangeA1 = 'A1:H11';
  var sqlText = "select A, C, D, F, 'google' where E > 0";

  var res = getSheetsQueryResult_(fileId, sheetName, rangeA1, sqlText);
  Logger.log(res);

}

代码:

/*   
  Types:

    Get             Return
    number    =>    number
    string    =>    string
    date      =>    string
    datetime  =>    string
    boolean   =>    boolean

  Note: 

    The function returns strings for dates because of 2 resons:
      1. The string is automatically converted into a date when pasted into the sheet
      2. There are multiple issues with dates (like different time zones) that could modify returned values
*/
function getSheetsQueryResult_(fileId, sheetName, rangeA1, sqlText)
{

  var file = SpreadsheetApp.openById(fileId);
  var sheetId = file.getSheetByName(sheetName).getSheetId();

  var request = 'https://docs.google.com/spreadsheets/d/' + fileId + '/gviz/tq?gid=' + sheetId + '&range=' + rangeA1 + '&tq=' + encodeURIComponent(sqlText);
  var result = UrlFetchApp.fetch(request).getContentText();     
  // get json object
  var from = result.indexOf("{");
  var to   = result.lastIndexOf("}")+1;  
  var jsonText = result.slice(from, to);  
  var parsedText = JSON.parse(jsonText);      

  // get types
  var types = [];
  var addType_ = function(col) { types.push(col.type); }
  var cols = parsedText.table.cols;
  cols.forEach(addType_);    

  // loop rows
  var rows = parsedText.table.rows;  
  var result = [];  
  var rowQuery = [];
  var eltQuery = {};
  var row = [];
  var nRows = rows[0].c.length;
  var type = '';
  for (var i = 0, l = rows.length; i < l; i++)
  {
    rowQuery = rows[i].c;
    row = [];
    // loop values   
    for (var k = 0; k < nRows; k++)
    {
      eltQuery = rowQuery[k];
      type = types[k];
      if (type === 'number') { row.push(parseInt(eltQuery.v)); }
      if (type === 'boolean' || type === 'string') { row.push(eltQuery.v); }
      else { row.push(eltQuery.f); }      
    }    
    result.push(row);
  }

  return result;

}