キャンバスアプリでドキュメントライブラリーのファイルをまとめてダウンロード

SharePoint Online サイトのドキュメントライブラリーに保存されている複数ファイルを、Power Apps で"まとめてダウンロード"する方法を調べてみました。

# 検証した状態
SharePoint Online サイト（以降、SPO サイト）にドキュメントライブラリーを追加し、複数ファイルを直下に格納しておきました。

![スクリーンショット 2024-06-16 182847.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/19dedc90-0535-3e39-40f8-01cca5d10801.png)

Power Apps キャンバスアプリで、上記ドキュメントライブラリーをデータソースとして指定。該当ファイルをギャラリーコントロールへ表示します。

![スクリーンショット 2024-06-16 175501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/ff50fc07-a707-dbc9-228d-84904c2b023d.png)

ギャラリーコントロールに一覧表示されている対象ファイルを、ボタン1回クリックしたら”全部まとめてダウンロードする”という機能を作成していきます。
なお、Windows11、 Microsoft Edge で検証しています。

# ForAll と Download 関数でしょ？
ファイルをダウンロードしたいので、[Download 関数](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-download?WT.mc_id=DX-MVP-5004053) を [ForAll 関数](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-forall?WT.mc_id=DX-MVP-5004053) でぶん回せば楽勝でしょ？と思っていたんです。

前述イメージのように、ボタンを配置して ForAll でダウンロードを連続実行してみました。

```
ForAll(Gallery1.AllItems, Download(ThisRecord.アイテムへのリンク))
```

## 実行してみる！（※期待どおりではなかった）
意気揚々と実行して、ボタンをクリックした結果！！

![スクリーンショット 2024-06-16 175802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/79da5399-9324-a3f6-d012-7829a8cb4f3d.png)

ブラウザー上でタブが開いてしまいました（汗
指定したファイルが全て複数のタブで表示された！ダウンロードじゃないじゃん(´・ω・`)

これ、利用しているブラウザーに依存しちゃうんですよね。
前述の Learn（Docs）、Description の章に明記されています。

> ネイティブ プレイヤー (Windows、Android、および iOS) で、ユーザーはファイルを保存する場所を求められます。
> 
> Web で使用する場合、Download はファイルで何が起こるか確認するためにブラウザーの設定に依存しています。 ブラウザがネイティブにサポートする画像、ビデオ、PDF、およびその他のファイル タイプの場合、ファイルを表示するために新しいブラウザ タブが開きます。 多くのブラウザは、コンテンツをローカル ファイル システムに保存することをサポートしています。
> 
> Windows でのみ、Download はファイルがテキスト文字列としてローカルに保存された場所を返します。

ブラウザーの設定に依存する、ということは、例えば「ダウンロード処理の場合はダイアログ等表示させずに所定の場所へ自動的に保存する」といった設定に変更しておけば、一括ダウンロードが実現できそうです。ただ、ブラウザーは Power Apps 以外でも利用する道具なので、このためだけに設定変更しておくのは少々使い勝手が悪いと思います。さて、どうしたものか🤔

# 「/_layouts/download.aspx」を利用する
Deep リンク等でタブで開かずに、直接ダウンロード処理ができないものか？と調べていたら発見しました。

[SharePoint Online や OneDrive for Business でファイルを直接ダウンロードさせる共有リンクの作り方](https://idea.tostring.jp/?p=5577#toc7) ［idea.toString();］

さすがです！ [Ota Hirofumi](https://twitter.com/hrfmjp)さん！毎度感謝です！！

もう1つボタンを追加して、以下の関数を指定しました。

```
ForAll(
    Gallery1.AllItems, 
    Download(
        $"https://＜サイト名＞.sharepoint.com/sites/SampleTeam/_layouts/15/download.aspx?SourceUrl={ThisRecord.アイテムへのリンク}"
    )
)
```

さて、上手くいくかな？

## 実行してみる！！
一瞬、タブが増えますが自動的にファイルのダウンロードが実行されました。

![スクリーンショット 2024-06-16 181607.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/27b62f85-8a15-7cdb-1753-f1f25034cfa9.png)

やったね！ SPO のドキュメントライブラリーに格納されている複数ファイルを、Power Apps で一括ダウンロードできました。当方の手元にある環境では、ダイアログも表示されずに指定したファイルが1個ずつダウンロードされました。

# 結び
前述通り、Windows 11、Edge ブラウザーで試しています。その他ブラウザーや、利用している端末の設定によっては異なる動きになる可能性があります。セキュリティー設定などでダウンロードに関する処理がクライアント側で何らかの制限が行われている場合も、期待した動作にならない可能性があるなぁ・・・と想定しています。

自分は、Edge で一括ダウンロードできればよかったので、コレで満足ですが、この記事を参考に同様の処理を実装する際は必ず動作確認を行うようお願いします。また、共有なりで他の方へ展開する場合は、注意事項として添えてあげるとよろしいかなと考えます。

昨今、ウィルス等の被害を広げないよう対応するため、ファイルダウンロード系の処理は非常に厳しくチェックされる方向になっています。ブラウザーも十数年前と比較すると様々な機能が追加されています。さらに企業などでは追加のセキュリティ対策も実施している場合も多いでしょう。なので、状況によっては”諦める”しかないってのもありえるかなぁ～ですね。

また、ドキュメントライブラリーを実際に運用している場合はフォルダー等が含まれると思います。そこらへんは状況に応じて工夫して対応してみてください。

以上のような注意点はあるものの、Power Apps のアプリからファイルをダウンロードさせたい、しかも複数まとめて、ってタイミングで、この記事がどなたかのお役に立てれば幸いです。

それでは、皆さま。素晴らしい Power Platform Life を！