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

1. 将大数据分析结果转换为幻灯片演示文稿

数据科学家可以使用许多工具来执行大数据分析,但最终分析师仍需向管理层论证结果。纸上或数据库中的大量数字很难向主要利益相关方展示。本中级 Google Apps 脚本 Codelab 将结合 Google WorkspaceGoogle Cloud 控制台这两大 Google 开发者平台,助您自动完成最后一步。

借助 Google Cloud 的开发者工具,您可以进行深入的数据分析。然后,您可以将结果插入电子表格,并根据这些数据生成幻灯片演示文稿。这提供了一种更适合向管理层提供数据的方式。本 Codelab 用到了 Cloud Console 的 BigQuery API(作为 Apps 脚本高级服务),以及适用于 Google 表格Google 幻灯片内置 Apps 脚本服务

设计初衷

此 Codelab 中的示例应用借鉴了以下其他代码示例:

虽然 Slides API Codelab 示例应用也包含 BigQuery 和 Slides,但它与本 Codelab 的示例应用在以下几个方面有所不同:

  • 他们的 Node.js 应用与我们的 Apps 脚本应用。
  • 它们使用 REST API,而我们使用 Apps 脚本服务。
  • 它们使用 Google 云端硬盘,但不使用 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/教程?

出于信息目的阅读,可能会将其转发给技术同事 尽可能完成所有步骤,并尽可能多地尝试练习 无论如何,我都要完成整个 Codelab

您如何评价自己在 Google Workspace 开发者工具和 API 方面的经验?

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

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

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

您如何评价自己在 Cloud 控制台开发者工具和 API 方面的经验水平?

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

3. 概览

现在,您已经了解了本 Codelab 的内容,接下来您将执行以下操作:

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

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

Google Apps 脚本和 BigQuery

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

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

  • 使用基于浏览器的代码编辑器开发脚本,但如果使用 clasp(Apps 脚本的命令行部署工具),也可选择本地开发。
  • 使用专用的 JavaScript 版本编写代码,该版本经过定制,可访问 Google Workspace 以及其他 Google 服务或外部服务(使用 Apps 脚本的 URL FetchJDBC 服务)。
  • 无需编写授权代码,因为 Apps 脚本会为您处理。
  • 无需托管应用,它会直接在 Google 云端服务器上部署和运行。

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

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

内置服务提供高层方法,可用于与用户数据、其他 Google 系统和外部系统进行交互。高级服务本质上是 Google Workspace API 或 Google REST API 的一个轻量级封装容器。高级服务全面覆盖 REST API,通常比内置服务的功能更强大,但需要更复杂的代码实现(不过仍比完整的 REST API 更易于使用)。在使用高级服务之前,还必须先为脚本项目启用这些服务

在可能的情况下,开发者应使用内置服务,因为它们比高级服务更易于使用,并且可以处理更多工作。不过,某些 Google API 并未提供内置服务,此时高级服务可能是唯一选择。例如,Google BigQuery 没有内置服务,但确实存在 BigQuery 服务。BigQuery 服务是一项 Cloud 控制台服务,可让您使用 Google BigQuery API 对海量数据集(例如数 TB 级)执行查询,但仍可在数秒内提供结果。

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

与 BigQuery 不同,Google 表格和 Google 幻灯片都有内置服务。此外,它们还提供高级服务,用于访问仅存在于相应 API 中的功能。在开始编写代码之前,请先查看内置的表格幻灯片服务的文档。请注意,我们还提供了Google 表格Google 幻灯片的高级服务文档。

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 的后续部分会使用单独的项目 ID 字段。)

接下来,您需要将 Apps 脚本项目连接到 Cloud 控制台项目。

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

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

  1. 为此,请切换到 Cloud 控制台,然后依次点击 API 和服务 > 信息中心。(确保您仍位于在第 3 步中创建的项目中。)
  2. 点击启用 API 和服务
  3. 搜索“big query”,选择 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 控制台项目 ID。变量下的 if 语句用于防止应用在没有项目 ID 的情况下继续运行。

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

afe500ad43f8cdf8.png

任务 1 摘要

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

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

如果您有兴趣了解如何使用莎士比亚的作品或其他公共数据表构建其他查询,请访问如何查询 BigQuery 示例表此 GitHub 代码库

您还可以在 Cloud 控制台中使用 BigQuery 页面运行查询,然后再在 Apps 脚本中运行这些查询。如需查找该界面,请依次点击“菜单”图标 f5fbd278915eb7aa.pngBigQuery 界面 > SQL 工作区直接链接)。例如,以下是我们的查询在 BigQuery 图形界面中的显示方式:

BigQueryUI

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

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

  1. 在 Apps 脚本编辑器中,将 createColumnChart() 函数添加到 bq-sheets-slides.js 中的 runQuery() 之后。该代码会获取工作表,并请求生成包含所有数据的柱状图。数据范围从单元格 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,并点击运行。代码运行完毕后,您会在 Google 云端硬盘中获得另一个电子表格,但这次,表格中数据的旁边会显示一个图表:

包含图表的工作表

6. 任务 3:将结果数据放入演示文稿中

本 Codelab 的最后一部分将会创建一份 Google 幻灯片演示文稿,在标题幻灯片上添加标题和副标题,然后为数据单元格和图表构建幻灯片。

  1. 在 Apps 脚本编辑器中,将 createSlidePresentation() 函数添加到 bq-sheets-slides.js 中的 createColumnChart() 之后。幻灯片演示的所有工作都在此函数中完成。我们先创建一份演示文稿,然后为默认的标题幻灯片添加标题和副标题。
/**
 * 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.png

5549f0ea81514360.png

7. 总结

恭喜!您已创建了一个同时使用 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、Google 表格和 Google 幻灯片的 REST API。
  • BigQuery - 针对您感兴趣的莎士比亚数据集尝试不同的查询。您还可以在原始的 Apps 脚本 BigQuery 示例应用中找到另一个示例查询。
  • BigQuery - 尝试使用 BigQuery 的其他一些公共数据集,找到对您更有意义的数据集。
  • BigQuery - 前面我们提到过,您可以使用莎士比亚的作品或其他公共数据表构建其他查询。您可以在此网页此 GitHub 代码库中找到这些代码。
  • Google 表格 - 在图表库中尝试其他图表类型。
  • Google 表格和 BigQuery - 使用您自己的大型电子表格数据集。2016 年,BigQuery 团队推出了一项功能,允许开发者使用 Google 表格作为数据源。如需了解详情,请参阅 Google BigQuery 与 Google 云端硬盘集成
  • 幻灯片 - 向生成的演示文稿添加其他幻灯片,例如与大数据分析相关的图片或其他素材资源。以下是 Slides 内置服务的参考文档。
  • Google Workspace - 通过 Apps 脚本使用其他 Google Workspace 或 Google 预装服务。例如 Gmail、日历、Google 文档、云端硬盘、Google 地图、Google Analytics、YouTube 等,以及其他高级服务。如需了解详情,请参阅内置服务和高级服务的参考概览