Excelのテンプレートに値を入れてPDFとして出力するPowerAutomateフロー

# Excelのテンプレートを使った請求書の自動発行
手作業で行っていた下記のような請求書発行の手順を、PowerAutomateで自動化することを考えます。

1. 顧客管理システムなどから下記請求情報を取得
   - 顧客会社名
   - 請求書番号
   - 請求日
   - 支払期限
1. 取得した情報をExcelのテンプレートに転記
1. Excelのテンプレートを"{請求書番号}_{顧客会社名}.pdf"の名前で保存

## Excelテンプレート
サンプルとして、下記テンプレートを使います。
赤い文字の部分を置き換えたものをPDFとして出力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/74329e26-400f-f2f7-44a9-aebaea45aff3.png)

:::note info
こちらのテンプレートは、Excelでシート作成時に選択可能な「基本的なビジネス請求書」というテンプレートをベースにしています。
:::


Excelのテンプレートは OneDrive for buisness の個人用フォルダに格納しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/4752d4d8-d606-034a-e909-23cbb7d07c47.png)


:::note info
ExcelをPDFに変換するアクションがOneDrive上に置いたファイルでのみ使えるようです。
SharePointのファイルを利用したい場合、PDFに変換する前にファイルを一度OneDriveにコピーするなどひと手間かける必要があります。
:::

## Officeスクリプト
Excelテンプレートに値を転記する処理はOfficeスクリプトを利用します。
OfficeスクリプトはExcel上で動作するプログラミング言語です。TypeScriptで記述し、PowerAutomateからの実行をサポートしています。

- ExcelのテンプレートファイルをWeb上のOneDriveで開きます。
- 「自動化」タブをクリックし、「新しいスクリプト」ボタンをクリックします。
- コードエディタが開くので、下記のコードを入力します。
- スクリプト名を「請求書作成」に変更し、保存します。

スクリプトは、PowerAutomateから受け取った値を所定のセルに設定するだけの単純なものです。
値はmain関数の引数で受け取ることができます。

```typescript
function main(
  workbook: ExcelScript.Workbook,
  company: string,
  invoiceNumber: string,
  dateOfInvoice: string,
  dueDate: string
) {
  let sheet = workbook.getWorksheet("請求書");
  sheet.getCell(3, 1).setValue('請求書番号: '+ invoiceNumber);
  sheet.getCell(4, 1).setValue('日付: ' + dateOfInvoice);
  sheet.getCell(6, 1).setValue(company+ '様');
  sheet.getCell(8, 1).setValue('支払期限: ' + dueDate);
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/ea57ba5e-fa4f-2394-2b20-95af48707bf1.png)

## フローの作成

作成するフローの概要は下記のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/479a1e33-7081-af5a-d3ce-f42f3cdadc24.png)

### 手動でフローをトリガー
今回は検証目的ですので、手動で実行するようにしています。
実際はタイマーによる定期実行など、利用するシステムに合わせたトリガーを選択します。

### 請求書情報を取得
今回は「変数の初期化」を使ってinputという変数に固定値のJSONを入れていますが、顧客管理システムのAPIなどから取得した請求情報が入っているものと思ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/9ebf7383-1810-cf4c-cd22-19f9591ba953.png)

### JSONの解析
先ほどのinput変数に入っているJSONを解析します。
スキーマは「サンプルから生成」ボタンで開くダイアログにJSONの値を貼り付けて生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/94b46f90-4517-77cb-1479-69fe665ea137.png)

### Excelテンプレートファイルを取得
OnDrive for business の「ファイル コンテンツの取得」を利用して、Excelテンプレートファイルを読み取ります。
OneDriveに配置したExcelテンプレートファイルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/d54b822c-e967-8959-e9cb-96ab6959acd1.png)

### 一時ファイルの作成
OnDrive for business の「ファイルの作成」を利用してテンプレートファイルをコピーします。
テンプレートと同じフォルダに"{請求書番号}_{請求先会社名}.xlsx"の名前でファイルを作成します。
「ファイルコンテンツ」には「Excelテンプレートファイルを取得」で読み込んだファイルの本文を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/94405c5b-97bb-0a89-da9e-b2d9f89f92ce.png)

### テンプレートに値を書き込むスクリプトの実行
作成した一時ファイルに対して、Officeスクリプトを実行します。
- 「場所」、「ドキュメントライブラリ」、「ファイル」で一時ファイルの場所を指定します。(「ファイル」には「一時ファイルの作成」の結果に含まれる「ID」を指定します。)
- 「スクリプト」では作成したOfficeスクリプトの名前「請求書作成」を選択します。
- スクリプトを選択すると、スクリプトのmain関数に記述した引数が入力項目に追加されます。各項目にinput変数の値を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/651c5d31-0ed4-135c-bd1c-faa5630c6f16.png)

### PDFファイルへの変換
OnDrive for business の「ファイル変換」を利用してExcelファイルをPDFに変換します。
「ファイル」には一時ファイルの「ID」を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/171fa648-6c41-76ba-57e7-bdd5c441a63c.png)

### PDFファイルの作成
OnDrive for business の「ファイルの作成」を利用してPDFに変換したファイルをOneDriveに出力します。
- Excelテンプレートと同じフォルダに出力します。
- 「ファイル名」には「PDFファイルへの変換」の結果に含まれる「ファイル名」を指定します（ここには一時ファイルのファイル名の拡張子が.pdfに変わったものが入っています）。
- 「ファイルコンテンツ」には「PDFファイルへの変換」の結果に含まれる「本文」の値を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/a3b97f07-dbb4-f936-2e37-41b6f5921d53.png)

## 実行結果
このフローを実行すると、Excelテンプレートと同じフォルダに２つのファイルが作成されます。

- 一時ファイル:{請求書番号}_{請求先会社名}.xlsx
- PDF請求書: {請求書番号}_{請求先会社名}.pdf 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/e33cefce-a65e-1669-a9ce-8f5527e8701f.png)

PDF請求書を開いてみると、input変数に設定した値が所定の位置に転記されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28805/162e9e13-75d9-7a36-ada0-b35b13e5156b.png)