毎月の締め作業の時期になると、請求書の作成・PDF化・宛先確認・メール添付・送信作業に追われていませんか?件数が10件〜20件程度であれば手用でもなんとかなりますが、取引先が増えて数十件、数百件となると、作業時間は膨大になり、手作業による宛先間違いや添付ミスなどの重大なリスク(情報漏洩)も高まります。
本記事では、SaaS型の請求書発行ツールを導入せずに、Googleスプレッドシート、Googleドキュメント、そしてGoogle Apps Script(GAS)だけを使って、完全自動で「請求書PDF生成」から「宛先別のGmail一括送信」までを完結させるシステム構築方法を徹底解説します。
1. システムの全体像と仕組み
まずは今回構築するシステムの全体フローと仕組みを理解しましょう。
| 要素 | 使用するツール | 役割・処理内容 |
|---|---|---|
| データ管理 | Googleスプレッドシート | 取引先名、メールアドレス、請求金額、品目、請求日などのマスターデータを管理。発行ステータスもここで保持。 |
| デザインテンプレート | Googleドキュメント | 請求書のレイアウト定義。{{会社名}}や{{請求金額}}などの置換タグ(プレースホルダー)を配置。 |
| 自動化エンジン | Google Apps Script (GAS) | スプレッドシートの行データを順次読み込み、ドキュメントのタグを一時的に置換してPDF化し、Gmailで送信。 |
この仕組みのメリットは、既存のGoogleアカウントがあれば完全無料で運用できる点と、自社の業務フローに合わせてレイアウトや送信文面を自由自在にカスタマイズできる点です。
2. 事前準備:スプレッドシートとテンプレートドキュメントの作成
① スプレッドシートのレイアウト作成
新規Googleスプレッドシートを作成し、シート名を「請求データ」とします。1行目に以下のヘッダーを設定し、テストデータを入力してください。
- A列: 請求書番号(例: INV-2026-001)
- B列: 取引先名(例: 株式会社サンプル)
- C列: 担当者名(例: 山田 太郎)
- D列: メールアドレス(例: test@example.com)
- E列: 件名(例: 業務委託対価)
- F列: 金額(税込)(例: 110000)
- G列: 発行日(例: 2026/09/30)
- H列: ステータス(未発行 / 送信完了 などの実行ログ用)
② テンプレート用Googleドキュメントの作成
新規Googleドキュメントを作成し、請求書のデザインを作成します。置換したい箇所には {{ }} で囲んだ文字列を記述します。
【請求書】
請求書番号: {{請求書番号}}
発行日: {{発行日}}
{{取引先名}}
{{担当者名}} 様
下記の通りご請求申し上げます。
ご請求金額: ¥{{金額}} (税込)
件名: {{件名}}
--------------------------------------------------
振込先口座: 〇〇銀行 サンプル支店 普通 1234567
お振込期限: 翌月末日
--------------------------------------------------
※ GoogleドキュメントのURLに含まれるID(https://docs.google.com/document/d/【ここの文字列】/edit)をメモしておいてください。
3. コピペで動く!GASソースコード
スプレッドシートのメニュー「拡張機能」>「Apps Script」を開き、デフォルトのコードを消去して以下のコードを貼り付けてください。TEMPLATE_DOC_ID はご自身のドキュメントIDに置き換えてください。
const CONFIG = {
TEMPLATE_DOC_ID: 'YOUR_DOCUMENT_ID_HERE', // ここに作成したドキュメントIDを貼り付け
SHEET_NAME: '請求データ'
};
function generateAndSendInvoices() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(CONFIG.SHEET_NAME);
const data = sheet.getDataRange().getValues();
// ヘッダー行をスキップして処理
for (let i = 1; i < data.length; i++) {
const row = data[i];
const docNo = row[0];
const clientName = row[1];
const contactName = row[2];
const email = row[3];
const subjectItem = row[4];
const amount = Number(row[5]).toLocaleString();
const issueDate = Utilities.formatDate(new Date(row[6]), "JST", "yyyy/MM/dd");
const status = row[7];
// すでに送信完了している行はスキップ
if (status === '送信完了' || !email) continue;
try {
// 1. テンプレートドキュメントを一時コピー
const templateFile = DriveApp.getFileById(CONFIG.TEMPLATE_DOC_ID);
const tempFile = templateFile.makeCopy(`請求書_${docNo}_${clientName}`);
const tempDoc = DocumentApp.openById(tempFile.getId());
const body = tempDoc.getBody();
// 2. プレースホルダーの置換
body.replaceText('{{請求書番号}}', docNo);
body.replaceText('{{発行日}}', issueDate);
body.replaceText('{{取引先名}}', clientName);
body.replaceText('{{担当者名}}', contactName);
body.replaceText('{{件名}}', subjectItem);
body.replaceText('{{金額}}', amount);
tempDoc.saveAndClose();
// 3. PDFの作成
const pdfBlob = tempFile.getAs('application/pdf').setName(`請求書_${docNo}_${clientName}.pdf`);
// 4. メール本文作成と送信
const mailSubject = `【ご請求書】${subjectItem}のご案内(${docNo})`;
const mailBody = `${clientName}\n${contactName} 様\n\n`
+ `お世話になっております。\n`
+ `今月分の請求書をお送りいたします。添付のPDFをご確認ください。\n\n`
+ `--------------------------------------------------\n`
+ `請求書番号: ${docNo}\n`
+ `請求金額: ¥${amount} (税込)\n`
+ `--------------------------------------------------\n\n`
+ `何卒よろしくお願い申し上げます。`;
GmailApp.sendEmail(email, mailSubject, mailBody, {
attachments: [pdfBlob]
});
// 5. 一時ファイルの削除とステータス更新
tempFile.setTrashed(true);
sheet.getRange(i + 1, 8).setValue('送信完了');
Logger.log(`成功: ${clientName} 様宛 (${docNo})`);
} catch (error) {
Logger.log(`エラー: 行 ${i + 1} - ${error.toString()}`);
sheet.getRange(i + 1, 8).setValue(`エラー: ${error.message}`);
}
}
}
4. トラブルシューティングと運用の注意点
初回の実行時には「承認が必要」というポップアップが表示されますので、権限を許可してください。運用上でハマりがちなポイントと対策は以下の通りです。
運用のポイントとエラー対処:
- Gmailの送信上限(Quota): 無料のGoogleアカウントの場合は1日100通まで、Google Workspaceアカウントの場合は1日1,500通までの送信制限があります。大量送信を行う場合は分割実行ロジックを組み込みましょう。
- 一時ファイルの消去忘れ: GAS上で作成した一時ドキュメントは tempFile.setTrashed(true) でゴミ箱に送る処理を入れています。これがないとGoogleドライブが不要なファイルで溢れてしまいます。
- 日付と数値のフォーマット: スプレッドシートから読み込んだ数値はそのまま表示すると「100000」となって見づらいため、toLocaleString() でカンマ区切り(100,000)に整形しています。
5. まとめ
本システムを導入することで、これまで手作業で行っていた「請求書作成→PDF化→宛先チェック→メール添付」という毎月の一連の作業が、ボタン一つで完全自動化されます。人件費の削減だけでなく、手作業による誤送信事故を未然に防ぐことができるため、バックオフィスの生産性は飛躍的に向上します。ぜひ自社の運用に合わせてアレンジしてみてください。

