使用 Google 表格和幻灯片,将大数据转化为实用洞见

1. 从大数据分析到幻灯片演示

数据科学家可以使用许多工具执行大数据分析,但分析人员最终仍需为管理层提供结果的合理性。纸上或数据库中的大量数据难以向主要利益相关者展示。此 Codelab 中级 Google Apps 脚本使用 2 个 Google 开发者平台(Google WorkspaceGoogle Cloud 控制台)来帮助您自动执行最后的这一阶段。

借助 Google Cloud 的开发者工具,您可以执行深度数据分析。然后,您可以获取结果,将其插入电子表格,并用这些数据生成幻灯片演示文稿。这提供了一种将数据发送给管理人员的更合适方法。此 Codelab 介绍了 Cloud 控制台的 BigQuery API(作为一种 Apps 脚本高级服务)以及适用于 Google 表格Google 幻灯片内置 Apps 脚本服务

设计初衷

此 Codelab 中的示例应用的灵感源自以下其他代码示例:

虽然幻灯片 API Codelab 示例应用也支持 BigQuery 和幻灯片,但它与此 Codelab 的示例应用有以下不同之处:

  • 他们的 Node.js 应用对比我们的 Apps 脚本应用。
  • 在我们使用 Apps 脚本服务时,它们使用 REST API。
  • 他们使用 Google 云端硬盘,而非 Google 表格,而此应用使用 Google 表格,而非云端硬盘。

对于此 Codelab,我们希望将多种技术整合到一个应用中,同时以类似于实际用例的方式展示整个 Google Cloud 的功能和 API。我们的目标是激发您的想象力,并考虑同时使用 Cloud 控制台和 Google Workspace 来解决组织和客户面临的难题。

学习内容

  • 如何将 Google Apps 脚本用于多项 Google 服务
  • 如何使用 Google BigQuery 分析大数据
  • 如何创建 Google 表格并向其中插入数据
  • 如何在 Google 表格中创建图表
  • 如何将 Google 表格中的数据和图表转移到 Google 幻灯片演示文稿

所需条件

  • 可连接到互联网的网络浏览器
  • Google 账号(Google Workspace 账号可能需要管理员批准)
  • 基本熟悉 Google 表格
  • 能够阅读 Google 表格 A1 表示法
  • JavaScript 基本技能
  • Apps 脚本开发知识有帮助,但并非必需

2. 调查问卷

您将如何使用此 Codelab/教程?

<ph type="x-smartling-placeholder"></ph> 通读这些信息以供参考,可能会转发给技术同事 尽可能详细地学习,尝试尽可能多的练习 我该完成整个 Codelab

如何评价您使用 Google Workspace 开发者工具的体验及API?

新手水平 中等水平 熟练水平

您如何评价自己使用 Apps 脚本的体验?

新手水平 中等水平 熟练水平

如何评价您使用 Cloud 控制台开发者工具的体验及API?

<ph type="x-smartling-placeholder"></ph> 新手 中级 熟练

3. 概览

现在,您已了解此 Codelab 的内容,接下来您需要执行以下操作:

  1. 获取现有的 Apps Script-BigQuery 示例并使其运行。
  2. 通过此示例,了解如何向 BigQuery 发送查询并获取结果。
  3. 创建一个 Google 表格,并将 BigQuery 中的结果插入其中。
  4. 修改代码,稍微更改返回并插入到工作表中的数据。
  5. 使用 Apps 脚本中的表格服务为 BigQuery 数据创建图表。
  6. 使用幻灯片服务创建 Google 幻灯片演示文稿。
  7. 为默认的标题幻灯片添加标题和副标题。
  8. 创建一张包含数据表格的幻灯片,并将工作表的数据单元格导出到其中。
  9. 再创建一张幻灯片,并将电子表格图表插入其中。

我们先来了解一些有关 Apps 脚本、BigQuery、表格和幻灯片的背景信息。

Google Apps 脚本和 BigQuery

Google Apps 脚本是一个 Google Workspace 开发平台,其运行级别高于 Google REST API。它是一个无服务器开发和应用托管环境,适合所有技术水平的开发者使用。从本质上讲,Apps 脚本是一种用于 Google Workspace 自动化、扩展程序和集成的无服务器 JavaScript 运行时。

