GASでPDF出力——ビジネス文書の自動化
Google Apps ScriptのDocsApp・DriveAppを組み合わせると、Googleスプレッドシートのデータから請求書・領収書・見積書などのPDFを自動生成して、指定のフォルダに保存したりメールで送ったりすることができます。
基本的な仕組み
スプレッドシート(データ)
↓
GAS でGoogleドキュメントのテンプレートをコピー
↓
テンプレート内の{{プレースホルダー}}を置換
↓
PDFに変換
↓
Googleドライブに保存 or メール添付で送信
テンプレートの準備
Googleドキュメントで請求書テンプレートを作成し、プレースホルダーを挿入します。
{{invoice_number}} ← 請求書番号
{{client_name}} ← 宛先
{{issue_date}} ← 発行日
{{due_date}} ← 支払期限
{{subtotal}} ← 小計
{{tax}} ← 消費税
{{total}} ← 合計
GASの実装
const TEMPLATE_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // テンプレートのドキュメントID
const OUTPUT_FOLDER = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'; // 出力先フォルダID
/**
* スプレッドシートから請求書PDFを生成する
* @param {number} row - スプレッドシートのデータ行(1-indexed、ヘッダーを除く)
*/
function generateInvoice(row) {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('請求データ');
const data = sheet.getRange(row + 1, 1, 1, 10).getValues()[0];
const invoiceData = {
invoice_number: data[0],
client_name: data[1],
issue_date: Utilities.formatDate(new Date(data[2]), 'Asia/Tokyo', 'yyyy年MM月dd日'),
due_date: Utilities.formatDate(new Date(data[3]), 'Asia/Tokyo', 'yyyy年MM月dd日'),
subtotal: data[4].toLocaleString(),
tax: data[5].toLocaleString(),
total: data[6].toLocaleString(),
description: data[7],
};
// テンプレートをコピー
const template = DriveApp.getFileById(TEMPLATE_ID);
const folder = DriveApp.getFolderById(OUTPUT_FOLDER);
const docName = `請求書_${invoiceData.invoice_number}_${invoiceData.client_name}`;
const copy = template.makeCopy(docName, folder);
// コピーを開いてプレースホルダーを置換
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
Object.entries(invoiceData).forEach(([key, value]) => {
body.replaceText(`{{${key}}}`, value);
});
doc.saveAndClose();
// PDFに変換
const pdfBlob = copy.getAs('application/pdf').setName(`${docName}.pdf`);
const pdfFile = folder.createFile(pdfBlob);
// 元のドキュメントを削除(PDFのみ残す)
copy.setTrashed(true);
console.log(`PDF生成完了: ${docName}.pdf`);
return pdfFile;
}
一括生成とメール送信
/**
* 未送付の請求書を全て生成してメールで送信
*/
function sendAllPendingInvoices() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('請求データ');
const data = sheet.getDataRange().getValues();
let sentCount = 0;
for (let i = 1; i < data.length; i++) {
const status = data[i][8]; // I列:送付状況
const clientEmail = data[i][9]; // J列:送付先メール
if (status !== '未送付' || !clientEmail) continue;
try {
const pdfFile = generateInvoice(i);
const pdfBlob = pdfFile.getBlob();
// メール送信
GmailApp.sendEmail(
clientEmail,
`【ご請求】株式会社WR からの請求書 No.${data[i][0]}`,
`${data[i][1]} 御中\n\n請求書をPDFで添付いたします。\nご確認のほどよろしくお願いいたします。\n\n株式会社WR\n代表取締役 土田昇`,
{
attachments: [pdfBlob],
name: '株式会社WR',
}
);
// ステータスを更新
sheet.getRange(i + 1, 9).setValue('送付済');
sheet.getRange(i + 1, 11).setValue(new Date());
sentCount++;
// API制限対策
Utilities.sleep(1000);
} catch (error) {
console.error(`行${i + 1}の処理でエラー: ${error.message}`);
sheet.getRange(i + 1, 9).setValue(`エラー: ${error.message}`);
}
}
console.log(`${sentCount}件の請求書を送信しました`);
Browser.msgBox(`${sentCount}件の請求書を送信しました`);
}
月次請求書の自動化
/**
* 毎月末に自動で請求書を生成する
*/
function generateMonthlyInvoices() {
const today = new Date();
const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();
// 月末だけ実行
if (today.getDate() !== lastDay) return;
// サービス利用データを集計して請求データを作成
const billingData = calculateMonthlyBilling();
billingData.forEach(client => {
// 請求データをスプレッドシートに追記
addInvoiceRow(client);
});
// 請求書を生成してメール送信
sendAllPendingInvoices();
// Slackに完了通知
sendSlackNotification(
`月次請求書を${billingData.length}件送信しました(${today.toLocaleDateString('ja-JP')})`
);
}
まとめ
GASによるPDF自動生成は、Googleドキュメントのテンプレート・DriveApp・GmailAppを組み合わせることで、追加コストゼロで実現できます。弊社では月次請求書の自動生成・送付をこの仕組みで運用しており、毎月の手作業を大幅に削減しています。
業務自動化ツールの開発についてはお気軽にご相談ください。