GASからGoogleドキュメントを操作する方法

# はじめに
この記事は「[Ateam LifeDesign Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ateam-life-design)」で完走賞を狙って25記事書いているうちの14日目の記事です。今年も完走目指して頑張るぞ！

今日はGASからGoogleドキュメントを操作する方法についてみていきます。

# GASからGoogleドキュメントを操作する方法
GASからGoogleドキュメントを操作するためには[DocumentApp](https://developers.google.com/apps-script/reference/document/document-app?hl=ja)クラスや[Document](https://developers.google.com/apps-script/reference/document/document?hl=ja)クラスを使います。

# サンプル

いくつかサンプルコードをあげながら操作についてみていきましょう。

## Googleドキュメントの作成
新しいGoogleドキュメントを作成するには、以下のようなコードを使用します。

```javascript
function createGoogleDoc() {
  var doc = DocumentApp.create('新しいドキュメント'); // ドキュメントの名前を指定して新規作成
  var docId = doc.getId(); // ドキュメントのID取得
  Logger.log('新しいドキュメントのIDは ' + docId + ' です。');
}
```

## 既存のドキュメントを開く
ドキュメントのIDを使用して既存のドキュメントを開く方法です。

```javascript
function openExistingDocument() {
  var docId = 'ここにドキュメントのIDを入力';
  var existingDoc = DocumentApp.openById(docId);
}
```
## ドキュメントの本文を取得・編集
ドキュメントの本文を取得し、テキストを追加・編集する方法です。サンプルでは新しい段落を追加してみます。

```javascript
function editDocumentBody() {
  var docId = 'ここにドキュメントのIDを入力';
  var doc = DocumentApp.openById(docId);
  var body = doc.getBody();

  // 新しい段落を追加
  body.appendParagraph('新しい段落の追加');
}
```

## テキストのスタイルを変更
ドキュメント内のテキストのスタイルを変更する方法です。

```javascript
function changeTextStyle() {
  var docId = 'ここにドキュメントのIDを入力';
  var doc = DocumentApp.openById(docId);
  var body = doc.getBody();

  // テキストのスタイルを変更
  var text = body.editAsText();
  text.setBold(10, 20, true); // 10文字目から20文字目までを太字にする
  text.setForegroundColor(30, 40, '#FF0000'); // 30文字目から40文字目までを赤色にする
}
```

# 作るもの

これらのサンプルを踏まえて、今回はクライアントへの資料の自動作成を簡易的に実現しようと思います。
- スプレッドシートのA列目にクライアント名がリストとして記載されている
    - <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/fde4c5c3-4ab5-a72b-eda3-96467f58d7c7.png" width="400px">

- 資料のテンプレートはGoogleドキュメントで用意されている
    - ドキュメント内には`{{NAME}}`と書かれた部分があり、ここを各クライアント名で置換してファイルをつくる
        - ![スクリーンショット 2023-12-11 21.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/489aee33-3984-ba1f-82ab-37dd8743b4f8.png)

    - 新たに作られたファイル名は`'顧客向け資料_' + クライアント名`という名前で保存する


# GASを書いていく

```javascript
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet  = spreadsheet.getActiveSheet();
  const templateDocId = 'テンプレートとなるドキュメントのID';
  var lastRow = sheet.getLastRow(); // 最終行を取得
```
ここはもう今までやってきたのと同様にスプレッドシートの情報を取得しています。今回何行目までデータがあるかは不明という前提なので`getLastRow()`でデータが入っている最終行までを見ていくことにします。またテンプレートとなるドキュメントのIDは`templateDocId`として保持しておいてのちのドキュメント操作のところで使っていきます。

```javascript
  for (var i = 1; i <= lastRow; i++) { // 2行目から開始（1行目はヘッダー）
    var customerName = sheet.getRange('A' + i).getValue(); // A列の顧客名を取得

    // テンプレートドキュメントから新しいドキュメントを作成
    var templateDoc = DocumentApp.openById(templateDocId);
    var templateText = templateDoc.getBody().getText();
    var updatedText = templateText.replace('{{NAME}}', customerName);

    // 新しいドキュメントを作成し、顧客名で命名
    var newDoc = DocumentApp.create('顧客向け資料_' + customerName);
    var newDocBody = newDoc.getBody();
    newDocBody.setText(updatedText);
  }
```

`for`ループで1行目から`lastRow`行目まで順に見ていきます。`sheet.getRange('A' + i).getValue()`でA列からクライアント名を取得します。
`DocumentApp.openById(templateDocId)`で先に指定していたドキュメントのIDをもとにテンプレートとなるドキュメントを呼び出します。テンプレートから`templateDoc.getBody().getText()`でテキスト情報を取得し、`replace`関数を使うことで`{{NAME}}`となっていたところに実際のクライアント名を置換していきます。

その後、作ったドキュメントを保存するために`DocumentApp.create`で新たなドキュメントを作成します。ドキュメント名はフォーマットに従って`顧客向け資料_' + customerName`としています。新たなドキュメントを作成したらそのドキュメントの`newDoc.getBody()`で本文を取得し、そこに`setText(updatedText)`することで更新されたテキストを新しいドキュメントに挿入します。
これにより、スプレッドシートから動的に顧客名を取得し、それぞれの顧客名に対応するドキュメントをテンプレートから生成します。

# 完成品がこちら

## GASのコード

```javascript
function generateDocumentsFromTemplate() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet  = spreadsheet.getActiveSheet();
  const templateDocId = 'テンプレートとなるドキュメントのID';
  var lastRow = sheet.getLastRow(); // 最終行を取得

  for (var i = 1; i <= lastRow; i++) { // 2行目から開始（1行目はヘッダー）
    var customerName = sheet.getRange('A' + i).getValue(); // A列の顧客名を取得

    // テンプレートドキュメントから新しいドキュメントを作成
    var templateDoc = DocumentApp.openById(templateDocId);
    var templateText = templateDoc.getBody().getText();
    var updatedText = templateText.replace('{{NAME}}', customerName);

    // 新しいドキュメントを作成し、顧客名で命名
    var newDoc = DocumentApp.create('顧客向け資料_' + customerName);
    var newDocBody = newDoc.getBody();
    newDocBody.setText(updatedText);
  }
}
```

## 実行結果
![スクリーンショット 2023-12-11 21.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/1dee66c4-69c9-a04e-384e-26649c2875f3.png)

テンプレートがクライアント名に置き換わりファイルが生成されていることがわかります。同様のものが株式会社B、株式会社Cについても作成されていました！

# 最後に
今日はGASからGoogleドキュメントを操作する方法についてサンプルコードを添えて見ていきました。今回のサンプルのように一斉に資料を作りたいときや、Googleドキュメントをつかって自動でレポートを作成したいときなどにはこの方法が活用できそうです。