Google Apps Scriptそのものには、印刷に関するメソッドがありません。しかし、ファイルのエクスポートではPDF形式がサポートされています。これは、URLを組み立てて投げることで、プログラム側からも利用出来るようになっています。

PDF化は何かと利用価値はありますが、これが実装できると、自動的にPDF化してメールに添付して送る、ドライブの所定の場所に自動的に格納するなどが可能になります。また、スプレッドシート固有の機能ではないので、他のドキュメントも利用することが出来ますよ。

使用するメソッド・クラス、準備するもの

  1. 今回使用するスプレッドシート
  2. UrlfetchAppクラスの各種メソッド
  3. DriveAppクラスのgetAsメソッド

ソースコード

メソッドを使って簡単にPDF化して取得

この方法は最も手っ取り早いPDF化の方法です。しかし、制御が出来ません。よって、細かいPDF化の為のオプションが存在しないので、そのドキュメントおよびスプレッドシートがまるごとPDFになるだけです。今回はスプレッドシートをPDF化して、ファイルを生成し、そのままログインユーザ名を取得して、操作者にそのままPDFをメールに添付して送り付けます。

  • 今回はフォルダの指定はしていないので、ルートディレクトリにPDFが生成されます。
  • 生成しなくてもメールに添付してそのまま送りつけてしまってもOKです。
  • getAsメソッドの引数にPDFのMIMETYPEを渡しています。これが最も重要です。
  • 特定のシートのみPDF化が出来ません。
  • 何も他にオプションが無いので、スプレッドシートではセルの枠線などもバッチリ映り込んでしまいますので、ドキュメント向けです。

URLを組み立ててPDFをエクスポートして取得

getAsメソッドだと自由が効かないので、使い勝手が悪いです。そこで、URLを組み立ててPDF化する方法があります。特定の1シートのみをPDF化することが可能です申請書類などをスプレッドシートで生成し、PDF化してメールで送る場合にはこの手法が最も良い方法でしょう。

ソースコード

  • 今回は、アクティブシートをA4用紙横印刷でグリッドライン無しのフィットページにてPDFを作成しています。
  • スクリプトトリガーなどで実行する場合は、実行者の権限で動かせます。また、ウェブアプリケーション上でもこのコードは実行者の権限設定ができますので、匿名の者であっても、ウェブアプリケーション化してしまえば、コードを実行することが可能です。
  • アクセス者の権限で呼び出す場合、必ずその人のアカウントで認証が必要です。またこの場合、実行時のQuotaは一人単位なので、設置者権限だとQuotaに引っかかる場合は、アクセスしてきてるユーザの権限で動かすと良い。
  • 但し上記の場合、PDFをドライブに生成する時は、そのフォルダへのアクセス権限が必要。
  • urlfetchappは連続で呼び出すと、途中でアクセス過多で503エラーや403エラーが出るので、沢山呼び出す時は、10秒くらいUtilities.sleep入れてウェイトする必要があります。一日に呼び出せるQuotaにも注意が必要です。PDFのファイルサイズにも注意。
  • ちなみにAPI呼び出しすぎの場合の403エラーは、User Rate Limit Execeedというエラーがそれです。間隔を空けましょう。

書き込みが間に合わない時の処置

データの書き込みを行い、其の流れでPDFを生成する場合には、データの書き込みが間に合わずPDFが生成されてしまうケースが、しばしばあります。このままでは、折角のPDFもデータが欠けた状態で作成されてしまうので、以下のような無限ループを利用して、「最終書き込みセル」を確認しながら、スクリプトをウェイトさせます。

最終書き込みをするであろう場所を今回は、名前付き範囲で指定しています。
その中身が空の状態の時は無限ループします。値が確認できたら、PDF生成ルーチンへ進むといった感じです。

URLオプション

URLに続けてオプションを付加すると、Chromeでの印刷時と同じオプションを付け加えることが出来る。重要度の高い物を赤字、次に必要な物を青字で説明してみた。

  • key : スプレッドシートのIDを指定する
  • gid : シートIDを指定する。シート毎に付いているもので、URLに入ってる。このオプション指定をしないと、全ページ印刷の対象となる。省略可。
  • format : 出力フォーマットを指定。PDFなので、format=pdfとして引数を取る。以前は、fmcmdで引数に数字を取っていた。

formatの引数に指定できるものは以下の数種類。要するに標準で装備してる「形式を指定してダウンロード」の対象物が取れるようになっているわけです。今回はスプレッドシートのみ紹介しますが、ドキュメントやスライドなどでは若干使えるもの使えないもの、違うものがあります(例えば、ドキュメントの場合、4.はodsではなくodtとなる)。

  1. pdf : 今回のテーマ。PDF形式で出力します。
  2. xlsx : Microsoft Excel形式で出力します。出力は、xlsx形式なので注意
  3. csv : UTF-8でエンコードされたCSVファイル。正直あまり使わない。Excelにインポートする時は、拡張子をtxtに変更してから取り込みましょう。
  4. ods : OpenDocument形式。但しこれは、スプレッドシートの場合の形式です。OpenOffice.orgのcalcの拡張子を指定すると覚えておけばOK。使わないと思うけれど。
  5. tsv : タブ区切りのテキストファイル形式です。
  6. zip : シートをHTML形式で出力しZIPで固めてエクスポート。その為、このオプションだけは、gid=の指定を入れてしまうとエラーになります。単純にexport?format=zipだけしか指定してはいけません。

