GASでスプレッドシート→請求書PDF自動生成→メール送信 月末3時間を削減
月末になると請求書をExcelやWordで1件ずつ作り、PDFに変換し、メールに添付して送る——この繰り返し作業は、スプレッドシートとGoogle Apps Scriptを組み合わせるだけで自動化できます。追加ツールの契約なしで、月額¥0のまま完結する方法をコードごと公開します。
- 請求データをスプレッドシートの行に入力するだけでPDF請求書が自動生成される
- 生成したPDFはGoogleドライブに自動保存され、同時に取引先へメール送信まで完了
- 外部の請求書サービスは不要。Google標準機能だけで月¥0、発行件数による課金なし
- 本記事のコードはそのままコピーして動く(PDF変換+メール送信+送付済み管理)
- 設定は約40分、必要なのはGoogleアカウントとテンプレート用スプレッドシートのみ
編集長の見解:請求書発行が月末に集中して負担になるのは、入力・PDF化・送付という3つの手作業が分断されているからです。ここで重要なのは、高額な請求書発行サービスに乗り換える前に、Googleが無料で提供している実行環境(GAS)で3つの作業を1本の処理につなげてしまうことです。一度コードを設定すれば、以後は行を埋めるだけで請求書が飛んでいきます。
🔍 なぜ請求書発行に「月3時間」もかかるのか
編集部のシミュレーションでは、取引先20社に毎月請求書を発行する事業者の場合、1件あたり「金額確認→テンプレート複製→PDF変換→メール添付→送付記録」に平均9分かかると、月あたり合計で約3時間の作業になります。これは実際の企業の計測値ではなく、一般的な作業時間から編集部が試算したものです。
この作業のほとんどは、以下の単純な繰り返しです。
- 請求先の名前・金額・請求書番号をテンプレートに転記する
- 完成したシートをPDFとして書き出す
- ファイルを添付してメールを作成し、送信する
- どこまで送ったかをExcelやメモで管理する
Google Apps Script(以下GAS)は、Googleアカウントに無料で付属するプログラム実行環境です。スプレッドシート・ドライブ・Gmailの3つに直接アクセスできるため、この一連の流れをまとめて自動化できます。
- 費用: 個人向けGoogleアカウントでも無料で利用可能
- 件数: 発行件数による従量課金がなく、取引先が増えても金額は変わらない
- 依存度: 外部の請求書クラウドサービス(SaaS)の値上げや仕様変更に振り回されない
代わりに必要なのは「テンプレートを整えてコードを貼る」という最初の一手間だけです。次のセクションで全体の流れを図で確認します。
🗺 全体フロー — 3ステップで完結
構造はシンプルです。請求リストの行に情報を入力し実行すると、GASがテンプレートへ転記し、PDFへ変換し、ドライブへ保存したうえでメール送信まで行います。
行を埋めて実行するだけ、PDF化と送付は自動
登場する部品は3つです。それぞれの役割を整理します。
| 部品 | 役割 | 公式ドキュメント |
|---|---|---|
| SpreadsheetApp | 請求リストの読み書き、テンプレートへの転記 | SpreadsheetApp リファレンス |
| DriveApp / UrlFetchApp | シートをPDFに変換し、ドライブへ保存 | DriveApp リファレンス |
| MailApp | 生成したPDFを添付してメール送信 | MailApp リファレンス |
この3つをつなぐのが、次のセクションで示すコードです。まずは土台となるスプレッドシートの形を確認します。
💰 必要なものと費用の目安
このレシピも、追加の支出は一切発生しません。用意するものを表で確認してください。
| 必要なもの | 役割 | 費用の目安 |
|---|---|---|
| Googleアカウント(無料 or Workspace) | スプレッドシート・ドライブ・GASの実行 | 無料(Workspaceは既存契約で可) |
| Google Apps Script | PDF生成・メール送信処理の実行環境 | 無料 |
| 請求書テンプレート用シート | 転記先レイアウト(自作) | 無料 |
| 保存用Googleドライブフォルダ | 生成したPDFの保管場所 | 無料枠内で可(容量超過時のみ有料) |
Googleドライブの無料容量(個人アカウントで15GB)は、請求書PDF程度のファイルサイズであれば長期間問題になりません。容量が心配な場合はGoogle One の料金ページで拡張プランを確認してください。
💡 編集部の判断材料:すでにfreeeやMisocaなどの請求書サービスを契約中なら、無理に乗り換える必要はありません。GASが向くのは「これから請求書発行を仕組み化したい」「発行件数が少なくサービス契約が割高に感じる」ケースです。会計freeeと連携した自動化を検討中の方はZapier×freee 請求書発行の自動化レシピも参考になります。
判断がついたら、実際の構築に進みます。
🛠 設定手順 — 約40分で完成
作業は「スプレッドシートの土台を作る」「GAS側でコードを貼る」の2段階です。プログラミングの知識は不要で、コードは本記事のものをそのまま貼り付ければ動きます。
貼り付けるコード(そのまま動きます)
以下をApps Scriptエディタの コード.gs に貼り付けてください。「請求リスト」の未送付行を順に処理する generateAndSendInvoices が本体です。
/**
* 請求リストの未送付行 → 請求書テンプレートへ転記 → PDF化 → ドライブ保存 → メール送信
* 手動実行、または時間主導型トリガーで毎月末に自動実行する
*/
function generateAndSendInvoices() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const listSheet = ss.getSheetByName('請求リスト');
const templateSheet = ss.getSheetByName('請求書テンプレート');
const folderId = PropertiesService.getScriptProperties().getProperty('PDF_FOLDER_ID');
if (!folderId) {
throw new Error('PDF_FOLDER_ID がスクリプトプロパティに未設定です');
}
const folder = DriveApp.getFolderById(folderId);
const data = listSheet.getDataRange().getValues();
// 列位置: 0=会社名 1=請求書番号 2=金額 3=メールアドレス 4=送付状況 5=送付日時
for (let i = 1; i < data.length; i++) {
const row = data[i];
const [company, invoiceNo, amount, email, status] = row;
if (!company || status === '送付済み') continue;
// テンプレートへ転記
templateSheet.getRange('C3').setValue(company);
templateSheet.getRange('C4').setValue(invoiceNo);
templateSheet.getRange('C5').setValue(amount);
templateSheet.getRange('C6').setValue(
Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd')
);
SpreadsheetApp.flush();
// PDF化してドライブに保存
const pdfBlob = exportSheetAsPdf_(ss, templateSheet);
const fileName = '請求書_' + invoiceNo + '_' + company + '.pdf';
const pdfFile = folder.createFile(pdfBlob).setName(fileName);
// メール送信
MailApp.sendEmail({
to: email,
subject: '【請求書】' + invoiceNo + ' ' + company + ' 様',
body:
company + ' 様\n\n' +
'いつもお世話になっております。\n' +
'請求書(' + invoiceNo + ')を添付にてお送りいたします。\n' +
'ご確認のほどよろしくお願いいたします。',
attachments: [pdfFile.getAs(MimeType.PDF)],
});
// 送付済みに更新
listSheet.getRange(i + 1, 5).setValue('送付済み');
listSheet.getRange(i + 1, 6).setValue(new Date());
}
}
/**
* 指定シートをA4のPDFとしてエクスポートし、Blobで返す
*/
function exportSheetAsPdf_(ss, sheet) {
const url =
'https://docs.google.com/spreadsheets/d/' + ss.getId() +
'/export?format=pdf&gid=' + sheet.getSheetId() +
'&size=A4&portrait=true&fitw=true&gridlines=false&printtitle=false';
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + token },
muteHttpExceptions: true,
});
if (response.getResponseCode() !== 200) {
throw new Error('PDF変換に失敗しました (HTTP ' + response.getResponseCode() + ')');
}
return response.getBlob().setName('invoice.pdf');
}
フォルダIDの登録(コードに直書きしない)
STEP 4で控えたフォルダIDは、コードに直接書かず「スクリプトプロパティ」に保存します。
- Apps Scriptエディタ左の**歯車アイコン(プロジェクトの設定)**を開く
- 最下部の「スクリプト プロパティ」で「スクリプト プロパティを追加」をクリック
- プロパティ名に
PDF_FOLDER_ID、値にSTEP 4のフォルダIDを入力して保存
💡 編集部メモ:毎月同じ日に手動実行するのを忘れそうな場合は、Apps Scriptエディタ左の時計アイコンから「トリガーを追加」し、「時間主導型」→「月タイマー」→希望の日を指定すれば、generateAndSendInvoices が自動で起動します。ただし初回はメール誤送信を避けるため、必ず手動実行で内容を確認してからトリガー化してください。
保存とテスト実行が終わったら、次のセクションでつまずきやすい点を確認します。
⚠️ 失敗パターンと運用上の注意
GASは無料で強力ですが、請求書という性質上、通知系のレシピよりも慎重な確認が必要です。編集部が特に注意すべきと考える2点を挙げます。
⚠️ 失敗パターン1:テストせずに全件へ本番メールが飛ぶ。請求リストに実データを入れたまま初回実行すると、金額確認前の請求書が取引先へ一斉送信されてしまいます。初回は必ず自分宛のメールアドレス1行だけで実行し、PDFの内容とメール文面を確認してから本番データに切り替えてください。
⚠️ 失敗パターン2:PDF変換のURLアクセス権限エラー。exportSheetAsPdf_ はスプレッドシート自身へのアクセス権限(OAuthトークン)を使ってPDFを取得します。スクリプトの実行者アカウントがそのスプレッドシートの閲覧権限を持っていないと、PDF変換が失敗します。共有スプレッドシートで運用する場合は、実行者にも編集権限を付与してください。
初回実行時には、Googleから「このアプリは確認されていません」という趣旨の警告が出ます。これは自分で書いたスクリプトに、自分のデータへのアクセスを許可するための画面です。詳細を開いてプロジェクト名が自分のものであることを確認し、承認すれば先へ進めます。
| トラブル | 起こりやすい原因 | 編集部の対策 |
|---|---|---|
| PDFが空欄・崩れる | テンプレートのセル位置とコードの参照先がズレている | getRange の参照先セルをテンプレートと突き合わせて確認 |
| メールが届かない | メールアドレス列の入力ミス、または未入力 | 送付前に列のメールアドレス形式を目視確認 |
| PDF変換エラー(403系) | 実行アカウントにシートの閲覧・編集権限がない | スプレッドシートの共有設定を確認し権限を付与 |
| 二重送信される | 「送付状況」列の判定が更新されていない | SpreadsheetApp.flush() の位置と列番号のズレを確認 |
なおGASには1日あたりの実行時間や外部通信回数の上限がありますが、請求書1件あたりの処理は数秒で終わるため、月20〜30件程度の発行では通常上限に届きません。詳細はApps Scriptの割り当てと制限を確認してください。次のセクションで、この40分の投資が経営上どう返ってくるかを整理します。
🚀 経営者はこの40分をどう回収するか
編集部の想定シナリオを1つ挙げます。取引先20社と月次契約を結ぶ小規模制作会社が、毎月末に請求書を手作業で発行しているケースです(実在の企業の事例ではありません)。
- 導入前: 1件9分×20件で月合計約3時間、月末の別作業と重なり深夜対応になりがち
- 導入後: 請求リストに20行入力し、1回の実行で全件のPDF生成とメール送付が完了。作業時間は入力の約30分のみ
- 効果: 月末の残業が減り、経理担当が確認・督促などの判断業務に時間を使える
かかった費用は¥0、かかった時間は初回設定の約40分だけです。基本形が動いたら、次の応用も同じコードの延長で組めます。
- 入金確認との連携: 入金が確認できた行に「入金済み」を追記し、督促対象を自動抽出
- 請求書番号の自動採番: 前月の最終番号をシートから読み取り、連番を自動生成
- 弁護士・士業のタイムチャージ集計: 稼働時間の集計から請求金額を自動算出したい場合は弁護士事務所のタイムチャージ集計から請求書発行までを自動化するレシピが参考になります
当サイトでは、請求・経理まわりの自動化を複数紹介しています。あわせて読むと設計の引き出しが増えます。
- Google Apps ScriptでGoogleフォーム回答をSlack即時通知する無料レシピ
- Make.comでAirtable→請求書PDFを自動生成し月3時間削減するレシピ
- Zapier×freee Amazon注文→請求書発行を自動化するレシピ
- n8n×Ollamaで請求書PDFの読み取りを自社完結で自動化するレシピ
編集部のまとめ:このレシピの本質は「入力・PDF化・送付という3つの手作業を、1本のスクリプトに統合する」ことです。GASを選べば、その仕組みを月¥0で、発行件数が増えても値上がりしない形で持てます。まずは自分宛のテスト送信で動作を確認し、そのうえで入金管理や自動採番といった応用へ進むのが堅実な順序です。
出典・参考情報
- Google Apps Script 公式サイト
- SpreadsheetApp リファレンス
- DriveApp リファレンス
- MailApp リファレンス
- Apps Scriptの割り当てと制限
- Google One 料金プラン
Mira / AI経営ラボ 編集長