GoogleAppsScript

Google Apps Script で指定したシートをPDF化するスクリプト

はじめに

Google Apps Scriptはかなり色々なことができ、指定したシートをPDF化するこももちろん可能です。Googleスプレッドシートで請求書や納品書などのテンプレートを作成しておいて、データを他のシートから取得して埋め込んでPDF化などすると便利です。ここでは、指定したスプレッドシートのPDF化を行うスクリプトをメモします。

なお、以降のコードは以下のサイト様のものを参考にさせて頂いてます。

Convert and Email Google Spreadsheets as PDF Files | CTRLQ


できるようになること

以下のようなスプレッドシートがあるとします。なお、このスプレッドシートは例として作成したもので請求書であることに意味はなくなんでもOKです。中身は全部手動で作成しておいてもいいですし、何かしらのスクリプトで自動でデータを挿入して作成しておいもOKです。
template_sheet

これをPDF化して、指定したフォルダ上に保存できるようになります。
pdf_folder

もちろんPDF化したファイルの中身はスプレッドシートの内容そのままです。
example-user

なお、以降では、保存するPDFのファイル名として、お名前(上記の場合、Example User)とPDF作成時のタイムスタンプを使用します。

スクリプト

以下がスクリプトになります。他の説明は下に載せます。

function myFunction(){

  // PDFの保存先となるフォルダID 確認方法は後述
  var folderid = "*********";
  
  // マイドライブ直下に保存したい場合は以下
  // var root= DriveApp.getRootFolder();
  // var folderid = root.getId();
  
  /////////////////////////////////////////////  
  // 現在開いているスプレッドシートをPDF化したい場合//
  ////////////////////////////////////////////
  // 現在開いているスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  // 現在開いているスプレッドシートのIDを取得
  var ssid = ss.getId();
  
  // 現在開いているスプレッドシートのシートIDを取得
  var sheetid = ss.getActiveSheet().getSheetId();
  // getActiveSheetの後の()を忘れると、TypeError: オブジェクト function getActiveSheet() {/* */} で関数 getSheetId が見つかりません。

  // ファイル名に使用する名前を取得
  var customer_name = ss.getRange("C15").getValue();
  // ここで例として使用しているスプレッドシートのC15に顧客の名前が入っているため、それをファイル名用に取得しているだけです。

  // ファイル名に使用するタイムスタンプを取得
  var timestamp = getTimestamp();
  
  // PDF作成関数
  createPDF( folderid, ssid, sheetid, customer_name + "_" + timestamp );
  
}

// PDF作成関数 引数は(folderid:保存先フォルダID, ssid:PDF化するスプレッドシートID, sheetid:PDF化するシートID, filename:PDFの名前)
function createPDF(folderid, ssid, sheetid, filename){

  // PDFファイルの保存先となるフォルダをフォルダIDで指定
  var folder = DriveApp.getFolderById(folderid);

  // スプレッドシートをPDFにエクスポートするためのURL。このURLに色々なオプションを付けてPDFを作成
  var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid);

  // PDF作成のオプションを指定
  var opts = {
    exportFormat: "pdf",    // ファイル形式の指定 pdf / csv / xls / xlsx
    format:       "pdf",    // ファイル形式の指定 pdf / csv / xls / xlsx
    size:         "A4",     // 用紙サイズの指定 legal / letter / A4
    portrait:     "true",   // true → 縦向き、false → 横向き
    fitw:         "true",   // 幅を用紙に合わせるか
    sheetnames:   "false",  // シート名をPDF上部に表示するか
    printtitle:   "false",  // スプレッドシート名をPDF上部に表示するか
    pagenumbers:  "false",  // ページ番号の有無
    gridlines:    "false",  // グリッドラインの表示有無
    fzr:          "false",  // 固定行の表示有無
    gid:          sheetid   // シートIDを指定 sheetidは引数で取得
  };
  
  var url_ext = [];
  
  // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納
  for( optName in opts ){
    url_ext.push( optName + "=" + opts[optName] );
  }

  // url_extの各要素を「&」で繋げる
  var options = url_ext.join("&");

  // optionsは以下のように作成しても同じです。
  // var ptions = 'exportFormat=pdf&format=pdf'
  // + '&size=A4'                       
  // + '&portrait=true'                    
  // + '&sheetnames=false&printtitle=false' 
  // + '&pagenumbers=false&gridlines=false' 
  // + '&fzr=false'                         
  // + '&gid=' + sheetid;

  // API使用のためのOAuth認証
  var token = ScriptApp.getOAuthToken();

    // PDF作成
    var response = UrlFetchApp.fetch(url + options, {
      headers: {
        'Authorization': 'Bearer ' +  token
      }
    });

    // 
    var blob = response.getBlob().setName(filename + '.pdf');

  //}

  // PDFを指定したフォルダに保存
  folder.createFile(blob);

}

 // タイムスタンプを返す関数
  function getTimestamp () {
    var now = new Date();
    var year = now.getYear();
    var month = now.getMonth() + 1;
    var day = now.getDate();
    var hour = now.getHours();
    var min = now.getMinutes();
    // var sec = now.getSeconds();
    
    return year + "_" + month + "_" + day + "_" + hour + min;
 }