その他のオプション指定項目は以下の通り。よく使うものだけ青色で表示。margin系は4方向すべて指定しなければなりません。現在、複数のsheetidを指定したPDF出力法がわからない・・・・カンマ区切りで渡してもだめでした。

  1. size : 出力するサイズ。A4と入れるとA4形式となる。番号での指定もできるようだ。また、10×20とするとインチ指定ですが横x縦のカスタムサイズ指定で出力可能。
  2. fzr : 各ページに行見出しを含めるかどうか。trueで含める、falseで含めない。
  3. fzc : 各ページに列見出しを含めるかどうか。trueで含める、falseで含めない。
  4. portrait : trueで縦出力、falseで横出力
  5. fitw : ページをフィットさせるかどうか。trueでフィット、falseで原寸大。
  6. gridlines : グリッドラインの有無。trueで有り、falseで無し。
  7. printtitle : ドキュメントのタイトルの有無。trueで有り、falseで無し。
  8. sheetnames : シート名の有無。trueで有り、falseで無し。
  9. pagenum : ページ番号の指定。CENTERと入れると真ん中に表示される。
  10. attachment : 不明。getFileというコマンドと連携してるとかしてないとか。
  11. locale : 言語の指定。必要ないと思う。
  12. range : シート単位ではなく、指定範囲内を印刷。名前付き範囲を指定したり、A1:D5の範囲指定ならば、A1%3AD5(%3Aでコロン)といったURLエンコードした範囲を与える
  13. widget : rangeの指定時のみ使用可能。今見ている範囲内をtrueとすると印刷範囲とする変なオプション。使いドコロ不明。
  14. top_margin : 上の余白(cmで指定)
  15. bottom_margin : 下の余白
  16. left_margin : 左の余白
  17. right_margin : 右の余白
  18. scale : 1= 標準100%, 2= 幅に合わせる, 3= 高さに合わせる,  4= ページに合わせる
  19. printnotes:コメントを印刷するかどうか。trueで印刷する。
  20. ir:不明
  21. ic:不明
  22. r1c1 : R1C1方式でのrangeの指定。&c1=0&r1=0&c2=4&r2=42といった感じに指定する。
  23. horizontal_alignment:水平方向の位置。LEFT/CENTER/RIGHTを指定
  24. vertical_alignment:垂直方向の位置。TOP/MIDDLE/BOTTOMを指定
  25. pageorder:複数ページの印刷時にどちらの方向から印刷するか。1で前から後ろ、2で後ろから前。

とりわけ、特定の範囲を指定してのPDF化の場合には、URLエンコードが必要なので、以下のように予め範囲指定をURLエンコードしておいて、URL組み立てでつないで上げれば楽です。encodeURIComponentでそれが可能です。

こうすることで、指定のシートのA1:E21の範囲をA4横でグリッドライン非表示、自動でフィットするようにPDF化してくれます。

暫定:特定の複数のページをPDF化する

現在、gidは1個しか指定ができません。印刷オプション的には特定のシートを複数選択して、それだけを印刷可能なので何らかのオプションが隠れていると思うのですが、指定方法が不明です。

そこで暫定的な方法としては、PDF化をする際に印刷対象にしないスプレッドシートを隠してからPDF化を実行すると、非表示にしたシートは印刷対象から外れます。非表示にするコードは以下の通り。このコードだと、水根貨物線跡というシートが一旦非表示になってからPDF化されて、再度表示しています。全3枚中2枚がPDF化されて印刷されます。gid指定は行っていません。エラー発生時を想定して、try{}catch(e){}で、エラー時には再度、showするコードを入れておくと良いと思います。

パスワード付きPDFを作りたい

Google Apps Scriptだけでは暗号化PDFは作る手段がありません。しかし、Node.jsのモジュールが使えれば作成する事ができます。自分もようやく最近作れるようになったのですが。。。

Node.jsが使える環境がGoogle Cloud Platformには複数あります。其のうちの一つである「Google Cloud Functions」にて、Node.js + hummus-recipeにて実現が可能です。無料枠がかなり広いので、超低コストでGoogle Apps Scriptの機能を拡張し、パスワード付きPDFを作る事が可能になります。

詳細については、以下のエントリーを参考に挑戦してみてください。サンプルも用意してあります。ちなみに、このモジュール、パスワード付きPDFを作るだけでなく、結合や加工(テキスト挿入やイメージ追加)、挿入や追加、分割やオーバーレイなど様々な事ができます。実装次第では一気にPDF作成の可能性が広がります。

Google Apps ScriptでCloud Functionsの関数を実行する

ボタンをクリックでダウンロード

これまでの説明は、スプレッドシートをPDFへ変換してUrlfetchAppで取得後にメールに添付して送るというものでした。しかし、メールではなくボタンを押したら直接ダウンロードしたいという要望があると思います。その場合、直接GASのコマンドを叩いてダウンロードは出来ませんが、例えばSidebarやダイアログにボタンを表示して、クリックするとPDFでダウンロードされるみたいな事は可能です。

GAS側コード

※現在見てるスプレッドシートをPDF化するリンクとファイル名を取得して、HTML側へ返しています。

HTML側コード(サイドバー)

※google.script.run.withSuccessHandlerにてGAS側へリンクとファイル名を要求。返って来た値を元にjQueryでボタンにそのリンクとファイル名を設定するというものです。ボタンをクリックするとリンクが叩かれてファイルがダウンロードされます。

関連リンク

共有してみる: