16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GASを用いて google フォームから google ドキュメントやスプレッドシートを経由してPDFファイルを送付する方法

Last updated at Posted at 2020-05-18

概要

google Apps Script (GAS) を用いて,google form でデータを収集し,google document and/or google spread sheet を経由し,PDFファイルを生成し,メールを送信するシステムを作成する簡単な例を紹介します。

状況設定はこちらになります.

gas_gaiyou.png

ユーザーから google form で情報を収集し,google form のバインドされたGAS(コンテナバインドと呼ぶ)を用いて,goole document and/or google spread sheet のテンプレートを更新してユーザー向けの文書を生成し,それをPDF化してユーザーにメールで通知する,というシステムになります.

ここでは例として,google document と spread sheet の両方を使いますが,それぞれ独立したプログラムと設定なので,一つだけでも動きます.

基本事項 GASを用いたメール転送

GASを用いた一番簡単で便利な使い方である,メールを転送する基本の型をまずは知っておこう.一番よくある例はフォームの情報を,メールで転送する,というパターンであろう.

FormApp.getActiveForm();
function form2email(e) {
        
  var email = ""; // default emails to know if it fails
  email = e.response.getRespondentEmail(); // get email from method or you can change anything you like. 
  var results = ""; // 全結果  
    
  var itemResponses = e.response.getItemResponses(); // get data from the form
  // store results and several keys
  var x = ""; // contents
  var y = ""; // results  

  itemResponses.forEach(function(itemResponse){
  x = itemResponse.getItem().getTitle()
  y = itemResponse.getResponse()  
    results += '' + x + '\n'
    results += y + '\n\n'
  });
      
  // create email 
  var subject = '[受領通知]';
  var emailbody = 'みなさま\n\n\n';
  emailbody += '受領したことを通知致します.\n\n';
  emailbody += '-------------------------------------------------------------\n\n';  
  emailbody += results
  var sender_email = "syamada@univ.ac.jp"; 
  var objArgs = {from:sender_email};
  GmailApp.sendEmail(email, subject, emailbody, objArgs);
}

この例では,メールの送信先は email という変数にformから取得したメールアドレスを設定している.これを,

var email = 'syamada@univ.ac.jp,tanaka@univ.ac.jp';

のように,任意のメールアドレス(gmailでなくてもよい)を指定して転送することができる.

Googleフォームに「控え」の送信機能が備わっていた にあるように,google form の控えを送信するだけでれば,Google form の 「回答のコピーを送信」というチェックボックスをONするだけで実行できる.

単純にメールを送るだけであれば,GASでのメール送信についてまとめてみる が参考になりました.

この記事では,単純にメールを送るだけではなくて,あらかじめ用意しておいた google document or spreadsheet のテンプレートを書き換え、それを pdf 化してメールで送る,という例を紹介します.

google form の設定

google form から,「メールアドレス」,「氏名」,「報告文」の3つの情報を集めるとします.「メールアドレス」は google form の自動収集機能を用いた場合は,

  email = e.response.getRespondentEmail(); // get email from method 

として,getRespondentEmailを用いて,メールアドレスを収集します.

その次に,このformから「スクリプトエディタ」を開きます.こうすると,自動的にこのformにバインドされたGASの設定になります.

gas_make.png

書類テンプレートの作成

文書のテンプレートを作成します.
テンプレートには「input1」「input2」「input3」の3つのプレースホルダーが記述されているとします.これらを,GASの中で定義された「fname」「formattedDate」「houkoku」にそれぞれ変換し,新しい文書を作成し,PDF化してメール送信する,という作戦です.

gas_template.png

固有IDの取得

テンプレートのファイルの固有IDを取得します.https 以下の docs.google.com/document/d/ID/edit の ID がこのファイルの固有IDとなるので,これをGASの中で使います.

(同様に,作業場所の固有ID も drive.google.com/drive/folders/ID にあるので,これもGASの中で使います. は古い記述。targetFolderIdの指定なくても動きます。2020.11.13追記)

GAS の設定

google ドキュメントから pdf生成とメール送信

google form に新規入力があったときに,form2doc.gs が動作し,google document の
テンプレートを更新して,メール送信します.

form2doc.gs
FormApp.getActiveForm();

// var targetFolderId = 'IDIDIDIDIDIDIDIDIDIDIDIDIDIDIDIDI' <== 更新ください

