GoogleAppScriptでGoogleドキュメントの差し込み印刷・PDF発行する

# 概要
## はじめに
本記事は、[Google Apps Script Advent Calendar 2020](https://qiita.com/advent-calendar/2020/google-apps-script)の25日目の記事です。

ほんとうはTrelloと組み合わせでの機能について書くつもりだったのですが、こちらのほうが面白そうでしたので、書くことにしました。書くつもりだった記事は、後日書きます。

## 作ったもの
難病患者や介助者は、入院書類や行政サービスを受けるのにたくさんの書類を書く必要があります。そうした書類の記述の一部を助けるため、書類を自動発行するLINEボット「[OneDoc](https://protopedia.net/prototype/2058)」のプロトタイプを作りました。今回はその機能のうち、差し込み印刷・PDF発行に絞ってご紹介します。
※現在は、速度向上のためFirebaseを活用しています

## 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90313/98fbeba7-35c1-b06e-8eb5-b4e10ee2795c.png)

## ソースコード
全ソースコードは[Github](https://github.com/CODE-for-GIFU/OneDoc_GAS)に掲載しています。

# 必要なもの

## 差し込み対象のGoogleドキュメントID
この部分をコピーしておきます。※IDはダミー
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90313/11b76746-58fb-5bc6-9fd7-6e15cc36e5f1.jpeg)

## 差し込み対象のGoogleドキュメントの編集
また、差し込みコードを以下のように準備しておきます。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90313/e0ab5d82-4b76-2e6f-a39b-49d662309eb3.jpeg)

## 差し込んだ書類を格納するGoogleドライブのID
この部分をコピーしておきます。※IDはダミー
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90313/2ffc17c6-8536-3407-cd09-f11636da8cb7.jpeg)


# 実装
## 差し込み用ファイルの取得
```javascript
      var src_doc = DriveApp.getFileById(dat[i][1]);
      var des_drive = DriveApp.getFolderById(des_drive_id);
      var fileName = doc_id+Moment.moment().format("YYYYMMDD_HHmmss");
      var duplicateDocument   = src_doc.makeCopy(fileName, des_drive);
      var duplicateDocumentId = duplicateDocument.getId();
      var des_doc = DocumentApp.openById(duplicateDocumentId);

      var body = des_doc.getBody();
```

* 元ファイルを取得
* 差し込み用に元ファイルのコピーを格納用のGoogleドライブに格納
* コピーしたGoogleドキュメントのIDを取得

## 差し込み
```javascript
      var body = des_doc.getBody();
      
      body.replaceText("{today}", Moment.moment().format("YYYY年M月D日"));
      body.replaceText("{user-fullname}", user_fullname);
      body.replaceText("{user-furigana}", user_furigana);
      body.replaceText("{user-birthday}", user_birthday);
      body.replaceText("{user-postcode}", user_postcode);
      body.replaceText("{user-address}",  user_address);
      body.replaceText("{user-phonenumber}",  user_phonenumber);
      body.replaceText("{user-email}",  user_email);
      
      des_doc.saveAndClose();
```

* コピーしたGoogleドキュメントのファイル名を変更
* replaceTextにてGoogleドキュメントを差し込みコードで更新
* 実装では、Googleスプレッドシートから差込データを取得している(本件では割愛)

##  PDF印刷
```javascript
 var des_url = 'https://docs.google.com/document/d/'+ duplicateDocumentId +'/export?';
      const opts         = {
        exportFormat: 'pdf',      // ファイル形式の指定 pdf / csv / xls / xlsx
        format:       'pdf',      // ファイル形式の指定 pdf / csv / xls / xlsx
        size:         'A4',       // 用紙サイズの指定 legal / letter / A4
        portrait:     'true',     // true → 縦向き、false → 横向き
        fitw:         'true',     // 幅を用紙に合わせるか
        docNames:     'false',    // シート名を PDF 上部に表示するか
        printtitle:   'false',    // スプレッドシート名を PDF 上部に表示するか
        pagenumbers:  'false',    // ページ番号の有無
        gridlines:    'false',    // グリッドラインの表示有無
        fzr:          'false',    // 固定行の表示有無
        range :       'A1%3AA1',  // 対象範囲「%3A」 = : (コロン)  
        
      };
      const urlExt = [];
      for(optName in opts){
        urlExt.push(optName + '=' + opts[optName]);
      }
      const options  = urlExt.join('&');
      const token    = ScriptApp.getOAuthToken();
      const response = UrlFetchApp.fetch(des_url + options, {headers: {'Authorization': 'Bearer ' +  token}});
      const blob = response.getBlob().setName(fileName + '.pdf');
      var pdf_url = des_drive.createFile(blob).getUrl();  //　PDFを指定したフォルダに保存してURLを取得
      return pdf_url;
```

* PDFのパラメータを設定し、PDFを作成
* 作成したPDFの外部公開用URLを取得
* 実装では、このURLリンクをLINEボットを介してユーザーに出力していた(本件では割愛)

# 終わりに
## 課題
* Googleスプレッドシートでの検索処理が重く、本番用環境ではGASは採用されませんでした。実装することで精一杯だったけど、次のアプリでは速度にもこだわりたい。

## 参考
* [Google Apps Script 活用事例　Google Documentを任意のGoogle DriveのフォルダにPDF変換してアップロードするスクリプト](https://note.com/nepia_infinity/n/nee3897455855)