2025年3月13日木曜日

レポート上にダウンロード・ボタンを配置しZIP圧縮してコンテンツをダウンロードする

対話モード・レポート上にダウンロード・ボタンを配置し、ボタンのある行のBLOB列のコンテンツをZIP圧縮してダウンロードします。無圧縮であればレポート列の設定だけでコンテンツのダウンロードはできます。今回はZIP圧縮するため、Oracle APEX 24.1で追加された動的アクションダウンロードを活用します。

わかりにくい例ですが、以下のように動作するAPEXアプリケーションを作成します。


最初に標準のダウンロードを実装したAPEXアプリケーションを作成します。

SQLワークショップクイックSQLを開き、以下のモデルを元に表EBAJ_PHOTOSを作成します。
# prefix: ebaj
# pk: identity
photos
    title vc80 /nn
    photo file

画面に従ってDDLの生成と実行を行います。表が作成されたら、アプリケーションの作成を呼び出します。


作成されるアプリケーションに、デフォルトで表EBAJ_PHOTOSフォーム付き対話モード・レポートのページが含まれます。

そのまま、アプリケーションを作成します。


アプリケーションが作成されます。

最初に対話モード・レポートのページを修正します。ページ・デザイナでページ番号を開きます。


対話モード・レポートの列PHOTOを選択します。ページ作成ウィザードBLOB属性の一部を設定しません。

MIMEタイプ列PHOTO_MIMETYPEファイル名列PHOTO_FILENAME最終更新列PHOTO_LASTUPD文字セット列PHOTO_CHARSETを設定します。

以上で変更を保存します。


ページ・デザイナでページ番号のフォームのページを開き、同様の変更を行います。

ページ・アイテムP3_PHOTOを選択し、ストレージMIMEタイプ列PHOTO_MIMETYPEファイル名列PHOTO_FILENAME文字セット列PHOTO_CHARSETBLOB最終更新列PHOTO_LASTUPDを設定します。

以上で変更を保存します。


以上で、APEXアプリケーションに標準のファイル・アップロードとダウンロードが実装されました。

作成したアプリケーションを実行し、いくつか写真をアップロードします。

対話モード・レポートには、写真をダウンロードするリンクが表示されます。標準のダウンロードは、アップロードした写真がそのままダウンロードされます。


これから、レポート上のダウンロードのリンクをボタンに変更し、写真がZIP圧縮されてダウンロードされるように機能を加えます。

ページ・デザイナで対話モード・レポートのページを開きます。

最初にダウンロード対象の写真を持つ行のIDを保持するページ・アイテムを作成します。

識別名前P2_IDタイプ非表示とします。動的アクションにより値を設定するため、設定保護された値オフにします。セッション・ステートストレージリクエストごと(メモリーのみ)です。


JavaScriptから参照できるように、対話モード・レポート静的IDとしてREPORTを設定します。


PHOTOをボタンに変更します。

識別タイププレーン・テキストに変更し、列の書式HTML式に以下を記述します。カスタム属性data-idに行の主キー値#ID#を渡しています。

<button type="button" class="t-Button" data-id="#ID#">Download</button>

この列もJavaScriptから参照できるように、静的IDとしてCOLUMN_DOWNLOADを設定します。


ユニバーサル・テーマのリファレンスに含まれるボタン・ビルダーを使用すると、ボタンのマークアップを生成できます。

https://apex.oracle.com/pls/apex/r/apex_pm/ut/button-builder


ボタンをクリックしたときに、ページ・アイテムP2_IDに主キーの値を設定する動的アクションを作成します。

左ペインで動的アクション・ビューを開き、クリックのノードに動的アクションを作成します。

識別名前onClick Download on Reportとします。実行イベント有効範囲動的に変更し、静的コンテナ(jQueryセレクタ)に対話モード・レポートの静的IDである#REPORTを設定します。

タイミングイベントクリック選択タイプjQueryセレクタを選び、jQueryセレクタに以下を記述します。列PHOTOのセルにあるボタンを指定しています。

td[headers="COLUMN_DOWNLOAD"] button


TRUEアクションとして値の設定を実行します。

設定タイプの設定JavaScript式を選択し、JavaScript式として以下を記述します。クリックしたボタンのカスタム属性data-idに渡している値を参照しています。

this.triggeringElement.dataset.id

ページ・アイテムで発生する変更イベントを受けてダウンロードを実行するため、変更イベントの禁止オフにします。値の設定先となる影響を受ける要素選択タイプアイテムアイテムP2_IDを選択します。

実行初期化時に実行オフです。


ページ・アイテムP2_ID動的アクションを作成します。

識別名前onChange IDタイミングイベント変更です。ページ・アイテムP2_IDの値が変更されたときに動的アクションが実行されます。


TRUEアクションとしてダウンロードを実行します。

設定複数のファイルオンにし、ダウンロードされるファイルがZIP圧縮されるようにします。ファイル名photo-&P2_ID..zipとします。

ダウンロードされるZIPファイルに含まれるファイルは、ソースに設定します。

SQL問合せとして以下を記述します。送信するアイテムとしてP2_IDを設定します。

select photo, photo_filename from ebaj_photos where id = :P2_ID

実行初期化時に実行オフにします。


以上で実装は完了です。アプリケーションを実行すると、記事に先頭にあるGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-download-button-on-report.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。