// スプレッドシートのメニューからPDF作成用の関数を実行出来るように、「スクリプト」というメニューを追加。
function onOpen() {
    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var entries = [       
        {
            name : "Create PDF",
            functionName : "myFunction"
        }
        ];
    sheet.addMenu("スクリプト", entries);
};


コード説明

上記のコメントだけでは不足している部分のみ載せます。

PDFの保存先となるフォルダを指定

以下の部分で指定しています。

  // PDFの保存先となるフォルダID 確認方法は後述
  var folderid = "*********";



Googleドライブ上では、フォルダやスプレッドシートにはそれぞれ一意のIDが設定されます。これらIDを指定してファイルの保存や処理を行う対象を指定できます。ここでフォルダIDの確認方法は次の通りです。

フォルダIDの確認方法

Googleドライブをブラウザ上で開き、以下のようにURLの中の*********がフォルダIDに該当します。

https://drive.google.com/drive/folders/*********


すなわち以下のようにフォルダを開いた状態でURLを確認した時に赤線部分が該当します。
folder_id

PDF化するスプレッドシートとシートの指定

上記のコードのように、単純に現在開いているスプレッドシートのシートをPDF化する場合は以下のようになります。
スプレッドシートのIDやシートのIDを事前に調べる必要はないです。


  /////////////////////////////////////////////  
  // 現在開いているスプレッドシートをPDF化したい場合//
  ////////////////////////////////////////////
  // 現在開いているスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  // 現在開いているスプレッドシートのIDを取得
  var ssid = ss.getId();
  
  // 現在開いているスプレッドシートのシートIDを取得
  var sheetid = ss.getActiveSheet().getSheetId();
  // getActiveSheetの後の()を忘れると、TypeError: オブジェクト function getActiveSheet() {/* */} で関数 getSheetId が見つかりません。
  



続いて現在開いているスプレッドシートとは別のスプレッドシートのシートを指定してPDF化したい場合は、以下のようになります。以下のコードでは事前にスプレッドシートとシートのそれぞれのIDを調べておく必要があります。


  /////////////////////////////////////////////  
  // IDで指定したスプレッドシートをPDF化したい場合//
  ////////////////////////////////////////////
  // PDF化したいスプレッドシートのID
  var ssid = "abcdefghijklmnopqrstuvwxyz1234567890";// スプレッドシートのID abcdefghijklmnopqrstu123

  // シートID(gid)を指定
  var sheetid = "987654321";

  // 指定したスプレッドシートを開く
  var ss = SpreadsheetApp.openById(ssid);



スプレッドシート、シートの各IDの確認方法は次の通りです。

スプレッドシートID、シートIDの確認方法

同じくIDを調べたいスプレッドシートをブラウザで開き、以下のようにURLの中のabcdefghijklmnopqrstuvwxyz1234567890のような英数字を含む部分がスプレッドシートのIDで、gid=の後に続く987654321がシートのIDです。なのでシートIDはもちろんシート毎に異なります。