function form2doc(e) {
    
  // define the folder of your work
  var folder = DriveApp.getRootFolder();
  var folderFiles = folder.getFiles(); 
  
  // set the template file ID 
  var fileId = "FIFIFIFIFIFIFIFIFIFIFIFIFIFIFIFIF"  <== 更新ください
    
  var fname = ""; // name
  var houkoku = ""; // houkoku
  var email = ""; // default emails to know if it fails
  email = e.response.getRespondentEmail(); // get email from method 
  var results = ""; // 全結果  
    
  var itemResponses = e.response.getItemResponses(); // get data from the form
  // store results and several keys
  var x = ""; // contents
  var y = ""; // results  
  itemResponses.forEach(function(itemResponse){
  x = itemResponse.getItem().getTitle()
  y = itemResponse.getResponse()  
    results += '' + x + '\n'
    results += y + '\n\n'
    if(x == "氏名"){
      fname = y;}
    else if (x == "報告文"){
        houkoku = y;}
    else if (x == "メールアドレス"){
        email = y;}
  });

  
  // copy and update documents
  var date = new Date(); //ファイル名の日付部分作成
  var formattedDate = Utilities.formatDate(date, "JST",  "yyyy'年'MM'月'dd'日'");
  //コピー元のファイルを開く
  var file = DriveApp.getFileById(fileId);
  //コピーを作成,作成したコピーを参照
  var newFile = file.makeCopy(fname + ".doc");  
  //コピーしたファイルをすぐに更新するため,IDを取得
  var newid = newFile.getId();
  var doc = DocumentApp.openById(newid)
  var docbody = doc.getBody(); // documents の本体を取得  
  docbody.replaceText('input1',fname);  
  docbody.replaceText('input2',formattedDate);       
  docbody.replaceText('input3',houkoku);
  doc.saveAndClose(); // 強制的にファイルを更新する.
  // reopen the file
//  var newid = newFile.getId();  
  var document = DriveApp.getFileById(newid)  
  var link = 'https://docs.google.com/document/d/'+newid
  results += 'Your document is created at ' + link;
    
  // create email 
  var subject = '[受領通知]';
  var emailbody = fname + '\n\n\n';
  emailbody += '受領したことを通知致します.\n\n';
  emailbody += '-------------------------------------------------------------\n\n';  
  emailbody += results
  
  Logger.log(email);    
  Logger.log(results);  
  Logger.log(link);

  // create pdf from the google document
  // DriveApp.getFolderById(targetFolderId).createFile(document.getAs(MimeType.PDF).setName(fname +  ".pdf")); // convert pdf
  var pdf = document.getAs(MimeType.PDF).setName(fname + ".pdf"); // get pdf 

  // set sharing for the google document 
  var access;
  var permission;
  access = DriveApp.Access.DOMAIN_WITH_LINK;
  permission = DriveApp.Permission.EDIT;
  document.setSharing(access, permission);
//  document.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
//  document.addEditor(email);
  // send email with pdf 
  var sender_email = "syamada@univ.ac.jp"; 
  var objArgs = {from:sender_email, attachments:pdf};
  GmailApp.sendEmail(email, subject, emailbody, objArgs);
}

google スプレッドシートから pdf生成とメール送信

google form に新規入力があったときに,form2sp.gs が動作し,google spreadsheet の
テンプレートを更新して,メール送信します.

form2sp.gs
FormApp.getActiveForm();

// var targetFolderId = 'IDIDIDIDIDIDIDIDIDIDIDIDIDIDIDIDI'  <== 更新ください

function form2sp(e) {
    
  // define the folder of your work
  var folder = DriveApp.getRootFolder();
  var folderFiles = folder.getFiles(); 
  
  // set the template file ID 
  var fileId = "FIFIFIFIFIFIFIFIFIFIFIFIFIFIFIFIF"   <== 更新ください
    
  var fname = ""; // name
  var houkoku = ""; // houkoku
  var email = ""; // default emails to know if it fails
  email = e.response.getRespondentEmail(); // get email from method 
  var results = ""; // 全結果  
    
  var itemResponses = e.response.getItemResponses(); // get data from the form
  // store results and several keys
  var x = ""; // contents
  var y = ""; // results  
  itemResponses.forEach(function(itemResponse){
  x = itemResponse.getItem().getTitle()
  y = itemResponse.getResponse()  
    results += '' + x + '\n'
    results += y + '\n\n'
    if(x == "氏名"){
      fname = y;}
    else if (x == "報告文"){
        houkoku = y;}
    else if (x == "メールアドレス"){
        email = y;}
  });

  
  // copy and update documents
  var date = new Date(); //ファイル名の日付部分作成
  var formattedDate = Utilities.formatDate(date, "JST",  "yyyy'年'MM'月'dd'日'");
  //コピー元のファイルを開く
  var file = DriveApp.getFileById(fileId);
  //コピーを作成,作成したコピーを参照
  var newFile = file.makeCopy(fname);  
  //コピーしたファイルをすぐに更新するため,IDを取得
  var newid = newFile.getId();
  var spreadsheet = SpreadsheetApp.openById(newid)
  // シートを取得する
  var sheet = spreadsheet.getSheets()[0] ;
  var textFinder = sheet.createTextFinder('input1');
  textFinder.replaceAllWith(fname);
  
  textFinder = sheet.createTextFinder('input2');  
  textFinder.replaceAllWith(formattedDate);

  textFinder = sheet.createTextFinder('input3');  
  textFinder.replaceAllWith(houkoku);
  
  SpreadsheetApp.flush();  // 変更内容を即反映
  // reopen the file
//  var newid = newFile.getId();  
  var document = DriveApp.getFileById(newid)  
  var link = 'https://docs.google.com/spreadsheets/d/'+newid
  results += 'Your spreadsheet is created at ' + link;
    
  // create email 
  var subject = '[受領通知]';
  var emailbody = fname + '\n\n\n';
  emailbody += '受領したことを通知致します.\n\n';
  emailbody += '-------------------------------------------------------------\n\n';  
  emailbody += results
  
  Logger.log(email);    
  Logger.log(results);  
  Logger.log(link);

  // create pdf from the google document
  // DriveApp.getFolderById(targetFolderId).createFile(document.getAs(MimeType.PDF).setName(fname +  "_sp.pdf")); // convert pdf
  var pdf = document.getAs(MimeType.PDF).setName(fname + "_sp.pdf"); // get pdf 

  // set sharing for the google document 
  var access;
  var permission;
  access = DriveApp.Access.DOMAIN_WITH_LINK;
  permission = DriveApp.Permission.EDIT;
  document.setSharing(access, permission);
//  document.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
//  document.addEditor(email);
  // send email with pdf 
  var sender_email = "syamada@univ.ac.jp"; 
  var objArgs = {from:sender_email, attachments:pdf};
  GmailApp.sendEmail(email, subject, emailbody, objArgs);
}

