GASでスプレッドシートを
自動でPDF化してGmailで送る方法
請求書や月次レポートを、スプレッドシートからexportURLでPDF化し、Gmailで自動送信する方法を、そのまま動くコードで解説します。用紙サイズや余白の指定、日付付きファイル名、定期トリガーまで紹介します。
Table of Contents
スプレッドシートのPDF送信を自動化するメリット
請求書や月次レポートを、毎回手作業で「ファイル → ダウンロード → PDF」と操作し、メールに添付して送るのは手間がかかります。GAS(Google Apps Script、Googleのサービスを自動化できるスクリプト環境)を使えば、この一連の流れをまるごと自動化できます。
手作業の削減
ダウンロードと添付の繰り返しをなくし、月末の定型作業を丸ごと自動化できる
送り忘れ・遅延の防止
定期トリガーで決まった日に自動送信するので、うっかり忘れが起きない
見た目を統一
余白や向きを固定でき、毎回同じ整ったレイアウトのPDFを出力できる
履歴が残る
同じ処理でDriveにも保存すれば、月ごとのPDFが自動でアーカイブされる
最小構成:ブック全体をPDFにして送る
まずは一番シンプルな方法です。getAs(MimeType.PDF)(スプレッドシートをPDF形式のデータに変換する関数)でブック全体をPDF化し、GmailApp.sendEmail()に添付として渡すだけです。細かいレイアウト指定は不要で、とにかく送りたいときに向いています。
// ブック全体をPDF化してメールで送る(最小構成)
function sendBookAsPdf() {
const ss = SpreadsheetApp.getActive();
const blob = ss.getAs(MimeType.PDF).setName(ss.getName() + ".pdf");
GmailApp.sendEmail(
"reader@example.com", // 送信先
"月次レポート", // 件名
"PDFを添付します。", // 本文
{ attachments: [blob] }
);
}この方法はお手軽ですが、シートの指定や余白の調整ができません。複数シートのうち1枚だけを、整ったレイアウトで送りたい場合は、次のexport URL方式を使います。
特定シートだけをPDF化する(export URL方式)
スプレッドシートには、URLの末尾を/export?format=pdfにするとPDFをダウンロードできる仕組みがあります。GASからこのURLを叩けば、シート単位・レイアウト指定つきでPDF化できます。ポイントはScriptApp.getOAuthToken()(実行中ユーザーの認証トークンを取り出す関数)をAuthorizationヘッダーに付けることです。これがないと非公開シートは取得できません。
// 特定シートだけをPDF化する(export URL方式)
function exportSheetAsPdf() {
const ss = SpreadsheetApp.getActive();
const sheet = ss.getSheetByName("請求書");
// export?format=pdf のURLを組み立てる
const url =
"https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?" +
"format=pdf" +
"&gid=" + sheet.getSheetId() + // このシートだけ対象にする
"&size=A4" +
"&portrait=true" + // 縦向き
"&fitw=true" + // 横幅をページ幅に合わせる
"&gridlines=false" + // 枠線を消す
"&sheetnames=false&printtitle=false"; // ヘッダー・フッターを消す
// ログイン中ユーザーのアクセストークンを付けて取得
const token = ScriptApp.getOAuthToken();
const response = UrlFetchApp.fetch(url, {
headers: { Authorization: "Bearer " + token },
muteHttpExceptions: true,
});
return response.getBlob().setName("請求書.pdf");
}gidにはsheet.getSheetId()で取得したシートIDを渡します。これで、そのシートだけがPDFの対象になります。
用紙サイズ・余白・向きを指定する
export URLには、レイアウトを制御するクエリパラメータを追加できます。パラメータが増えると読みにくくなるので、オブジェクトにまとめてから連結すると管理しやすくなります。よく使う指定は次のとおりです。
size=A4
用紙サイズ。A3・letter なども指定可能
portrait=true / false
true で縦向き、false で横向き
fitw=true
横幅をページ幅に収める(はみ出し防止)
gridlines=false
セルの枠線を非表示にする
top_margin など
上下左右の余白をインチ単位で指定
printtitle / sheetnames=false
ヘッダーのタイトル・シート名を非表示に
// レイアウトを細かく指定してPDFのBlobを返す
function buildPdfBlob(sheet, fileName) {
const ss = SpreadsheetApp.getActive();
const params = {
format: "pdf",
gid: sheet.getSheetId(),
size: "A4",
portrait: "true",
fitw: "true",
gridlines: "false",
printtitle: "false",
sheetnames: "false",
top_margin: "0.5", // 上余白(インチ)
bottom_margin: "0.5",
left_margin: "0.5",
right_margin: "0.5",
};
// オブジェクトをクエリ文字列に変換
const query = Object.keys(params)
.map((key) => key + "=" + encodeURIComponent(params[key]))
.join("&");
const url =
"https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?" + query;
const response = UrlFetchApp.fetch(url, {
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true,
});
return response.getBlob().setName(fileName);
}日付付きファイル名でDrive保存とメール送信
実務では、PDFのファイル名に年月を入れておくと後から探しやすくなります。Utilities.formatDate()(日付を指定した書式の文字列に変換する関数)でタイムゾーンをAsia/Tokyoに固定するのがポイントです。同じ関数の中でDriveにも保存しておけば、送信履歴が自動で残ります。
// 日付付きファイル名でDriveに保存し、メールで送る
function sendMonthlyInvoice() {
const ss = SpreadsheetApp.getActive();
const sheet = ss.getSheetByName("請求書");
// 例: 2026-07 のような年月文字列を作る
const ym = Utilities.formatDate(
new Date(),
"Asia/Tokyo",
"yyyy-MM"
);
const fileName = "請求書_" + ym + ".pdf";
const blob = buildPdfBlob(sheet, fileName);
// Driveの指定フォルダに保存(履歴として残す)
const folder = DriveApp.getFolderById("フォルダIDをここに");
folder.createFile(blob);
// メールで送信
GmailApp.sendEmail(
"reader@example.com",
ym + " 請求書のご送付",
"今月の請求書を添付いたします。ご確認ください。",
{ attachments: [blob], name: "経理担当" }
);
}毎月1日に自動送信するトリガー
最後に、時間主導トリガー(決めた時刻に関数を自動実行する仕組み)を設定します。onMonthDay(1)で毎月1日に、atHour(9)で9時台に実行します。トリガーを作る関数は一度だけ手動で実行すれば設定完了です。二重登録を防ぐため、既存の同名トリガーを消してから作り直しています。
// 毎月1日の朝9時に自動送信するトリガーを作る
function createMonthlyTrigger() {
// 二重登録を避けるため既存のトリガーを削除
ScriptApp.getProjectTriggers().forEach((t) => {
if (t.getHandlerFunction() === "sendMonthlyInvoice") {
ScriptApp.deleteTrigger(t);
}
});
ScriptApp.newTrigger("sendMonthlyInvoice")
.timeBased()
.onMonthDay(1) // 毎月1日
.atHour(9) // 9時台に実行
.create();
}実務での注意点
1. 初回実行時に権限の承認が必要
スプレッドシート・Drive・Gmailにアクセスするため、最初の実行で権限承認のダイアログが表示されます。承認しないとトリガーも動きません。自分のアカウントで一度手動実行して承認しておきましょう。
2. Gmailの送信数には上限がある
GmailApp.sendEmailには1日あたりの送信上限(無料アカウントで100通程度、Google Workspaceで1500通程度)があります。大量送信する場合は宛先をまとめる、送信間隔をあけるなどの配慮が必要です。
3. 送信前に下書き保存でテストする
いきなり本番の宛先に送るのは危険です。動作確認の段階ではGmailApp.createDraft()で下書きとして保存し、PDFの中身とレイアウトを目視で確認してから本番に切り替えると安全です。
4. 大きなシートはタイムアウトに注意
データ量が多いシートはPDF生成に時間がかかり、GASの実行時間制限(1回あたり6分)に近づくことがあります。対象範囲を絞る、印刷したい範囲だけ別シートにコピーするなどで軽くできます。
まとめ
GASでのスプレッドシートPDF送信は、export URLとOAuthトークンを組み合わせることで、シート単位・レイアウト指定つきで自動化できます。日付付きファイル名でDriveに保存し、月次トリガーで定期送信すれば、請求書や月次レポートの送付作業を人手なしで回せます。まずは下書き保存で見た目を確認し、問題なければ本番の宛先に切り替えるのが安全な進め方です。
よくある質問
スプレッドシートの「export?format=pdf」URLを、ScriptApp.getOAuthToken()で取得したアクセストークンを付けてUrlFetchAppで取得する方法が最も確実です。getAs(MimeType.PDF)でもPDF化できますが、シートやセル範囲の指定・余白・向きなどを細かく制御したい場合はexport URL方式が向いています。
できます。export URLに「gid=シートID」を付けると、そのシートだけをPDF化できます。シートIDはsheet.getSheetId()で取得できます。gidを付けないとブック全体が対象になります。
できます。export URLのクエリパラメータで、size=A4(用紙サイズ)、portrait=true(縦向き)、fitw=true(横幅をページ幅に合わせる)、gridlines=false(枠線を消す)、top_margin / bottom_margin(余白)などを指定できます。請求書や帳票を整った見た目で出力したいときに使います。
できます。時間主導トリガー(ScriptApp.newTrigger)でonMonthDay(1)などを指定すれば、毎月1日に自動でPDF化とメール送信を実行できます。月次レポートや請求書の定期送付に向いています。
blob.setName()でファイル名を自由に指定できます。Utilities.formatDate()で「2026-07」のような年月文字列を作り、ファイル名に埋め込むと、月ごとに区別しやすくなります。同じ関数の中でDriveにも保存しておけば履歴として残せます。