請求書や見積書、月次報告書をGoogleスプレッドシートで作成したあと、毎回「ファイル」→「ダウンロード」→「PDF」→「保存先フォルダへ移動」→「ファイル名を変更」という作業を繰り返していないでしょうか。
1回だけなら数分で終わる作業でも、毎日・毎月繰り返すと意外に大きな負担になります。特に「顧客名を確認してファイル名へ入力する」「決められたGoogleドライブのフォルダへ保存する」といった定型作業は、できるだけ人の手を介さず自動化したいところです。
そこで今回は、GAS(Google Apps Script)を使って、スプレッドシートの特定シートをワンクリックでPDF化し、指定したGoogleドライブフォルダへ自動保存する方法を紹介します。
完成後は、シート上のボタンからスクリプトを実行するだけで、たとえば「【請求書】株式会社サンプル_20260904.pdf」のようなファイル名を自動生成し、所定のフォルダへ保存できます。さらに、作成したPDFのURLと処理日時もスプレッドシートへ自動記録します。
【結論】コピペで使えるGASのPDF自動保存コード
今回の完成コードでは、次の処理を一括で行います。
- 指定した「請求書」シートを取得する
- 顧客名と請求日をセルから取得する
- 使用しているセル範囲だけをPDF化する
- A4・縦向き・余白なし・グリッド線なしでPDFを生成する
- 指定したGoogleドライブフォルダへ保存する
- 生成したPDFのURLと処理日時をシートへ記録する
「FOLDER_ID」「SHEET_NAME」「CUSTOMER_CELL」「DATE_CELL」を、自分のスプレッドシートに合わせて変更してください。
// ==================================================
// 機能:
// 指定したスプレッドシートのシートをPDF化し、
// Googleドライブの指定フォルダへ自動保存する
// ==================================================
function exportInvoiceToPdf() {
// --------------------------------------------------
// 設定値
// --------------------------------------------------
// PDFの保存先となるGoogleドライブのフォルダID
const FOLDER_ID = "ここにGoogleドライブのフォルダIDを入力";
// PDF化するシート名
const SHEET_NAME = "請求書";
// 顧客名が入力されているセル
const CUSTOMER_CELL = "B2";
// 請求日が入力されているセル
const DATE_CELL = "F2";
// PDFのURLを書き込むセル
const PDF_URL_CELL = "H2";
// PDF生成日時を書き込むセル
const TIMESTAMP_CELL = "H3";
// --------------------------------------------------
// スプレッドシートと対象シートを取得
// --------------------------------------------------
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName(SHEET_NAME);
// シート名が間違っている場合は処理を停止
if (!sheet) {
throw new Error(
"指定したシートが見つかりません。シート名を確認してください:" + SHEET_NAME
);
}
// --------------------------------------------------
// 保存先フォルダを取得
// --------------------------------------------------
const folder = DriveApp.getFolderById(FOLDER_ID);
// --------------------------------------------------
// ファイル名に使用する顧客名と日付を取得
// --------------------------------------------------
const customerName = sheet.getRange(CUSTOMER_CELL).getDisplayValue().trim();
const invoiceDateValue = sheet.getRange(DATE_CELL).getValue();
// 顧客名が空欄の場合は処理を停止
if (customerName === "") {
throw new Error(
"顧客名が入力されていません:" + CUSTOMER_CELL
);
}
// 日付として入力されている場合はyyyyMMdd形式に変換
let invoiceDate;
if (
invoiceDateValue instanceof Date &&
!isNaN(invoiceDateValue.getTime())
) {
invoiceDate = Utilities.formatDate(
invoiceDateValue,
Session.getScriptTimeZone(),
"yyyyMMdd"
);
} else {
// 日付型でない場合は表示されている文字列をそのまま利用
invoiceDate = sheet.getRange(DATE_CELL).getDisplayValue().trim();
}
// 日付が空欄の場合は処理を停止
if (invoiceDate === "") {
throw new Error(
"請求日が入力されていません:" + DATE_CELL
);
}
// Windowsなどでファイル名に使えない記号を除去
const safeCustomerName = customerName.replace(/[\\/:*?"<>|]/g, "_");
const safeInvoiceDate = invoiceDate.replace(/[\\/:*?"<>|]/g, "-");
// PDFファイル名を作成
const fileName =
"【請求書】" +
safeCustomerName +
"_" +
safeInvoiceDate +
".pdf";
// --------------------------------------------------
// PDF化する範囲を取得
// --------------------------------------------------
// データが存在する最終行・最終列を取得
const lastRow = sheet.getLastRow();
const lastColumn = sheet.getLastColumn();
// PDFエクスポート用の範囲指定は0始まり
const r1 = 0;
const c1 = 0;
const r2 = lastRow;
const c2 = lastColumn;
// --------------------------------------------------
// GoogleスプレッドシートのPDF出力URLを作成
// --------------------------------------------------
const baseUrl =
"https://docs.google.com/spreadsheets/d/" +
spreadsheet.getId() +
"/export?";
const exportParams = [
"format=pdf",
"size=A4",
"portrait=true",
"fitw=true",
"sheetnames=false",
"printtitle=false",
"pagenumbers=false",
"gridlines=false",
"fzr=false",
"top_margin=0",
"bottom_margin=0",
"left_margin=0",
"right_margin=0",
"gid=" + sheet.getSheetId(),
"r1=" + r1,
"c1=" + c1,
"r2=" + r2,
"c2=" + c2
].join("&");
const exportUrl = baseUrl + exportParams;
// --------------------------------------------------
// OAuthトークンを使ってPDFデータを取得
// --------------------------------------------------
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: "Bearer " + token
},
muteHttpExceptions: true
});
// HTTPエラーが発生した場合は詳細を表示して停止
if (response.getResponseCode() !== 200) {
throw new Error(
"PDFの生成に失敗しました。HTTPステータス:" +
response.getResponseCode() +
"\n" +
response.getContentText()
);
}
// 取得したレスポンスをPDF Blobへ変換
const pdfBlob = response
.getBlob()
.setName(fileName);
// --------------------------------------------------
// 指定フォルダへPDFファイルを保存
// --------------------------------------------------
const pdfFile = folder.createFile(pdfBlob);
// --------------------------------------------------
// 作成したPDFのURLと生成日時をシートへ記録
// --------------------------------------------------
sheet.getRange(PDF_URL_CELL).setValue(pdfFile.getUrl());
sheet.getRange(TIMESTAMP_CELL).setValue(new Date());
// タイムスタンプの表示形式を設定
sheet
.getRange(TIMESTAMP_CELL)
.setNumberFormat("yyyy/mm/dd hh:mm:ss");
// 完了メッセージを表示
SpreadsheetApp
.getUi()
.alert(
"PDFを作成しました。\n\nファイル名:" +
fileName +
"\n保存先URL:" +
pdfFile.getUrl()
);
}
完成スクリプトの動作イメージ
上記コードでは、たとえば「請求書」シートのB2セルに顧客名、F2セルに請求日が入力されている想定です。
| 項目 | 設定例 |
|---|---|
| PDF化するシート | 請求書 |
| 顧客名 | B2セル |
| 請求日 | F2セル |
| PDFのURL記録先 | H2セル |
| 生成日時の記録先 | H3セル |
| 生成されるファイル名 | 【請求書】株式会社サンプル_20260904.pdf |
PDFはブラウザへダウンロードするのではなく、GASから直接Googleドライブへ保存されます。そのため、ユーザーがPDFをダウンロードしてから別フォルダへ移動する必要はありません。
コードの詳しい解説
1. DriveApp.getFolderByIdで保存先フォルダを取得する
まず、PDFを保存するGoogleドライブのフォルダを取得しています。
const FOLDER_ID = "ここにGoogleドライブのフォルダIDを入力";
const folder = DriveApp.getFolderById(FOLDER_ID);
DriveApp.getFolderById()は、Googleドライブ上のフォルダIDを指定して、そのフォルダを表すオブジェクトを取得するメソッドです。
たとえばGoogleドライブで対象フォルダを開いたとき、URLが次のようになっていたとします。
https://drive.google.com/drive/folders/xxxxxxxxxxxxxxxxxxxx
この場合、「xxxxxxxxxxxxxxxxxxxx」の部分がフォルダIDです。
2. シートIDを指定して特定シートだけをPDF化する
GoogleスプレッドシートをPDF化するときは、通常のSpreadsheetAppだけで完結させるのではなく、GoogleスプレッドシートのPDFエクスポートURLへアクセスします。
特定のシートだけを出力するために重要なのが、次の部分です。
"gid=" + sheet.getSheetId()
getSheetId()は、対象シート固有の数値IDを取得するメソッドです。スプレッドシート全体のIDであるspreadsheet.getId()とは役割が異なります。
- spreadsheet.getId():スプレッドシートファイルそのもののID
- sheet.getSheetId():その中にある各シートのID
このシートIDをPDFエクスポートURLのgidへ渡すことで、「請求書」シートだけをPDFとして出力できます。
3. PDFの用紙サイズ・向き・余白・グリッド線を指定する
今回のコードでは、PDFの印刷設定もURLパラメータで指定しています。
| パラメータ | 指定値 | 意味 |
|---|---|---|
| format | PDF形式で出力 | |
| size | A4 | 用紙サイズをA4に指定 |
| portrait | true | 縦向きで出力 |
| fitw | true | 横幅をページ幅に合わせる |
| gridlines | false | スプレッドシートのグリッド線を非表示 |
| sheetnames | false | シート名を印刷しない |
| pagenumbers | false | ページ番号を非表示 |
| top_marginなど | 0 | 上下左右の余白を0に指定 |
横向きで出力したい場合は、次のようにportrait=falseへ変更します。
"portrait=false"
見積書や請求書のような縦長帳票ならtrue、列数が多い月次報告書などはfalseにする、と使い分けると便利です。
4. r1・c1・r2・c2でPDFの印刷範囲を指定する
今回のコードでは、シート全体ではなく、実際にデータが存在する範囲をPDF化するためにgetLastRow()とgetLastColumn()を使用しています。
const lastRow = sheet.getLastRow();
const lastColumn = sheet.getLastColumn();
const r1 = 0;
const c1 = 0;
const r2 = lastRow;
const c2 = lastColumn;
PDFエクスポートURLで使う範囲指定は0始まりです。
- r1:開始行
- c1:開始列
- r2:終了側の行
- c2:終了側の列
今回のコードではA1から最終使用セルまでを自動判定しているため、請求書の明細行数が多少増減しても対応しやすくなっています。
5. UrlFetchApp.fetchでPDFデータを取得する
生成したPDFエクスポートURLへアクセスする処理がUrlFetchApp.fetch()です。
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: "Bearer " + token
},
muteHttpExceptions: true
});
ScriptApp.getOAuthToken()で現在のGAS実行ユーザーのOAuthトークンを取得し、Authorizationヘッダーへ付与しています。
これにより、ログインが必要な自分のGoogleスプレッドシートに対して、GASから認証済みの状態でPDFエクスポートを実行できます。
muteHttpExceptions: trueを設定すると、HTTPエラー時にもレスポンスを取得できるため、ステータスコードを確認して原因を特定しやすくなります。
6. Blobへ変換してfolder.createFileで保存する
PDFのレスポンスを取得できたら、次の処理でBlobデータへ変換します。
const pdfBlob = response
.getBlob()
.setName(fileName);
const pdfFile = folder.createFile(pdfBlob);
Blobとは、PDFや画像などのバイナリデータをGAS上で扱うためのオブジェクトです。
- response.getBlob():HTTPレスポンスをBlobとして取得
- setName():保存するファイル名を設定
- folder.createFile():指定したGoogleドライブフォルダへファイルを作成
ここまで実行されると、ユーザーが手動でダウンロードやアップロードをしなくても、目的のGoogleドライブフォルダへ直接PDFが作成されます。
7. 顧客名と日付からファイル名を動的に生成する
帳票自動化で特に便利なのが、シート上のセル値を使ったファイル名の自動生成です。
const customerName = sheet.getRange(CUSTOMER_CELL).getDisplayValue().trim();
const fileName =
"【請求書】" +
safeCustomerName +
"_" +
safeInvoiceDate +
".pdf";
たとえば、B2セルが「株式会社サンプル」、F2セルが2026年9月4日なら、次のファイル名になります。
【請求書】株式会社サンプル_20260904.pdf
getDisplayValue()は、セルに画面上表示されている文字列を取得するメソッドです。一方、日付セルではgetValue()を使ってDateオブジェクトとして取得し、Utilities.formatDate()でファイル名向けの形式へ変換しています。
8. Utilities.formatDateで日付をyyyyMMdd形式へ変換する
日付をそのままファイル名にすると、「2026/09/04」のようにスラッシュが含まれる場合があります。そのため、ファイル管理しやすいyyyyMMdd形式へ変換しています。
invoiceDate = Utilities.formatDate(
invoiceDateValue,
Session.getScriptTimeZone(),
"yyyyMMdd"
);
Utilities.formatDate()の主な引数は次の3つです。
| 引数 | 意味 |
|---|---|
| 第1引数 | 変換対象となるDateオブジェクト |
| 第2引数 | タイムゾーン |
| 第3引数 | 出力する日付フォーマット |
ここではSession.getScriptTimeZone()を使い、GASプロジェクト側で設定されているタイムゾーンを利用しています。
9. PDFのURLと生成日時をシートへ記録する
業務でPDFを自動生成するなら、「作ったら終わり」ではなく、いつ・どのPDFを生成したか記録しておくと運用しやすくなります。
sheet.getRange(PDF_URL_CELL).setValue(pdfFile.getUrl());
sheet.getRange(TIMESTAMP_CELL).setValue(new Date());
sheet
.getRange(TIMESTAMP_CELL)
.setNumberFormat("yyyy/mm/dd hh:mm:ss");
pdfFile.getUrl()では、Googleドライブ上に作成されたPDFのURLを取得できます。
このURLをシートに残しておけば、担当者はGoogleドライブ内を検索しなくても、スプレッドシートから直接PDFへアクセスできます。
スプレッドシートに「PDF作成」ボタンを設置する方法
今回の処理はApps Scriptエディタから毎回実行する必要はありません。スプレッドシート上に図形や画像を配置し、exportInvoiceToPdfを割り当てれば、ワンクリックで実行できます。
- Googleスプレッドシートで「挿入」から図形描画または画像を配置する
- 「PDF作成」などのボタンを作る
- 配置した図形または画像のメニューから「スクリプトを割り当て」を選択する
- exportInvoiceToPdfと入力する
- ボタンをクリックして処理を実行する
実務でよくあるカスタマイズ
単一シートだけPDF化する場合
今回のコードは、請求書や見積書など1枚の帳票だけをPDF化したいケースに向いています。
次のパラメータによって、対象シートを限定しています。
"gid=" + sheet.getSheetId()
請求書以外のシートへ変更したい場合は、コード冒頭のSHEET_NAMEを変更します。
const SHEET_NAME = "見積書";
スプレッドシート内の全シートを1つのPDFにする場合
月次報告書など、「表紙」「売上」「明細」「集計」といった複数シートをまとめて1つのPDFへ出力したい場合は、gidと個別範囲指定をURLから外すことで全シートを対象にできます。
全シートPDF化用のサンプルコードは次のとおりです。
// ==================================================
// 機能:
// スプレッドシート内の全シートを1つのPDFにして
// 指定したGoogleドライブフォルダへ保存する
// ==================================================
function exportAllSheetsToPdf() {
// 保存先フォルダIDを指定
const FOLDER_ID = "ここにGoogleドライブのフォルダIDを入力";
// スプレッドシートを取得
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 保存先フォルダを取得
const folder = DriveApp.getFolderById(FOLDER_ID);
// 現在日時をファイル名用に整形
const timestamp = Utilities.formatDate(
new Date(),
Session.getScriptTimeZone(),
"yyyyMMdd_HHmmss"
);
// PDFファイル名を作成
const fileName =
spreadsheet.getName() +
"_" +
timestamp +
".pdf";
// 全シート出力用のURLを作成
const exportUrl =
"https://docs.google.com/spreadsheets/d/" +
spreadsheet.getId() +
"/export?" +
[
"format=pdf",
"size=A4",
"portrait=true",
"fitw=true",
"sheetnames=false",
"printtitle=false",
"pagenumbers=false",
"gridlines=false",
"fzr=false",
"top_margin=0",
"bottom_margin=0",
"left_margin=0",
"right_margin=0"
].join("&");
// OAuthトークンを取得
const token = ScriptApp.getOAuthToken();
// PDFデータを取得
const response = UrlFetchApp.fetch(exportUrl, {
headers: {
Authorization: "Bearer " + token
},
muteHttpExceptions: true
});
// HTTPエラーをチェック
if (response.getResponseCode() !== 200) {
throw new Error(
"PDFの生成に失敗しました。HTTPステータス:" +
response.getResponseCode() +
"\n" +
response.getContentText()
);
}
// PDF Blobへ変換
const pdfBlob = response
.getBlob()
.setName(fileName);
// Googleドライブへ保存
const pdfFile = folder.createFile(pdfBlob);
// 完了メッセージを表示
SpreadsheetApp
.getUi()
.alert(
"全シートをPDF化しました。\n\n" +
pdfFile.getUrl()
);
}
帳票1枚だけなら最初のexportInvoiceToPdf()、複数シートをまとめたい場合はexportAllSheetsToPdf()という形で使い分けると分かりやすいでしょう。
PDF生成直後にGmailへ添付して送信する
PDFをGoogleドライブへ保存できるようになると、次のステップとして非常に相性がよいのがGmailとの連携です。
たとえば、今回の処理で作成したpdfBlobをそのままGmailAppやMailAppへ渡せば、次のような業務フローを構築できます。
- 請求書シートを作成する
- ボタンをクリックする
- PDFをGoogleドライブへ保存する
- PDFをメールへ添付する
- 顧客のメールアドレスへ自動送信する
- 送信日時をスプレッドシートへ記録する
つまり、「帳票を作る → PDF化する → 保存する → メールへ添付する → 送信する」までを、GASで一本化できます。
GASを使ったGmailの自動送信については、以下の記事もあわせて参考にしてください。
【GAS】スプレッドシートのデータを使ってGmailを自動送信する方法
GASのPDF化とExcel VBAのExportAsFixedFormatを比較
Excel VBAでも、ExportAsFixedFormatを使えばワンクリックでPDFを出力できます。ただし、GASとVBAでは実行環境や保存先に大きな違いがあります。
| 比較項目 | GAS | Excel VBA |
|---|---|---|
| 主な実行場所 | Googleのクラウド環境 | Excelが動作するローカルPC |
| 元データ | Googleスプレッドシート | Excelブック |
| 代表的なPDF生成方法 | PDFエクスポートURL+UrlFetchApp | ExportAsFixedFormat |
| 保存先 | Googleドライブ | ローカルフォルダ、社内共有フォルダなど |
| PC依存 | 比較的少ない | ExcelやPC環境への依存が大きい |
| 共有のしやすさ | ドライブURLを利用しやすい | メール添付や共有サーバーへの配置などが中心 |
| Gmail連携 | GAS内で連携しやすい | Outlook連携など別の仕組みが必要になることが多い |
どちらが優れているというより、Google Workspace中心の職場ならGAS、Excel中心の職場ならVBAという使い分けが実務的です。
Excel VBAを使ったPDF一括保存については、以下の記事で詳しく解説しています。
【Excel VBA】ワンクリックでPDFを一括保存する方法
実務で使う際の注意点・エラー対策
1. 初回実行時はOAuth権限の承認が必要
今回のスクリプトでは、スプレッドシートの読み書きに加えて、Googleドライブへのファイル作成やPDF取得を行います。
そのため、初回実行時にはGoogleアカウントの権限承認画面が表示されます。
基本的な流れは次のとおりです。
- Apps ScriptエディタからexportInvoiceToPdfを実行する
- 「承認が必要です」などの案内が表示されたら権限確認へ進む
- スクリプトを実行するGoogleアカウントを選択する
- 表示されたアクセス権限の内容を確認する
- 内容に問題がなければ許可する
2. 「Unexpected error while getting the method or property getFolderById」が出る場合
DriveApp.getFolderById()周辺でエラーになる場合は、まずフォルダIDを確認してください。
特によくある原因は次のとおりです。
- フォルダURL全体をFOLDER_IDへ入力している
- フォルダIDをコピーする際に文字が欠けている
- 対象フォルダへのアクセス権限がない
- 別のGoogleアカウントが所有するフォルダへアクセスしようとしている
また、共有ドライブなど組織管理された環境では、権限設定によってファイル作成が制限されていることもあります。
3. 「指定したシートが見つかりません」と表示される場合
次の設定値と、実際のシート名が完全一致しているか確認してください。
const SHEET_NAME = "請求書";
「請求書」と「請求書 」のように末尾へスペースが入っている場合も別名として扱われるため注意しましょう。
4. PDFが横にはみ出す場合
列数が多い帳票では、A4縦向きでは文字が小さくなったり、レイアウトが崩れたりすることがあります。
その場合は、まずportrait=falseへ変更して横向きを試してください。
"portrait=false"
さらに、不要な列を印刷範囲から除外したり、シート上の列幅そのものを調整したりすると改善できます。
5. 余白なしにすると帳票が窮屈になる場合がある
今回のサンプルでは、上下左右の余白を0にしています。
"top_margin=0",
"bottom_margin=0",
"left_margin=0",
"right_margin=0"
ただし、請求書のデザインによっては端まで詰まりすぎることがあります。その場合は、たとえば0.25程度の余白を設定して調整してください。
"top_margin=0.25",
"bottom_margin=0.25",
"left_margin=0.25",
"right_margin=0.25"
6. 同じ顧客・同じ日付で何度も実行すると同名PDFが増える
Googleドライブでは、同じフォルダ内に同名のファイルを複数作成できます。
そのため、同じ顧客名・同じ日付の状態で何度も実行すると、見た目上は同じ名前のPDFが複数保存されます。
実務では、運用に応じて次のような方法を検討するとよいでしょう。
- 請求番号をファイル名へ追加する
- 生成時刻をファイル名へ追加する
- 同名ファイルがあれば既存ファイルを削除してから作成する
- 「確定後のみPDF生成」といった業務ルールを設ける
たとえば請求番号がA2セルにあるなら、「【請求書】INV-001_株式会社サンプル_20260904.pdf」のようにすると、ファイルを識別しやすくなります。
GASをVBA経験者が学ぶときのポイント
VBA経験者であれば、GASも基本的な考え方はそれほど難しくありません。
たとえば今回の処理をVBAと対応させて考えると、イメージしやすくなります。
| 処理 | GAS | VBAの感覚 |
|---|---|---|
| シート取得 | getSheetByName() | Worksheets(“請求書”) |
| セル取得 | getRange() | Range() |
| PDF化 | PDFエクスポートURLへアクセス | ExportAsFixedFormat |
| ファイル保存 | DriveApp / createFile() | ローカルパスへ保存 |
VBA経験者向けにGASの基本を整理した記事もありますので、「GASは初めて」という方はこちらから読むと理解しやすいです。
VBA経験者向けGAS超入門|Excelマクロ経験を活かしてGoogle Apps Scriptを始める方法
まとめ
今回は、GASでGoogleスプレッドシートをPDF化し、Googleドライブの指定フォルダへ自動保存する方法を紹介しました。
今回の仕組みを使えば、これまで手作業で行っていた「PDFダウンロード → フォルダ移動 → リネーム」という一連の定型作業を、スプレッドシート上のボタン1つにまとめられます。
ポイントを整理すると、次のとおりです。
- DriveApp.getFolderById()で保存先フォルダを取得する
- getSheetId()を使って特定シートだけをPDF化する
- PDFエクスポートURLでA4、縦横、余白、グリッド線などを指定する
- UrlFetchApp.fetch()でPDFデータを取得する
- folder.createFile()でGoogleドライブへ直接保存する
- 顧客名や日付などのセル値からファイル名を自動生成できる
- 生成したPDFのURLとタイムスタンプをシートへ記録できる
- Gmailと組み合わせれば、PDF生成からメール送信まで自動化できる
請求書・見積書・納品書・月次報告書など、定型フォーマットの帳票を日常的に扱っている職場では、非常に効果の高い自動化です。
まずは今回のコードをコピーし、FOLDER_ID、SHEET_NAME、CUSTOMER_CELL、DATE_CELLの4か所を自分の環境へ合わせて変更してみてください。
