GASでGoogleドキュメントを
コードで自動作成・編集する方法

Documentcreate / openByIdgetBody()Body本文コンテナappendParagraph()段落setHeading()見出しappendTable()appendListItem()リスト

GAS の DocumentApp(Googleドキュメントを操作するサービス)を使うと、レポートや帳票をコードで組み立てられます。 作成・見出し・装飾・表・置換までを、動くコードで順に解説します。

|対象: GAS DocumentApp / getBody / appendTable / replaceText

Table of Contents

DocumentApp の基本:作る・開く

Googleドキュメントの操作はDocumentAppから始めます。新規作成はcreate()、本文はgetBody()で取り出します。

// 新しいドキュメントを作って本文を書き込む
function createDoc() {
  const doc = DocumentApp.create('自動生成レポート');
  const body = doc.getBody();

  body.appendParagraph('これは本文の最初の段落です。');
  body.appendParagraph('GASからでも普通の文書と同じように書けます。');

  doc.saveAndClose();       // 変更を確定する
  Logger.log(doc.getUrl()); // 作成したドキュメントのURL
}

すでにあるドキュメントを編集するならopenById()で開きます。IDはドキュメントのURLの/d//editの間の文字列です。

// 既存のドキュメントを開いて編集する
function openDoc() {
  // URLの /d/ と /edit の間がドキュメントID
  const doc = DocumentApp.openById('1AbC...XYZ');
  const body = doc.getBody();

  body.appendParagraph('追記した段落です。');
  doc.saveAndClose();
}

3つの入口の使い分け

コンテナにバインドされたスクリプト(ドキュメントに紐づくスクリプト)ではgetActiveDocument()で開いているドキュメントを直接取得できます。単独のスクリプトからはopenById()openByUrl()を使います。

見出しと箇条書きで構成を組む

appendParagraph()が返す段落にsetHeading()を付けると、見出しスタイル(タイトル・見出し1など)になります。目次生成やナビゲーションにも効きます。 箇条書きはappendListItem()です。

// タイトル・見出し・箇条書きで構成を組み立てる
function buildStructure() {
  const body = DocumentApp.getActiveDocument().getBody();

  body.appendParagraph('月次売上レポート')
      .setHeading(DocumentApp.ParagraphHeading.TITLE);

  body.appendParagraph('1. 概要')
      .setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph('本レポートは今月の売上をまとめたものです。');

  body.appendParagraph('2. 支店別実績')
      .setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendListItem('東京支店:120万円')
      .setGlyphType(DocumentApp.GlyphType.BULLET);
  body.appendListItem('大阪支店:98万円')
      .setGlyphType(DocumentApp.GlyphType.BULLET);
}

ParagraphHeadingにはTITLE/HEADING1HEADING6、通常段落のNORMALがあります。

文字を装飾する(太字・色・サイズ)

装飾には2つのやり方があります。段落全体をまとめて変えるならsetAttributes()が簡単です。段落の一部の文字だけ変えたいときはeditAsText()でテキストにして、文字位置を指定します。

// 文字の装飾(段落全体と、一部だけ)
function styleText() {
  const body = DocumentApp.getActiveDocument().getBody();

  // 段落全体をまとめて装飾(setAttributes が簡単)
  const p = body.appendParagraph('重要:締め切りは月末です');
  p.setAttributes({
    [DocumentApp.Attribute.BOLD]: true,
    [DocumentApp.Attribute.FOREGROUND_COLOR]: '#c00000',
    [DocumentApp.Attribute.FONT_SIZE]: 14,
  });

  // 段落の一部だけ装飾する場合は editAsText で文字位置を指定
  // 位置は0始まり・終了位置は「含む」
  const t = body.appendParagraph('通常の文字と強調文字が混在します。').editAsText();
  t.setBold(0, 3, true); // 「通常の文」を太字にする
}

文字位置の指定に注意

setBold(開始, 終了, true)の位置は0始まりで、終了位置は「含む」点に注意します。setBold(0, 3, true)は0〜3文字目(4文字分)が対象です。JavaScriptの slice の感覚とはズレるので混同しないようにします。

表を差し込む

appendTable()に二次元配列を渡すだけで表になります。スプレッドシートのgetValues()の結果をそのまま渡せるので、集計結果の帳票化と相性が良いです。

// スプレッドシートの二次元配列をそのまま表にする
function addTable() {
  const body = DocumentApp.getActiveDocument().getBody();

  const data = [
    ['支店', '売上', '前年比'],
    ['東京', '120万円', '110%'],
    ['大阪', '98万円', '105%'],
  ];
  const table = body.appendTable(data);

  // 先頭行(ヘッダー)を太字にする
  const header = table.getRow(0);
  for (let c = 0; c < header.getNumCells(); c++) {
    header.getCell(c).editAsText().setBold(true);
  }
}