https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz1234567890/edit#gid=987654321


すなわち以下のように赤線部分が該当します。
spreadsheet_id

PDF作成関数について

Googleスプレッドシートは、開いている時のURLにexport?format=pdfのようにパラメータを渡すことでPDFやCSV形式でダウンロードすることが可能です。例えば、スプレッドシートIDがabcdefghijklmnopqrstuvwxyz1234567890で、シートIDが987654321の場合に以下のURLにブラウザからアクセスすると、そのシートをPDF形式でダウンロード可能です。

https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz1234567890/export?format=pdf&gid=987654321

すなわち、上記のスプレッドシートIDとシートIDを任意のものに置換して利用すれば指定したスプレッドシートのシートをPDF化することが可能です。
なお、上記はフォーマットをPDFに指定しているだけですが、この他にも用紙サイズや縦横での出力などをオプションで指定可能です。これを利用してPDF作成を行う関数になります。

上に載せたcreatePDFという名前のPDF作成用の関数では、以下を引数として取ります。

  • folderid : 保存先フォルダID
  • ssid : PDF化するスプレッドシートID
  • sheetid : PDF化するシートID
  • filename : 作成したPDFにつけるファイル名


そして以下の部分でPDF作成時のオプションを指定しています。

 // PDF作成のオプションを指定
  var opts = {
    exportFormat: "pdf",    // ファイル形式の指定 pdf / csv / xls / xlsx
    format:       "pdf",    // ファイル形式の指定 pdf / csv / xls / xlsx
    size:         "A4",     // 用紙サイズの指定 legal / letter / A4
    portrait:     "true",   // true → 縦向き、false → 横向き
    fitw:         "true",   // 幅を用紙に合わせるか
    sheetnames:   "false",  // シート名をPDF上部に表示するか
    printtitle:   "false",  // スプレッドシート名をPDF上部に表示するか
    pagenumbers:  "false",  // ページ番号の有無
    gridlines:    "false",  // グリッドラインの表示有無
    fzr:          "false",  // 固定行の表示有無
    gid:          sheetid   // シートIDを指定
  };
  
  var url_ext = [];
  
  // 上記のoptsのオプション名と値を「=」で繋げて配列に格納
  for( optName in opts ){
    url_ext.push( optName + "=" + opts[optName] );
  }

  // url_extの各要素を「&」で繋げる
  var options = url_ext.join("&");

上記のurl_extは単純にoptsの中身である各項目と値を=で繋げているだけです。例えば、exportFormatと対応する値であるpdf=で繋げて、exportFormat=pdfという文字列を作成してurl_ext配列に格納しています。そしてそれを各項目に繰り返しています。
つまりurl_extは以下のような配列になっています。

url_ext = ["exportFormat=pdf", "format=pdf", "size=A4", ... , "fzr=false", "gid=sheetid"]


そして後はurl_extの各要素を今度は&で繋げます。そして最終的にoptionsは以下のようになります。

options = 'exportFormat=pdf&format=pdf&size=A4&portrait=true&fitw=true&sheetnames=false&printtitle=false&pagenumbers=false&gridlines=false&fzr=false&gid=sheetid';


つまりここでは単に以下のようURLを作成しているだけになります。

https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz1234567890/export?exportFormat=pdf&format=pdf&size=A4&portrait=true&fitw=true&sheetnames=false&printtitle=false&pagenumbers=false&gridlines=false&fzr=false&gid=987654321



なので最初からoptionsを上記のようにオプションを並べてしまっても同じです。ここでは、見やすさのために上記のように=&で繋げる処理をしているだけになります。

そして後は作成したURLによって生成されるPDFのデータをUrlFetchApp.fetchで取得して、それをblobという変数に格納、最後にGoogleドライブのフォルダIDで指定したフォルダに保存しています。blobというのは、Google Apps Script上で使用するデータ形式で大体このblob形式でデータを保存しておいて、後々これを色々なデータ形式で出力するようです。まだまだ理解が不足しているのでそのうち詳細を確認して載せます。

