D14 - 如何用 Apps Script 自动化地创造与客制 Google Docs?(一) 以 NDA 为例的大架构与简单复制

今天的目标

现在几乎每天都会打开 Google Doc,但有时就是会有很多类似的文件,其实只要调整一点点东西,可能是薪资单、要交的报告、给客户的企划书(X)。总之,我们不时会需要「调整 Google Doc 中的一点点部分」,请问我们能怎麽做?

今天的主题是,每次要跟不同的厂商与单位签 NDA,如果比较一般的合作,那就可以拿范本,但如果是比较深度的合作,老板总会想要搞一点客制,那要怎麽简单将这件事自动化呢?

  1. 要如何自动依照范本创造并微调 Google 文件(Google Docs)?

今天只有一个问题,那我们就开始吧!


Q1. 要如何自动依照范本创造并微调 Google 文件(Docs)?

Step 1 开启 Google Sheet,并串起 GAS

今天勤劳一点先把影片录起,总之先开一个 Google Sheet 的并串接 GAS。

一样在最一开始执行时会有「需要验证」出现,让我借用一下 D2 的影片。

Step 2 设定要要填入 Google Docs 的参数

关於创造文件,我们可以选择复制范本(像是 D11 复制并客制你的 Google Form),或是创造新的文件(像是 D12 幅度客制你的 Google Form);这次我会针对复制「新文件」来做介绍,也就是 D12 的那种版本。那我们要长出什麽样子呢?这边先给大家看我们的参数们。

这边我们简单设定了三个参数 Name(文件的名字)、Header 和 Footer。

为什麽选这些参数呢?因为每一份 Google Doc 其实都有这样的架构。分别是文章内部的 Header、Body、Footer;以及额外的 Url、Name 和 Id。来让我们看一下一份 Google Docs 的架构——

今天我们会主要讲结构的 HeaderFooterBody 怎麽抓,待因为抓入每一个结构,内步的调整就会包含很多客制化的部分,我会於明天另外以完整的篇幅介绍。

Step 3 读取 Sheet 内的资料

那一样我们要先读取表单内的资料,透过老朋友 readSheetData() 来完成。这边不懂可以参照 D11 和 D4。

function readSheetData(){
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getActiveSheet();
  let start_row = 2;
  let start_col = 1;
  let numRows = sheet.getLastRow() - start_row +1;
  let numCols = sheet.getLastColumn() - start_col +1;;
  let values = sheet.getRange(start_row,start_col,numRows,numCols).getValues();
  Logger.log(values);
  return values;
}

让我们来看一下跑起来的画面——

Step 4 用 DocumentApp.create() 来创造文件

好,那接着就要创造文件了。这边我们会用到两个功能,分别是 moveFile()DocumentApp.create()

首先 moveFile() 的执行细节在 D12 有讲到,我们就快速看过程序码。

function moveFile(fileId, destinationFolderId) {
  let destinationFolder = DriveApp.getFolderById(destinationFolderId);
  DriveApp.getFileById(fileId).moveTo(destinationFolder);
}

那新的 function 是 DocumentApp.create() 虽说是新的,但其实就是简单地创造一个新的文件档案。实际执行时,要抓出你要放在哪一个 folder,把 "your_id_here 换掉。

var target_folder_ID= "your_id_here";

function createDoc(file_name) {
  let new_doc = DocumentApp.create(file_name);
  let doc_id = new_doc.getId();
  moveFile(doc_id, target_folder_ID)
}

我们来看一下跑起来长怎麽样——

Step 5 针对结构写入内容(文字)

好,那我们现在已经能创造文件,现在要来看怎麽样「写入内容」。我们来看看程序码先——

function createDoc() {
  let new_doc = DocumentApp.create('D14 practice');
  let doc_id = new_doc.getId();
  moveFile(doc_id, target_folder_ID)
  let header = new_doc.addHeader();
  let footer = new_doc.addFooter();
  new_doc.setName("Hi, Amy")
  header.setText("Amy's NDA");
  footer.setText("2021/09/14");
}

比较值得一提的是,在 Google Doc 中,「写入内容」都是要——

先把结构叫出来,再针对结构进行调整
就是下图这样,都是要先叫出 Object。

像是其中这段, header 是结构,再用 setText() 设定文字。

  let header = new_doc.addHeader();
  header.setText("Amy's NDA");

跑起来长这样——

好,那看来有...

  1. setName 改到名称
  2. header.setText 有改到 header
  3. footer.setText 有改到 footer

接着,就是大量制作了!

Step 6 针对每个参数创造文件

这边我们先将原本的 createDoc() 改为可以输入参数,分别是我们最一开始资料的 nameheader_textfooter_text。换句话说,如果我们想创造和 Step 5 一样的文件,就要改成输入 createDoc("Hi! Amy", "Amy's NDA", "20210914") 即可。

function createDoc(name, header_text, footer_text) {
  let new_doc = DocumentApp.create('D14 practice');
  let doc_id = new_doc.getId();
  moveFile(doc_id, target_folder_ID)
  let header = new_doc.addHeader();
  let footer = new_doc.addFooter();
  new_doc.setName(name)
  header.setText(header_text);
  footer.setText(footer_text);
}


function createDocsFromSheet(){
  let data = readSheetData();
  for (row_data of data){
    let name = row_data[0];
    let header_text = row_data[1];
    let footer_text = row_data[2];
    Logger.log(name+ " "+ header_text + " "+ footer_text);
    createDoc(name, header_text, footer_text);
  }
}

我们另外再创造一个 createDocsFromSheet() 把 Sheet 里面的资料解构,并输入上面那个 createDoc() 当中。这边要注意的是,如

最後跑起来长这样——


好,那今天就是我们的 D14。提醒的是,创造文件有 Quota 限制——每天不超过 250 件。明天我会介绍当有很多文件要产出时,内部细节到底要怎麽写。

如果还有问题,透过留言之外,也可以到 Facebook Group,想开很久这次铁人赛才真的开起来哈哈哈,欢迎来当 Founding Member。如果不想错过可以订阅按赞小铃铛(?),也欢迎留言跟我说你还想知道什麽做法/主题。我们明天见。


<<:  成员 2 人:别公平、别相爱、别把友情当应该

>>:  从 IT 技术面细说 Search Console 的 27 组数字 KPI (14) :检索统计

DAY08随机森林演算法(续6)

昨天,我们已建立完决策树,那今天,我打算带入资料去看他分类结果: 建立决策树的使用模型: #用树来预...

DAY7:Kaggle-San Francisco Crime Classification(下)

资料视觉化 这边我们会用到seaborn来做一下简单的资料视觉化。 import seaborn ...

[13th][Day19] http request header(上)

golang 服务 常用於 http server/ http client 来看看一张厉害的图儿 ...

Day 23 (Js)

1.is 开头的大部分回传值是booling ex:isNaN() https://www.w3sc...

Day 25-制作购物车之设计购物车画面

设计的部分就不多做分析,主要呈现实作成果。 因为太长了,所以分一点过来。 以下内容有参考教学影片,底...