複数のシートを自動でPDFにできたらなあ…
PDF化するときのオプション項目が多すぎてよくわからない!
スプレッドシートをPDFに変換したいとき、手作業で1シートずつしていたら、時間がかかると思います。
GASを使えば、数回のクリックでパッとPDFに変換できるんじゃないかと考えているかもしれませんね。
そこでこのページでは、スプレッドシートのPDF化のオプションやPDF化するGASのテンプレートを紹介します。
PDFの出力オプションの設定値
まずは、GASでPDFを出力する際のオプション設定方法を解説します。
設定する項目がいくつかあるので、それぞれを表でまとめますね。
コード | 内容 |
---|---|
size | A3 / A4 / letterなど |
portrait | 用紙の向き true:縦向き false:横向き |
fitw | ページ幅を用紙にフィットさせるか true:フィットさせる false:原寸大 |
top_margin | 上の余白 |
right_margin | 右の余白 |
bottom_margin | 下の余白 |
left_margin | 左の余白 |
sheetnames | シート名をPDFに表示するか true:表示する false:表示しない |
printtitle | スプレッドシート名をPDFに表示するか true:表示する false:表示しない |
pagenum | ページ番号を表示するか true:表示する false:表示しない |
scale | 用紙にどのようにして合わせるか 1:標準100% 2:幅に合わせる 3:高さに合わせる 4:ページに合わせる |
horizontal_alignment | 水平方向の位置 |
vertical_alignment | 垂直方向の位置 |
gridlines | グリッドラインを表示するか true:表示する false:表示しない |
fzr | 固定行の表示有無 true:表示する false:表示しない |
fzc | 固定列の表示有無 true:表示する false:表示しない |
range | セル範囲の指定 セル範囲を「%3A」でつなぐ。「%3A」がコロンの代わりになる。 たとえば、A2:B2の場合は以下のようになる。 ‘A2’ + ‘%3A’ + ‘B2’ |
以下の項目は、シートの内容に応じて、変更する頻度が高いと思われます。
- portrait:用紙の向き
- fitw:ページ幅を用紙にフィットさせるか
- scale:用紙にどのようにして合わせるか
- range:セル範囲の指定
必要に応じて、値を変更してみてくださいね。
すぐ使えるテンプレートファイル
自分でコードを書く時間はないから、完成版がほしい!
時間がないときは、自分でコードを書くのも面倒だと思うので、完成版を以下に用意しました。
複製して使ってみてください。
ちなみに、このGASで作れるPDFは以下の出力設定になっています。出力したいPDFの仕様に合わせて、変更してくださいね。
- 用紙サイズ:A4
- 用紙の向き:横向き
- ページ幅を用紙にフィットさせるか:フィットさせる
- 上の余白:0.50
- 右の余白:0.50
- 下の余白:0.50
- 下の余白:0.50
- シート名の表示:なし
- スプレッドシート名の表示:なし
- ページ番号をどこに入れるか:入れない
- スケール:ページに合わせる
- 水平方向の位置:中央
- 垂直方向の位置:中央
- グリッドラインの表示:なし
- 固定行の表示:なし
- 固定列の表示:なし
- セル範囲の指定:A2:B2
GASのコード
このGASのコードは以下のとおりです。
/**
* スプレッドシートをPDF化し、Google Driveに保存するメイン関数。
*/
function saveSheetsAsPdf() {
try {
const sheetInfo = getSheetInfo();
if (!sheetInfo.spreadsheetUrl || !sheetInfo.driveFolderUrl) {
return; // エラーメッセージは getSheetInfo 関数内で表示される。
}
// 対象のスプレッドシートを取得する
const spreadsheet = SpreadsheetApp.openByUrl(sheetInfo.spreadsheetUrl);
const allSheets = spreadsheet.getSheets();
// Googleドライブのフォルダを取得する
const driveFolder = DriveApp.getFolderById(extractFolderId(sheetInfo.driveFolderUrl));
// シートを一枚ずつPDF化していく
for(const sheet of allSheets){
let pdf = fetchPdfBlob(spreadsheet.getId(), sheet);
driveFolder.createFile(pdf);
Logger.log(`${driveFolder.getName()}フォルダにPDF「${pdf.getName()}」を作成しました。`);
Utilities.sleep(6000); // APIレート制限対策
}
} catch (error) {
Logger.log('エラーが発生しました: ' + error.toString());
const ui = SpreadsheetApp.getUi();
ui.alert('エラー', '処理中にエラーが発生しました。詳細はログを確認してください。', ui.ButtonSet.OK);
}
}
/**
* 必要なシート情報を取得する。
* @return {Object} スプレッドシートとDriveフォルダのURLを含むオブジェクト
*/
function getSheetInfo() {
const prepSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PDF化準備');
const spreadsheetUrl = prepSheet.getRange('B2').getValue();
const driveFolderUrl = prepSheet.getRange('B3').getValue();
const ui = SpreadsheetApp.getUi();
if (!spreadsheetUrl) {
ui.alert('お願い', 'B2セルに「PDF化したいスプレッドシート」のURLを入力してください。', ui.ButtonSet.OK);
}
if (!driveFolderUrl) {
ui.alert('お願い', 'B3セルにPDFを保存するGoogle DriveのURLを入力してください。', ui.ButtonSet.OK);
}
return { spreadsheetUrl, driveFolderUrl };
}
/**
* Google DriveのフォルダIDをURLから抽出する。
* @param {string} url Google DriveフォルダのURL
* @return {string} フォルダID
*/
function extractFolderId(url) {
try {
// URLからクエリパラメータを削除
let folderUrl = url.split('?')[0];
// '/folders/'より後ろの文字列を抽出する
return folderUrl.split('/folders/')[1];
} catch (error) {
Logger.log('フォルダURLの解析エラー: ' + error.toString());
throw new Error('フォルダURLの解析中にエラーが発生しました。');
}
}
/**
* PDFファイルとしてシートをフェッチし、Blobとして返す。
* @param {string} spreadsheetId スプレッドシートのID
* @param {GoogleAppsScript.Spreadsheet.Sheet} sheet シート
* @return {GoogleAppsScript.Base.Blob} PDF Blob
*/
function fetchPdfBlob(spreadsheetId, sheet) {
try {
const pdfUrl = preparePdfUrl(spreadsheetId, sheet.getSheetId());
const response = UrlFetchApp.fetch(pdfUrl, {
headers: { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() }
});
return response.getBlob().setName(sheet.getName() + '.pdf');
} catch (error) {
Logger.log('PDFの取得エラー: ' + error.toString());
throw new Error('PDFの取得中にエラーが発生しました。');
}
}
/**
* PDF生成のためのURLを準備する。
* @param {string} spreadsheetId スプレッドシートのID
* @param {string} sheetId シートのID
* @return {string} PDF生成URL
*/
function preparePdfUrl(spreadsheetId, sheetId) {
// PDFの設定オプション
const options = {
size: 'A4', // 用紙サイズ (A4)
portrait: 'false', // 用紙の向き(falseは横向き)
fitw: 'true', // ページ幅に合わせるか(falseは原寸大)
top_margin: '0.50', // 上の余白(0.50インチ)
right_margin: '0.50', // 右の余白(0.50インチ)
bottom_margin: '0.50', // 下の余白(0.50インチ)
left_margin: '0.50', // 左の余白(0.50インチ)
sheetnames: 'false', // シート名の表示(falseは非表示)
printtitle: 'false', // スプレッドシート名の表示(falseは非表示)
pagenum: 'UNDEFINED', // ページ番号の位置('UNDEFINED'は非表示)
scale: '4', // 印刷の拡大/縮小(4はページに合わせる)
horizontal_alignment: 'CENTER', // 水平方向の位置(CENTERは中央)
vertical_alignment: 'CENTER', // 垂直方向の位置(CENTERは中央)
gridlines: 'false', // グリッドラインの表示(falseは非表示)
fzr: 'false', // 固定行の表示(falseは非表示)
fzc: 'false', // 固定列の表示(falseは非表示)
range: 'A2' + '%3A' + 'B2' // セル範囲を指定(この場合だとA2:B2)
};
let url = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/export?format=pdf&id=${spreadsheetId}&gid=${sheetId}`;
for (const key of Object.keys(options)){
url += `&${key}=${options[key]}`;
};
return url;
}
このコードの大まかな流れは、以下のとおりです。
- 「PDF化準備」シートを取得する
- B2セルから「PDF化したいスプレッドシート」のURLを取得する
- B3セルからGoogle DriveのフォルダURLを取得する
- 「PDF化したいスプレッドシート」内のすべてのシートを取得する
- すべてのシートのA2:B2範囲をPDF化する
- PDFをGoogle Driveの指定フォルダに保存する
スプレッドシートとGoogle DriveフォルダのURLさえ入れれば、すぐに使えますよ!
完成版GASの使い方
ここからは、完成版の使い方を解説していきます。
「原本_GASでスプレッドシートのシートを1枚ずつPDFにする」を複製してください。
▼メニューバーの[ファイル]>[コピーを作成]をクリックします。
▼複製先のフォルダを指定したら[コピーを作成]をクリックしましょう。
新しいタブが開いて、複製されたスプレッドシートが表示されますよ。
B2とB3セルに以下のURLを入力してください。
- B2:PDF化したいスプレッドシートのURL
- B3:PDFを保存するGoogle DriveのフォルダのURL
▼こんな感じで、URLを入力します。
このGASでは、各シート名がPDFのファイル名になります。
もし複製したいシート名が「シート1」や「シート2」となっている場合は、希望のPDFファイル名に変更しておくのがいいと思います。
「PDF化準備」というシート名は、変更しないでください。GASが動かなくなります。
[GASメニュー]をクリックすると[スプレッドシートをPDF化する]が表示されるので、クリックしましょう。
このGASを初めて実行する場合、このような画面が出てくると思います。
これは、このGASを実行してもいいかの承認を求める画面です。
[続行]をクリックしたら、あとは画面の指示に従って、クリックして進めていきます。
どうすればいいかわからない場合は、以下のページを参考にしてみてください。
画像付きで、解説していますよ。
承認が終わったら、もう一度[GASメニュー]>[スプレッドシートをPDF化する]をクリックしてください。
GASが実行されます。
「スプリプトを実行しています」と表示されている間は、しばらく待ちましょう。
最大で6分ほどかかることがあります。
「スクリプトが終了しました」と表示されたら、PDF化が完了しています。
対象のGoogle Driveを見てみましょう。
PDFが保存されているはずです。
▼今回はシート名を「シート1〜3」のまま、PDF化しました。
このGASを作った経緯
私は業務委託で、Webスクール事業の事務業務の効率化サポートをしています。
毎月このスクールでは、受講者に成績表をPDFで配布しています。
以前は、スプレッドシートに受講者の人数分のシートを用意して、それらを手作業でPDF化していました。
1カ月に100人以上の成績表をつくるので、手作業でPDF化していると、非常に時間がかかります。
そこで、GASで自動化できないかと、私が相談を受けました。
さいごに
スプレッドシートをPDF化するGASプログラムを解説しました。
テンプレートファイルを使えば、すぐにPDF化できるので、試してみてくださいね。
もしも「この作業もGASでできるかな?」というお悩みをお持ちの場合は、コメント欄でおしえてください。
コメント
コメント一覧 (11件)
はじめまして、私が求める作業を探していたところここにたどり着きました。
早速B2に指定スプレッドのURLを入力し、B3にドライブの格納フォルダURLを入力し実行した所下記のエラーが出て実行できませんでした。
エラー回避させるためにはどのような対応が必要でしょうか?
お忙しいところ恐縮ですが回答よろしくお願いします。
エラー
TypeError: Cannot read properties of null (reading ‘getRange’)
saveSheetsAsPdf @ コード.gs:10
安藤さん
コメントありがとうございます!
私の作ったGASを使ってくださてて、本当にうれしいです。
発生しているエラーの原因は、シート名が「PDF化準備」になっていないことだと考えられます。
URLを入力したシートの名前が「PDF化準備」になっているかをお確かめください。
もし、シート名を変更したい場合は、コードの行目の「PDF化準備」をお好きなシート名に変更してください。
永富様
とても素晴らしいGASを公開してくださって、ありがとうございます。
私はスプレッドシート(15ファイル)内の10程度のシートをPDF化したく、
方法を調べていたところこちらにたどり着きました。
実際に使ってみたのですが、下記のようなエラーが出てしまい、困っています。
お知恵をお借りしたく、お願いいたします。
なお、シート名は”PDF化準備”ではなく、現在入力してある名称(●月〇日)に
したいです。
以下エラーコード
エラーが発生しました: Exception: Unexpected error while getting the method or property getFolderById on object DriveApp.
お褒めいただきありがとうございます!うれしいです。
シート名を変える場合は、コードの31行目の「PDF化準備」の部分もシート名と同じにする必要があります。
このエラーはB3セルに、GoogleドライブフォルダのURLが正しく入力されていないことによって、起こっていると考えられます。
GoogleドライブフォルダのURLが入力されているかを確かめてみてくださいね。
もし問題が解決しない場合は、ビデオ通話で、ととさんの画面を一緒に見ながら解決策を考えることもできます。
以下のURLをクリックして、GASのメンタリングサービス(相談無料)をお申し込みください。
https://menta.work/plan/13118/41009
軽微なエラーなので、無料プランの通話中に解決すると思います。
ありがとうございます。
相談を入力させていただきました。
よろしくお願いいたします。
こんにちは。
毎月スプレッドシートの複数のシートをPDF化する必要があり、
探していたとことこちらにたどり着きました。
短時間でPDF化でき、大変助かりました。
出来ればPDF化するシートのセルの範囲を設定したいと思っております。
(例えば印刷範囲を”E2:AA15”にしたい)
調べてみると設定オプションで”range”を使う方法が出てくるのですが、
GASで使用しようとするとサポート外な為かエラーが発生してうまくいきません。
PDF化するシートの範囲設定は可能でしょうか。
ほりうちさん
コメントありがとうございます
お役に立ててうれしいです!
セル範囲を指定できるなんて知りませんでした!
教えてくださりありがとうございます。
調べてみて、実際に実装してみたところ、エラーは起きずにPDF化できました。
記事内のコードに「range: ‘A2’ + ‘%3A’ + ‘B2’ 」を追加してみたので、コピペして使ってみてください。
うまくいったかどうかのご報告もいただけると幸いです。
ご返信、およびご確認いただきありがとうございます!
永富さんはエラーが発生しなかったのですね。
range を記載すると下部に波線が入り、保存時に下記エラーが発生して保存できませんでした。
(記事内のコードをコピペさせていただきましたが、同様のエラーが発生して保存できませんでした、、、バージョンなど関係するのでしょうか)
可能であれば、「Google Docs」のスプレッドシートのGASを更新いただけますでしょうか。
お手数をおかけした恐れ入ります
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
構文エラー: SyntaxError: Unexpected identifier ‘range’ 行: 103 ファイル: saveSheetsAsPdf.gs
スプレッドシートのコードを修正いたしました。
動作確認済みです!
他の箇所のコードも、よりエラーの起きにくいコードに書き換えたので、コードすべてをコピペした使っていただくのが良いかと思います!
ありがとうございます!
スプレッドシート毎コピーして実行すると、指定した範囲でのPDF化が出来ました!
大変助かりました。毎月の従業員の給料明細作成が楽になります、、、
有意義な情報提供に加え、見ず知らずの私の質問に迅速にご対応いただき、感謝でいっぱいです。
お役に立ててうれしいです!
もし、貴社の中で繰り返し発生している業務があり、その業務を自動化したい場合は、以下のリンクから開発代行をご依頼ください!
https://jidou-ka.com/contact/
過去の実績や開発できることも記載しています。
ご検討いただけますと幸いです。