SharePoint ドキュメントライブラリのPDFを #PowerApps で表示する

# はじめに
本投稿は Brian Edwardsさんの投稿を応用した手法の紹介です。
オリジナルの投稿はhttps://masteroffice365.com/viewing-pdfs-from-sharepoint-within-powerapps/ こちらをご覧ください。

*Acknowledgment* : This post is based on the work provided by Brian Edwards linked above. I'm deeply grateful to his work.

# やったこと
SharePointドキュメントライブラリのPDFは、PowerAppsで利用できる標準のSharePointコネクターではサポート外になっています。PDFコントロールにライブラリのURLをセットしても認証の問題から表示することができません。
これを解決するための方法が上記ブログに記載されています。ポイントはFlowを利用して、ライブラリのアイテムのコンテンツを取得し、その結果をResponse to PowerAppsで、ファイルとして返却するというものです。
ここではその方法を発展させ、ライブラリに存在するすべてのドキュメントを配列で返却し、ギャラリーコントロールで表示させる方法を紹介します。


# Flow側

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/d1b2c928-c97e-bd6b-6515-5926d328d8ad.png)

| ステップ      |役割  |
|:--------------------|:-----------------------------------------------------|
| initializeArray      |最後にHTTP ResponseするときのBodyを配列として初期化|
| Get files (properties only)  |対象のライブラリに含まれるファイルのプロパティ（フォルダーパス、ファイル名、拡張子を利用）|
| Get file content using Path  |対象のライブラリの特定のファイルのコンテンツを取得|
| Append to array variable  |Initializeした配列変数に、前のステップで取得したファイルのコンテンツとファイル名を格納|
| Response  |Foreachで取得したコンテンツに基づいて作成された配列要素をBodyとして、特殊なスキーマでResponseを返す|


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/0e131138-78be-9aa6-a6e2-20a30210579b.png)
"Get file content using path" は、ファイルのコンテンツを、ファイルへのパスに基づいて取得するアクションです。
また後続の"Append to array variable"にある fileContent は```body('Get_file_content_using_path')?['$content']``` で指定しています。
※ここで、「ファイルのコンテンツ」は出力をダウンロードすると以下のような形式になっていました。

```FileContent.json
{
    "statusCode": 200,
    "headers": {
        "Transfer-Encoding": "chunked",
        "X-SharePointHealthScore": "2",
        "DATASERVICEVERSION": "3.0",
       （中略）
        "X-Powered-By": "ASP.NET",
        "Content-Disposition": "attachment",
        "Content-Type": "application/pdf",
        "Expires": "Tue, 23 Jul 2019 07:27:40 GMT",
        "Last-Modified": "Wed, 07 Aug 2019 07:27:40 GMT",
        "Content-Length": "461325"
    },
    "body": {
        "$content-type": "application/pdf",
        "$content": "JVBERi0x.......jYNJeLjz9MNCjE"
    }
}

```
ここから、$contentにファイルのBase64文字列が格納されていることがわかります。まさに```body('Get_file_content_using_path')?['$content']```では、このBase64文字列を抽出しています。

## 最大のポイント：スキーマ
今回の最大のポイントは、ResponseステップでのResponse Bodyに関するスキーマです。

```ResponseSchema.json
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "fileContent": {
                "title": "fileContent",
                "x-ms-dynamically-added": true,
                "type": "string",
                "format": "byte"
            },
            "fileName": {
                "type": "string"
            }
        }
    }
}
```
重要なのは```"fileContent":```に続く「おまじない」パートです。これをいれることによって、PowerAppsにファイルとしてデータを返却したときと同じ結果が得られます。


# PowerApps側
PowerApps側は非常にシンプルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/b59a942f-4a3b-0082-5fba-8c2d4b5a22e2.png)
App.OnStartで、Flowの実行結果をCollectionに格納します。Collection内に格納されている"fileContent"をラベルに表示させると、「```appres://blobmanager/....```」となっています。
つまり先ほどの特殊なスキーマによって、Base64文字列から、ローカルにキャッシュされたようなPDFファイルが作成されたことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/f43f08d1-0072-2679-c183-5e8d57232edd.png)

以上で全体の作成は完了です。Phoneレイアウトで作成した場合の作例は下記をごらんください。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I’ve achieved to collect PDF files from SharePoint Library! ! <a href="https://t.co/HC9dgLoogi">pic.twitter.com/HC9dgLoogi</a></p>&mdash; Hiro #JSON()Addict (@mofumofu_dance) <a href="https://twitter.com/mofumofu_dance/status/1158939173090287617?ref_src=twsrc%5Etfw">August 7, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>