【问题标题】:Can I use Google Visualization API to query a spreadsheet in apps script?我可以使用 Google Visualization API 在应用脚本中查询电子表格吗?
【发布时间】:2014-03-11 16:18:07
【问题描述】:

我有一个包含大约 3000 行数据(和大约 30 列)的 Google 电子表格。数据以标准方式排列,具有列标题和每个数据项一行。数据代表各种学术课程中使用的案例研究和文章,并且数据集一直在增长。

我需要根据指定的参数搜索/查询数据。例如,我想运行这个查询:select * where course_no = 123 and coach = Smith and year = 2012。我想得到一系列数据作为结果,然后我可以简单地显示为原始数据新工作表上的数据,或使用 GAS 处理成某种报告,或者只是将原始数据通过电子邮件发送给收件人。

看起来 Google 可视化 API 提供了不错的查询选项(我正在查看 google.visualization.Query 类的 setQuery 方法),但是是否可以在不将其附加到图表或可视化的情况下使用它?我可以在脚本中调用它,然后自己管理它返回的范围吗?当我尝试这个时,我在这一行收到错误“ReferenceError: google is not defined”:

var query = new google.visualization.Query(my_data_source_url);

我也不确定在上面的代码行中使用电子表格 url 作为 data_source_url 是正确的做法,尽管我正在尝试这样做。

我正在尝试这个,因为我假设使用这种查询方法比逐个搜索单元格更有效(就像这里建议的 How do I search Google Spreadsheets?)但我感谢所有反馈。谢谢!嘉莉

【问题讨论】:

    标签: google-apps-script


    【解决方案1】:

    很遗憾,目前无法在 Google Apps 脚本项目中直接加载 Google Visualization API。不过,您确实有几个选择:

    1. querying the response 之前使用构建到 Google Apps 脚本 (ScriptDb) 中的 noSQL 存储到 read the spreadsheet into a database

    2. 忘记在 Apps 脚本中查询数据并在工作表中使用 QUERY formula(这使用与 the Google Visualization API Query Language 相同的语法

    3. 如果使用旧表格,您可以文件 > 发布到网络,然后使用 URL Fetch Service 查询脚本中的数据并通过 Setting the Query in the Data Source URL 调用数据 simple tool helps you build the datasource url。

    就个人而言,根据情况,我会尝试#2,但如果失败,则选择#1

    【讨论】:

    • #3 是去这里的唯一途径。除非您的来源很少更改,否则#1 没有多大意义。我之前做过#3,它并不难,而且比循环所有数据要快。您需要处理 spresdsheet api 的获取标头和 oauth 设置,因此在您第一次运行它时,谷歌会请求权限。将返回类型指定为 json,因为解析它很简单。
    • 感谢您的 cmets 和建议。很高兴知道 Visualization API 不是一个选项。我之前没有考虑过 QUERY 公式,因为我将使用不同的值多次运行查询以生成例如每个讲师的报告。但也许我可以在工作表中设置公式并通过脚本操作参数。源数据一直在增长,但查询(大部分)需要在设定的时间(每季度一次或两次)进行,所以 #1 也值得一看。
    • 至于#3,我不希望数据公开——发布到网络需要这样做吗?我还想切换到新的表格,因为我们要积累的数据量很大,但还没有。如果我有其他问题,我会让你知道什么对我有用。谢谢!
    • #3 不需要公开电子表格。 Gas UrlFetch 将接管 oauth。您还不能使用新工作表进行此类查询。
    • 我有一个显示 givz 图表的页面。现在我想以编程方式生成并保存同一张图表。我怎么做 ?作为一个黑客,我尝试创建一个查询页面的函数,但我得到“你应该打开 Javascript 支持。”...
    【解决方案2】:

    我已经设法使用UrlFetchApp 来获取数据。

    • 文件必须公开共享(“每个人都可以查看”就足够了)

    用法

    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;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多