它使用服务器端 JavaScript(与 Node.js 类似),但侧重于与 Google Workspace 和其他 Google 服务的紧密集成,而不是快速的异步事件驱动型应用托管。它还具有可能与您所习惯的开发环境不同的开发环境。借助 Apps 脚本,您可以:

  • 您可以使用基于浏览器的代码编辑器开发脚本,也可以使用 Apps 脚本的命令行部署工具 clasp 进行本地开发。
  • 使用专为访问 Google Workspace 和其他 Google 服务或其他外部服务而定制的专用 JavaScript 版本编写代码(使用 Apps 脚本的 URL FetchJDBC 服务)。
  • 无需编写授权代码,因为 Apps 脚本会为您处理授权代码。
  • 您不必托管应用,您的应用将位于 Google 的云端服务器中运行。

Apps 脚本可通过以下 2 种不同方式与其他 Google 技术进行交互:

  • 作为内置服务
  • 作为高级服务

内置服务具有与用户数据、其他 Google 系统和外部系统交互的高级方法。高级服务本质上是 Google Workspace API 或 Google REST API 的瘦封装容器。高级服务可全面覆盖 REST API,功能通常比内置服务更多,但是需要的代码更复杂(同时仍比完整 REST API 更易于使用)。您还必须为脚本项目启用高级服务,然后才能使用这些服务。

如果可能,开发者应该使用内置服务,因为这些服务更易于使用,并且提供的功能远不止高级服务。但是,有些 Google API 没有内置服务,因此高级服务可能是唯一选项。例如,Google BigQuery 没有内置服务,但 BigQuery 服务确实存在。BigQuery 服务是一项 Cloud 控制台服务,借助该服务,您可以使用 Google BigQuery API 对大型数据语料库(例如,数 TB)执行查询,但仍能在几秒钟内提供结果。

访问表格和通过 Apps 脚本创建幻灯片

与 BigQuery 不同,Google 表格和 Google 幻灯片都有内置服务。他们也提供高级服务,以使用只有 API 才有的功能。在开始编写代码之前,请先查看内置的表格幻灯片服务的相关文档。请注意,我们还提供了有关表格幻灯片高级服务的文档。

4. 任务 1:运行 BigQuery 并将结果记录到 Google 表格

简介

我们将通过第一项任务完成此 Codelab 的很大一部分任务。事实上,完成学习后,您已完成整个 Codelab 的一半。该课程分为几个子部分,您可以:

  • 创建 Google Apps 脚本和 Cloud 控制台项目。
  • 启用对 BigQuery 高级服务的访问权限。
  • 打开脚本编辑器并输入应用源代码。
  • 熟悉应用授权流程 (OAuth2)。
  • 运行向 BigQuery 发送请求的应用。
  • 查看使用 BigQuery 结果创建的新 Google 表格。

设置

  1. 如需创建 Apps 脚本项目,请前往 script.google.com,然后点击新建项目
  2. 如需重命名 Apps 脚本项目,请点击未命名项目,输入项目标题,然后点击重命名

接下来,您需要创建一个 Cloud 控制台项目,以便在 BigQuery 中查询数据。

  1. 如需创建 Cloud 控制台项目,请使用此快捷方式链接创建项目,为项目命名,然后点击创建
  1. 项目创建完成后,页面上会显示一条通知。确保在页面顶部的项目列表中选择您的新项目。
  2. 点击“菜单”图标 f5fbd278915eb7aa.png,然后转到 API 和服务 >OAuth 权限请求页面直接链接)。
  3. 点击内部 >创建即可为贵组织中的 Google Workspace 用户构建应用。
  4. 应用名称字段中,输入“Big Data Codelab”。
  5. 用户支持开发者联系信息字段中,输入联系电子邮件地址。
  6. 点击保存并继续 >保存并继续
  7. 点击导航栏中的“更多”图标 50fa7e30ed2d1b1c.png,然后选择项目设置直接链接)。
  8. 复制项目编号下列出的值。(此 Codelab 稍后会使用单独的 Project ID 字段。)

接下来,将您的 Apps 脚本项目关联到 Cloud 控制台项目。

  1. 切换到 App Script 编辑器,然后点击 Project Settings 图标 设置齿轮
  2. 在“Google Cloud Platform (GCP) 项目”下,点击更改项目
  3. 输入项目编号,然后点击设置项目
  4. 接下来,点击编辑器 代码编辑器 以开始添加 BigQuery 高级服务。
  5. 服务旁边,点击“添加服务”图标 添加服务
  6. 在“添加服务”对话框中,选择 BigQuery API,然后点击添加