トリガーの設定

「編集 」==> 「現在のプロジェクトのトリガー」を押して,それぞれの関数に対して,「フォーム送信時」のイベントとして登録する.

gas_trigger.png

基本設定は以上になります.

技術的な補足

GAS関係

文字列変換

文字の変換方法は google ドキュメントとスプレッドシートで異なるので,注意が必要です.

google document の場合は,

  var docbody = doc.getBody(); // documents の本体を取得  
  docbody.replaceText('input1',fname);  
  docbody.replaceText('input2',formattedDate);       
  docbody.replaceText('input3',houkoku);
  doc.saveAndClose(); // 強制的にファイルを更新する.

のように,replaceText で変換して,強制的にファイル更新する.強制的に更新するのは,変更前のものがPDF化されるのを回避するためです.

google spreadsheet の場合は,

  // シートを取得する
  var sheet = spreadsheet.getSheets()[0] ;
  var textFinder = sheet.createTextFinder('input1');
  textFinder.replaceAllWith(fname);
  
  textFinder = sheet.createTextFinder('input2');  
  textFinder.replaceAllWith(formattedDate);

  textFinder = sheet.createTextFinder('input3');  
  textFinder.replaceAllWith(houkoku);

のように,sheet を取得して,createTextFinder で検索して,replaceAllWith で変換します.

ファイルのアクセス権限の設定

更新したユーザ用のファイルのアクセス権限は次のようにして設定しています.

  // set sharing for the google document 
  var access;
  var permission;
  access = DriveApp.Access.DOMAIN_WITH_LINK;
  permission = DriveApp.Permission.EDIT;
  document.setSharing(access, permission);
//  document.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
//  document.addEditor(email);

この例はドメインでの設定になります.他の例は,DriveApp.Accessを参照ください.

もし個人のメールアドレスごとに設定したい場合は,addEditor 関数の引数にメールアドレスを入れます.

pdf変換

PDFへの変換は,MineType.PDFを指定して,createFile を実行するだけでよい.

var document = DriveApp.getFileById(newid)   
DriveApp.getFolderById(targetFolderId).createFile(document.getAs(MimeType.PDF).setName(fname +  "_sp.pdf")); // convert pdf

とするだけでよい.書き方はgoogle document でも spreadsheet でも変わらない.その理由は,Blobという概念があるらしく,
GAS の Blob とファイル変換まとめ が参考になりました.

ただし,google spread sheet の場合は,グリッド線を消しておかないと,pdf にしたときにセルの線が出てしまう.

スクリーンショット 2020-05-18 13.12.56.png

メールの送信方法

GmailApp.sendEmail を使います.

  var sender_email = "syamada@rikkyo.ac.jp"; 
  var objArgs = {from:sender_email, attachments:pdf};
  GmailApp.sendEmail(email, subject, emailbody, objArgs);

sender_email はなくてもよいですが,エイリアスを張っているアドレスから送りたい場合に使います.PDFを添付して,emailbodyというテキストを subject というタイトルで email 宛に送信します.


[編集編集後記]

google の G Suite を用いた環境で使っていますので,別環境で動作が違う場合はすいません.

  • 2020.5.18, first draft, 簡単なフォームで作成.(自分がGAS初心者)

関連ページ

16
18
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?