動作確認

動作確認のために、スクリプトエディタのメニューからスクリプトを実行してももちろんOKです。実行すると指定したフォルダにPDFが作成されるはずです。初めて実行する場合は許可を求められるのでOKしてください。なお、スプレッドシートでは、メニューの中に独自のメニューを追加することができます。具体的には以下のようにメニューに任意の名前で追加できます。以下の「スクリプト」→「Create PDF」は上に載せたmyFunctionに結びつけてあります。
add_menu


上記のようにメニューを追加するには、以下のようにGoogle Apps Script側で用意されているonOpenという関数を利用します。

function onOpen() {
    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var entries = [       
        {
            name : "Create PDF",
            functionName : "myFunction"
        }
        ];
    sheet.addMenu("スクリプト", entries);
};


このonOpen関数は、スプレッドシートが開かれた時点で実行される関数です。この関数内に、現在開いているスプレッドシートのメニューに「スクリプト」という項目を追加して、その中に「Create PDF」という項目を追加しています。そしてこの「Create PDF」は上で載せたmyFunctionに結びついているので、メニューからmyFunctionを実行できるようになります。動作確認用だけでなく、スクリプトなどを知らない方に利用してもらう際にも便利です。

なお、onOpenなどの用意されている関数は以下の公式ページ(英語)に載っています。

Simple Triggers | Google Apps Script


メニューを複数追加したい場合は、以下のようにentriesの中身に追記すればOKです。

function onOpen() {
    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var entries = [       
        {
            name : "Create PDF",
            functionName : "myFunction"
        },
        {
            name : "New Function 2",
            functionName : "myFunction2"
        }
        ];
    sheet.addMenu("スクリプト", entries);
};


 ——-2017/11/30 追記
スクリプトを初めて実行する場合は承認作業が必要なりました。この承認作業手順についてはGoogle Apps Scriptの初回実行に必要となる承認手順にまとめましたので必要な方はご参照ください。

まとめ

ここで載せたPDF作成用の関数を作っておけば、あとは好きなタイミングで呼び出して色々と応用できると思います。for文で複数のPDFやCSVファイルを一度に作成することも可能です。また、特定のシートからデータを取得して指定したスプレッドシートに挿入し、その上でPDF化けるなどももちろん可能です。特定のデータを指定したシート間でやりとりするスクリプトについてはまた載せたいと思います。

SPONSORED LINK

4 thoughts on “Google Apps Script で指定したシートをPDF化するスクリプト

  1. この記事の本質とは少し離れますが、

    getTimestampは下記のように1行で書けます^^

    “`
    function getTimestamp () {
    return Utilities.formatDate(new Date(), ‘JST’, ‘yyyy_MM_dd_HHmm’);
    }
    “`

  2. 初めまして。
    スプレッドシートの特定のシートをPDF化し、メールで定期的に送ることができる方法を探してこのブログに辿り着きました。
    1点質問があるのですが、39行目「 var folder = DriveApp.getFolderById(folderid);」の部分で「指定された ID のアイテムは見つからなかったか、アクセスする権限がありません。」というエラーが出ます。
    フォルダIDを確認して、マイドライブ、共有ドライブのオーナーがきちんと自分のものになっているフォルダを設定していますが、やはりエラーになってしまいます。
    こちらのサイトさん(https://apps.qiite.net/gas/gas_gmail/)の方法では全てのシートをPDFにして送ることができたのですが、勉強不足で特定のシートのみの場合のコードを書いた時どこを直せばいいのか分かりません。

    お手数ですが宜しくお願い致します。フォルダID、スプレッドシートID、シートID以外は掲載されているコードと同じです。

  3. PDFへの変換処理をLoop処理で実行すると、Error429が発生します。
    PDF変換処理は連続で行えないように制限が掛かっているのでしょうか?
    またこれを回避する方法をご存じでしょうか。

コメントを残す

メールアドレスが公開されることはありません。