最后一步是在 Cloud 控制台上启用 BigQuery API。

  1. 为此,请切换到 Cloud 控制台,然后点击 API 和服务 >信息中心。(确保您仍位于第 3 步中创建的同一项目。)
  2. 点击启用 API 和服务
  3. 搜索“大查询”,选择 BigQuery API不是 BigQuery Data Transfer API),然后点击启用将其开启。

a0e07fa159de9367.png

现在,您可以输入应用代码,完成授权流程,然后让该应用的首次迭代开始运行。

上传并运行应用

  1. 在脚本编辑器中,将默认的 myFunction() 代码块替换为以下代码:
// File name for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud Console Project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into a Sheet. You must turn on
 * the BigQuery advanced service before you can run this code.
 * @see https://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see https://github.com/googleworkspace/apps-script-samples/blob/master/advanced/bigquery.gs
 *
 * @returns {Spreadsheet} Returns a spreadsheet with BigQuery results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BigQuery job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to Sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
}
  1. 点击“保存”保存
  2. Code.gs 旁边,点击“更多”图标 50fa7e30ed2d1b1c.png >重命名。将标题从 Code.gs 更改为 bq-sheets-slides.js
  3. 接下来,我们来看一下用于查询 BigQuery 并将结果写入 Google 表格的代码。您可以在 runQuery() 顶部附近查看:
SELECT
    LOWER(word) AS word,
    SUM(word_count) AS count
FROM [bigquery-public-data:samples.shakespeare]
GROUP BY word
ORDER BY count
DESC LIMIT 10

此查询浏览了莎士比亚的作品(BigQuery 的公共数据集的一部分),并生成了所有作品中出现频率最高的前 10 个字词(按热门程度降序排列)。想象一下手动进行此编译会有多少工作量,您就会明白 BigQuery 会有多实用。

该函数还声明了一个 PROJECT_ID 变量,该变量需要有效的 Cloud Console 项目 ID。变量下的 if 语句用于防止应用在没有项目 ID 的情况下继续运行。

  1. 切换到您的 Cloud 控制台项目,点击导航栏中的“更多”图标 50fa7e30ed2d1b1c.png,然后选择项目设置
  2. 复制项目 ID 下列出的值。
  3. 切换回 App Script 编辑器,在 bq-sheets-slides.js 中找到 PROJECT_ID 变量,然后添加值。
  4. 点击保存 保存 >Run
  5. 点击查看权限以继续。
  1. 脚本开始运行后,内置的执行日志便会打开并实时记录脚本操作。
  1. 执行日志显示“执行已完成”后,前往您的 Google 云端硬盘 (drive.google.com),找到名为“所有莎士比亚作品中最常用字词”的 Google 表格。(或者您分配给 QUERY_NAME 变量的名称,如果您已对其进行更新):
  2. 打开电子表格,查看 10 个最常见的字词及其总数,按降序排列:

afe500ad43f8cdf8.png

任务 1 摘要

为回顾一下,您运行了一些代码,用于查询莎士比亚的所有作品,查看每部戏剧中的每一个词。它统计了单词数,并按出现顺序降序排列。您还使用了适用于 Google 表格的 Apps 脚本内置服务来显示这些数据。

您用于 bq-sheets-slides.js 的代码也可以在此 Codelab 的 GitHub 代码库的 step1 文件夹中找到,该文件夹位于 github.com/googlecodelabs/bigquery-sheets-slides 中。该代码的灵感来源于“BigQuery 高级服务”页面中的原始示例,该示例运行的查询略有不同,以检索莎士比亚使用的 10 个或更多字符的热门字词。您还可以在其 GitHub 代码库中查看示例。

如果您对可使用莎士比亚作品或其他公共数据表构建的其他查询感兴趣,请参阅如何查询 BigQuery 示例表此 GitHub 代码库

此外,您也可以在使用 Apps 脚本运行查询之前,先使用 Cloud 控制台中的 BigQuery 页面运行查询。如需找到它,请点击“菜单”图标 f5fbd278915eb7aa.png,然后转到 BigQuery 界面 >SQL 工作区直接链接)。例如,以下是我们的查询在 BigQuery 图形界面上的显示方式:

BigQueryUI

5. 任务 2:在 Google 表格中创建图表

runQuery() 的用途是使用 BigQuery 并将其数据结果发送到 Google 表格。接下来,我们需要使用这些数据制作图表。我们来创建一个名为 createColumnChart() 的新函数来调用 Google 表格的newChart() 方法。

  1. 在 Apps 脚本编辑器中,将 createColumnChart() 函数添加到 runQuery() 之后的 bq-sheets-slides.js 中。代码会获取工作表并请求生成包含所有数据的柱形图。数据范围从单元格 A2 开始,因为第一行包含列标题。
/**
 * Uses spreadsheet data to create a column chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} Visualizes the results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first) Sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in Sheet is from cell A2 to B11.
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on Sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the Sheet using above values.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);
}
  1. createColumnChart() 函数需要电子表格对象参数,因此我们需要更新 runQuery() 以返回可传递到 createColumnChart()spreadsheet 对象。在 runQuery() 末尾,在记录成功创建工作表后返回 spreadsheet 对象:
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());

  // NEW: Return the spreadsheet object for later use.
  return spreadsheet;
}
  1. 创建一个 createBigQueryPresentation() 函数来同时调用 runQuery()createColumnChart()。最佳做法是在逻辑上将 BigQuery 和图表创建功能分开:
/**
 * Runs the query, adds data and a chart to a spreadsheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  createColumnChart(spreadsheet);
}
  1. 您已完成上述 2 个重要步骤:返回电子表格对象并创建条目函数。为了使 runQuery() 更加实用,我们需要将日志行从 runQuery() 移至 createBigQueryPresentation()。您的方法现在应如下所示:
/**
 * Runs a BigQuery query, adds data and a chart to a spreadsheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl()); // MOVED HERE
  createColumnChart(spreadsheet);
}

完成上述更改后(PROJECT_ID 除外),您的 bq-sheets-slides.js 现在应如下所示。您也可以在 GitHub 代码库的 step2 中找到此代码。

// File name for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud Console Project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into a sheet. You must turn on
 * the BigQuery advanced service before you can run this code.
 * @see https://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see https://github.com/googleworkspace/apps-script-samples/blob/master/advanced/bigquery.gs
 *
 * @returns {Spreadsheet} Returns a spreadsheet with BigQuery results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BigQuery job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  // Return the spreadsheet object for later use.
  return spreadsheet;
}

/**
 * Uses spreadsheet data to create a columnar chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} Visualizes the results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first) sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in sheet is from cell A2 to B11.
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on Sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the sheet using above values.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);
}

/**
 * Runs a BigQuery query, adds data and a chart to a spreadsheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  createColumnChart(spreadsheet);
}

在脚本编辑器中,保存您的脚本项目。然后从函数列表中选择 createBigQueryPresentation,并点击 Run。导出完成后,系统会在您的 Google 云端硬盘中再创建一个电子表格,但这次系统会在数据旁边的工作表中添加一个图表:

包含图表的工作表

6. 任务 3:将结果数据放入幻灯片演示材料

此 Codelab 的最后一部分涉及创建 Google 幻灯片演示文稿、为标题幻灯片添加标题和副标题,然后构建用于数据单元格和图表的幻灯片。

  1. 在 Apps 脚本编辑器中,将 createSlidePresentation() 函数添加到 createColumnChart() 之后的 bq-sheets-slides.js 中。这张幻灯片上的所有工作都在此函数中进行。我们先创建一个幻灯片组,然后为默认的标题幻灯片添加标题和副标题。
/**
 * Create presentation with spreadsheet data and a chart
 * @param {Spreadsheet} Spreadsheet containing results data
 * @param {EmbeddedChart} Sheets chart to embed on a slide
 * @returns {Presentation} Slide deck with the results
  * @see https://developers.google.com/apps-script/reference/slides/presentation
 */
