APEX 22.2より対話モード・レポートとクラシック・レポートでもテンプレート・ディレクティブが利用できるようになりました。
今までは条件ごとに列の表示を切り替えるために、主にCASE句を使用していました。これだとレポートのSELECT文が非常に見難くなります。
APEX 22.2より対話モード・レポートとクラシック・レポートで使用できるようになったテンプレート・ディレクティブにより、レポートのソースのSELECT文がどのように変わるか以下に紹介します。
アプリケーションのページに対話モード・レポートを3つ作成しています。最初の対話モード・レポートデフォルトは表SAMPLE_FILESにテスト・データを投入するために使用します。ページ作成ウィザードによって作成されたフォーム付き対話モード・レポートです。
対話モード・レポート従来の実装では、レポートのソースのSELECT文にCASE句を使っています。対話モード・レポートテンプレート・ディレクティブでは、レポートのソースのSELECT文ではなくテンプレート・ディレクティブで列の表示を切り替えています。
どちらも表示上は同じになっています。
表SAMPLE_FILESの作成
クイックSQLの以下のモデルより、表SAMPLE_FILESを作成しています。
# prefix: sample
files
name vc80 /nn
url vc400
content file
生成されるDDLは以下になります。
create table sample_files (
id number generated by default on null as identity
constraint sample_files_id_pk primary key,
name varchar2(80 char) not null,
url varchar2(400 char),
content blob,
content_filename varchar2(512 char),
content_mimetype varchar2(512 char),
content_charset varchar2(512 char),
content_lastupd date
)
;
今回実装するレポートの列Nameに、以下の設定を行ないます。
列CONTENTにBLOBのデータが保存されている場合は、NameをクリックするとBLOBのデータをダウンロードします。そうでない場合は列URLを開きます。
また、列CONTENT_MIMETYPEよりファイルタイプに応じたアイコンを表示します。
従来の実装
従来の実装でのソースです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
select | |
case | |
when nvl(sys.dbms_lob.getlength(content),0) > 0 then | |
'<a href="' || apex_util.get_blob_file_src('P3_ID', id) || '">' || name || '</a>' | |
when url is not null then | |
'<a href="' || url || '">' || name || '</a>' | |
else | |
name | |
end name | |
, case | |
when url is not null then | |
'<span aria-hidden="true" class="fa fa-external-link"></span>' | |
when content_mimetype = 'image/png' then | |
'<span aria-hidden="true" class="fa fa-file-image-o"></span>' | |
when content_mimetype = 'application/vnd.openxmlformats-officedocument.presentationml.presentation' then | |
'<span aria-hidden="true" class="fa fa-file-powerpoint-o"></span>' | |
when content_mimetype = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' then | |
'<span aria-hidden="true" class="fa fa-file-excel-o"></span>' | |
else | |
content_mimetype | |
end type | |
from sample_files |
レポートに現れる列はNAMEとTYPEですが、これらは両方ともHTMLなのでセキュリティの特殊文字のエスケープをOFFにする必要があります。アプリケーションの安全性が下がります。
また列フィルタのタイプとしてデフォルトの列タイプに基づくデフォルトが選択されていると、列のデータ(HTMLのA要素)がそのまま検索条件やソートの条件に使用されます。
テンプレート・ディレクティブ
テンプレート・ディレクティブの使用を前提とした、ソースのSELECT文です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
select | |
name | |
, url external_url | |
, content_mimetype type | |
, apex_util.get_blob_file_src('P3_ID', id) as download_url | |
, nvl(sys.dbms_lob.getlength(content),0) as file_exist | |
from sample_files |
列DOWNLOAD_URL、EXTERNAL_URL、FILE_EXISTが追加されています。列NAMEとTYPEにテンプレート・ディレクティブを使ったHTML式を記述する際に使用しますが、表示は不要です。これらの列の識別のタイプは非表示にします。
列NAMEの列の書式のHTML式として、以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{!#FILE_EXIST#/} | |
{if FILE_EXIST/} | |
<a href="#DOWNLOAD_URL#">#NAME#</a> | |
{elseif EXTERNAL_URL/} | |
<a href="#EXTERNAL_URL#">#NAME#</a> | |
{else/} | |
#NAME# | |
{endif/} |
先頭の1行はコメントです。
{!#FILE_EXIST#/}
本来であればこの行が無くても同じ動作になるのですが、if文の条件に非表示文字列が使用されていると正しく認識されないという不具合があり、そのワークアラウンドとして先頭に非表示列を含むコメント行を含めています。
列TYPEのHTML式です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{if EXTERNAL_URL/} | |
<span aria-hidden="true" class="fa fa-external-link"></span> | |
{else/} | |
{case TYPE/} | |
{when image/png/} | |
<span aria-hidden="true" class="fa fa-file-image-o"></span> | |
{when application/vnd.openxmlformats-officedocument.presentationml.presentation/} | |
<span aria-hidden="true" class="fa fa-file-powerpoint-o"></span> | |
{when application/vnd.openxmlformats-officedocument.spreadsheetml.sheet/} | |
<span aria-hidden="true" class="fa fa-file-excel-o"></span> | |
{otherwise/} | |
#TYPE# | |
{endcase/} | |
{endif/} |
列NAMEとTYPEともに検索結果のデータ自体はHTMLではないため、セキュリティの特殊文字のエスケープをOFFにする必要はありません。より安全な実装になっています。
また、列フィルタの値もHTMLにはなりません。
列TYPEの列フィルタの値は、アイコンではなくMIMEタイプの文字列が表示されます。アイコンでは検索やソートはできないので、文字列が表示される方が実用的といえます。
対話モード・レポートでのテンプレート・ディレクティブの利用方法の紹介は以上になります。
今回使用したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/new-222-template-directive.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完