セルはgetRow()getCell()で取り出し、テキストとして装飾できます。数値をそのまま渡すとエラーになることがあるため、String()で文字列化してから渡すと安全です。

文字列を差し込む・検索して置換する

テンプレートに{{会社名}}のような目印を置いておき、replaceText()で一括置換すると差し込み文書が作れます。特定のキーワードだけ装飾したいときはfindText()で位置を探します。

// プレースホルダの差し込みと、キーワードの色付け
function fillAndHighlight() {
  const body = DocumentApp.getActiveDocument().getBody();

  // {{ }} を実際の値に一括置換(差し込みに便利)
  body.replaceText('{{会社名}}', '株式会社ラスタージ');
  body.replaceText(
    '{{日付}}',
    Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy年MM月dd日')
  );

  // findText で見つけた「締め切り」を全て赤くする
  let found = body.findText('締め切り');
  while (found) {
    const el = found.getElement().asText();
    el.setForegroundColor(
      found.getStartOffset(),
      found.getEndOffsetInclusive(),
      '#c00000'
    );
    found = body.findText('締め切り', found); // 次の一致から続ける
  }
}

findText はループで最後まで回す

findText()は最初の1件を返すだけです。全件処理するには、2つ目の引数に前回の結果を渡して次の一致から探し、 見つからなくなる(null になる)までwhileで回します。

実務での注意点

1. 出力の前に saveAndClose で確定する

編集は自動保存されますが、同じ実行の中でDriveApp経由でPDF化する場合は、その前にsaveAndClose()を呼びます。確定前だと古い状態が出力されることがあります。

// 変更を確定してからPDFとして書き出す
function exportAsPdf() {
  const doc = DocumentApp.getActiveDocument();
  doc.saveAndClose(); // ← 先に確定しないと古い内容が出る

  const file = DriveApp.getFileById(doc.getId());
  const pdf = file.getAs('application/pdf').setName(doc.getName() + '.pdf');
  DriveApp.createFile(pdf);
}

2. 作成場所とフォルダ移動

create()で作ったファイルはマイドライブの直下に置かれます。所定のフォルダにまとめたいときはDriveApp.getFileById(doc.getId()).moveTo(folder)で移動します。

3. 大量生成は実行時間制限に注意

1回の実行は約6分の上限があります。数百件を生成する場合は、処理済み件数をPropertiesServiceに記録し、時間主導トリガーで分割実行するのが安全です。1件ごとにsaveAndClose()することも忘れないようにします。

まとめ

DocumentAppを使えば、レポートや帳票をコードで組み立てて自動生成できます。基本の流れは 「作る・開く → 本文を取り出す → 段落・見出し・表を足す → 装飾・置換 → 確定」の5ステップです。

構成を組む

appendParagraph + setHeading で見出し・箇条書き

見せ方を整える

setAttributes / editAsText で装飾、appendTable で表

差し込む

replaceText でテンプレート差し込み、findText で検索

応用できる業務用途

月次レポート自動生成
請求書・契約書の差し込み
議事録テンプレート作成
PDF化してメール送付

よくある質問

DocumentApp.create('ファイル名') を使います。戻り値の Document から getBody() で本文を取り出し、appendParagraph() などで内容を書き込みます。作成したファイルはマイドライブの直下に置かれるので、必要なら DriveApp でフォルダへ移動します。

DocumentApp.openById('ドキュメントID') または openByUrl('URL') で開きます。IDはドキュメントのURLの /d/ と /edit の間の文字列です。開いたあとは新規作成と同じく getBody() で本文を操作します。

段落を editAsText() で Text 型にしてから、setBold(開始位置, 終了位置, true) のように文字位置(0始まり・終了位置は含む)を指定します。段落全体をまとめて装飾するなら setAttributes() に DocumentApp.Attribute を渡す方が簡単です。

編集は自動保存されますが、同じ実行の中でPDF化やDriveApp経由の読み出しをする場合は、その前に doc.saveAndClose() を呼んで変更を確定してください。確定前だと古い状態が出力されることがあります。

できます。シートの getValues() で取得した二次元配列を、そのまま body.appendTable(データ) に渡すと表になります。数値は String() などで文字列化してから渡すと安全です。

1回の実行は約6分の上限があります。数百件を生成する場合は、処理した件数をPropertiesServiceに記録し、時間主導トリガーで少しずつ処理を分割するのが安全です。1件ずつ saveAndClose() することも忘れないでください。

GAS開発・帳票自動化を
相談する。

Googleドキュメントの自動生成・差し込み文書・PDF出力など、文書業務の自動化もご相談いただけます。 内容が固まっていなくても大丈夫です。現在の業務・課題をお聞きした上でご提案します。

GAS開発の対応範囲を見る