function createSlidePresentation(spreadsheet, chart) {
  // Create the presentation.
  var deck = SlidesApp.create(QUERY_NAME);

  // Populate the title slide.
  var [title, subtitle] = deck.getSlides()[0].getPageElements();
  title.asShape().getText().setText(QUERY_NAME);
  subtitle.asShape().getText().setText('using Google Cloud Console and Google Workspace APIs:\n' +
    'Google Apps Script, BigQuery, Sheets, Slides');
  1. createSlidePresentation() 中的下一步是将 Google 表格中的单元格数据导入新幻灯片。将以下代码段添加到函数中:
  // Data range to copy is from cell A1 to B11
  var START_CELL = 'A1';  // include header row
  var END_CELL = 'B11';
  // Add the table slide and insert an empty table on it with
  // the dimensions of the data range; fails if the sheet is empty.
  var tableSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  var sheetValues = spreadsheet.getSheets()[0].getRange(
      START_CELL + ':' + END_CELL).getValues();
  var table = tableSlide.insertTable(sheetValues.length, sheetValues[0].length);

  // Populate the table with spreadsheet data.
  for (var i = 0; i < sheetValues.length; i++) {
    for (var j = 0; j < sheetValues[0].length; j++) {
      table.getCell(i, j).getText().setText(String(sheetValues[i][j]));
    }
  }
  1. createSlidePresentation() 中的最后一步是再添加一张幻灯片,从电子表格导入图表,然后返回 Presentation 对象。将以下代码段添加到函数中:
  // Add a chart slide and insert the chart on it.
  var chartSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  chartSlide.insertSheetsChart(chart);

  // Return the presentation object for later use.
  return deck;
}
  1. 现在,我们的函数已完成,请再次查看它的签名。createSlidePresentation() 需要同时提供电子表格和图表对象参数。我们已将 runQuery() 调整为返回 Spreadsheet 对象,但需要对 createColumnChart() 进行类似的更改,使其返回图表对象 (EmbeddedChart)。返回 createColumnChart(),并将以下代码段添加到函数的末尾:
  // NEW: Return the chart object for later use.
  return chart;
}
  1. 由于 createColumnChart() 现在会返回图表对象,因此我们需要将图表保存到变量中。然后,我们将电子表格和图表变量同时传递到 createSlidePresentation()。此外,由于我们要记录新建电子表格的网址,因此还要记录新幻灯片演示文稿的网址。更新 createBigQueryPresentation(),使其如下所示:
/**
 * Runs a BigQuery query, adds data and a chart to a spreadsheet,
 * and adds the data and chart to a new slide presentation.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  var chart = createColumnChart(spreadsheet); // UPDATED
  var deck = createSlidePresentation(spreadsheet, chart); // NEW
  Logger.log('Results slide deck created: %s', deck.getUrl()); // NEW
}
  1. 保存并再次运行 createBigQueryPresentation()。不过,在执行之前,您的应用还需要用户再获得一组权限才能查看和管理 Google 幻灯片演示文稿。在您检查并允许这些权限后,该应用会像以前一样运行。
  2. 现在,除了创建的电子表格之外,您还应该获得一个包含 3 张幻灯片(标题、数据表格、数据图表)的新 Google 幻灯片演示文稿,如下所示:

f6896f22cc3cd50d.png

59960803e62f7c69

5549f0ea81514360

7. 总结

恭喜,您创建了一个应用,该应用同时使用了 Google Cloud 和 Google Cloud 的两种功能。它会执行 Google BigQuery 请求,查询其某个公共数据集,创建 Google 表格电子表格来存储结果,根据数据添加图表,最后创建 Google 幻灯片演示文稿,展示该电子表格中的数据和图表结果。

这些步骤是您从技术层面执行的操作。大体上来说,您已经从大数据分析发展成为了可以向利益相关方呈现的结果,而所有这些都是通过代码自动执行的。我们希望这个示例可以给您带来启发,让您针对自己的项目进行自定义。在此 Codelab 结束时,我们将针对如何进一步增强此示例应用提供一些建议。

通过对最终任务所做的更改(PROJECT_ID 除外),您的 bq-sheets-slides.js 现在应如下所示:

/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// File name for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud Console Project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into a spreadsheet. You must turn on
 * the BigQuery advanced service before you can run this code.
 * @see https://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see https://github.com/googleworkspace/apps-script-samples/blob/master/advanced/bigquery.gs
 *
 * @returns {Spreadsheet} Returns a spreadsheet with BigQuery results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BigQuery job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  // Return the spreadsheet object for later use.
  return spreadsheet;
}

/**
 * Uses spreadsheet data to create a column chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} Visualizes the results
 * @see https://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first) sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in sheet is from cell A2 to B11.
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the sheet using above values.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);
  
  // Return the chart object for later use.
  return chart;
}

/**
 * Create presentation with spreadsheet data and a chart
 * @param {Spreadsheet} Spreadsheet containing results data
 * @param {EmbeddedChart} Sheets chart to embed on a slide
 * @returns {Presentation} Slide deck with the results
 * @see https://developers.google.com/apps-script/reference/slides/presentation
 */
function createSlidePresentation(spreadsheet, chart) {
  // Create the presentation.
  var deck = SlidesApp.create(QUERY_NAME);

  // Populate the title slide.
  var [title, subtitle] = deck.getSlides()[0].getPageElements();
  title.asShape().getText().setText(QUERY_NAME);
  subtitle.asShape().getText().setText('using Google Cloud Console and Google Workspace APIs:\n' +
    'Google Apps Script, BigQuery, Sheets, Slides');

  // Data range to copy is from cell A1 to B11
  var START_CELL = 'A1';  // include header row
  var END_CELL = 'B11';
  // Add the table slide and insert an empty table on it with
  // the dimensions of the data range; fails if the sheet is empty.
  var tableSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  var sheetValues = spreadsheet.getSheets()[0].getRange(
      START_CELL + ':' + END_CELL).getValues();
  var table = tableSlide.insertTable(sheetValues.length, sheetValues[0].length);

  // Populate the table with spreadsheet data.
  for (var i = 0; i < sheetValues.length; i++) {
    for (var j = 0; j < sheetValues[0].length; j++) {
      table.getCell(i, j).getText().setText(String(sheetValues[i][j]));
    }
  }

  // Add a chart slide and insert the chart on it.
  var chartSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  chartSlide.insertSheetsChart(chart);

  // Return the presentation object for later use.
  return deck;
}

/**
 * Runs a BigQuery query, adds data and a chart to a spreadsheet,
 * and adds the data and chart to a new slide presentation.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  var chart = createColumnChart(spreadsheet);
  var deck = createSlidePresentation(spreadsheet, chart);
  Logger.log('Results slide deck created: %s', deck.getUrl());
}

您还可以在 GitHub 代码库中的 final 文件夹中找到此代码示例。

8. 其他资源

下面提供了更多资源,可帮助您更深入地了解此 Codelab 中介绍的内容,并探索以编程方式访问 Google 开发者工具的其他方式。

此应用的资源

文档

视频

新闻和最新动态

其他 Codelab

入门级

中级

9. 下一步:代码验证

下面列出了可用于增强或扩充此 Codelab 中构建的示例的不同方法。此列表并非详尽无遗,但针对如何进行下一步提供了一些鼓舞人心的想法。

  • 应用 - 不想局限于使用 JavaScript 或 Apps 脚本施加的限制?将此应用移植到使用适用于 Google BigQuery、表格和幻灯片的 REST API 的您喜爱的编程语言。
  • BigQuery - 针对您感兴趣的莎士比亚数据集进行其他查询实验。另一个示例查询可以在原始的 Apps Script BigQuery 示例应用中找到。
  • BigQuery - 使用 BigQuery 的一些其他公共数据集进行实验,找到对您更有意义的一个。
  • BigQuery - 前面我们提到过可以使用莎士比亚的作品或其他公开数据表构建的其他查询。您可以在此网页此 GitHub 代码库上找到它们。
  • 表格 - 在图表库中尝试其他图表类型。
  • 表格和BigQuery - 使用您自己的大型电子表格数据集。2016 年,BigQuery 团队推出了一项功能,可让开发者使用 Google 表格作为数据源。有关详情,请参阅(Google BigQuery 与 Google 云端硬盘集成
  • 幻灯片 - 将其他幻灯片添加到生成的演示文稿中,例如与您的大数据分析相关联的图片或其他资源。请参阅幻灯片内置服务的参考文档。
  • Google Workspace - 通过 Apps 脚本使用其他 Google Workspace 或 Google 内置服务。例如 Gmail、Google 日历、Google 文档、Google 云端硬盘、Google 地图、Google Analytics、YouTube 等,以及其他高级服务。如需了解详情,请转到内置服务和高级服务的参考概览