2021年11月17日水曜日

Oracle APEX 21.2新機能(15) - レポートの拡張

 Oracle APEX 21.2でのレポート(対話モード・レポート、対話グリッド、クラシック・レポート)に、以下の機能が追加されました。レポートのタイプによっては、追加されていない機能もあります。

  • PDF、XLSXおよびHTML形式のレポートのダウンロードにイメージが埋め込まれます。
    • 対話グリッドは除きます。対話グリッドには、列のタイプにイメージの表示がありません。
  • ダウンロードのダイアログにリッチ・テキストを削除のスイッチが追加されています。
    • タイプリッチ・テキストの列で、書式HTMLマークダウンの両方に適用されます。
    • セキュリティのプロパティ特殊文字をエスケープOFFの列に適用されます。
    • 特殊文字のエスケープCSVとXLSX形式のレポートに適用されます。
  • PDFのダウンロードにアクセシビリティ・タブを含めることができます。
    • クラシック・レポートではダウンロードのダイアログは開かないため、アクセシビリティ・タグを含めるスイッチはありません。
  • 対話モード・レポートのサブスクリプションで、すべてのレポート形式がサポートされます。また、データが見つからない場合はスキップのスイッチが追加されています。
オラクルの公式ブログに、プロダクト・マネージャーのMonica GodoyさんによるWhat's New for Report Regions in APEX 21.2という題のレポートの新機能を紹介する記事が載っています。こちらの記事にそってアプリケーションを実装することにより、新機能の確認を行ってみます。

データの準備


作成するAPEXアプリケーションで使用するデータセットを準備します。こちらのリンクよりEMPLOYEES .sqlをダウンロードします。ダウンロードしたファイルを実行します。

SQLワークショップよりSQLスクリプトを開きます。アップロードを実行します。


ファイルとしてダウンロードしたEMPLOEES .sql(EMPLOYEESの後ろに空白あり)を選択します。アップロードをクリックします。


ファイルがアップロードされたら右端の実行をクリックします。表EMPLOYEESが新たに作成され、例題で使用するデータが投入されます。すでに表EMPLOYEESが存在する場合は削除はしないため、(表定義が異なると)データの投入に失敗します。表EMPLOYEESが存在する場合は、スクリプトの実行前に削除しておくか名前を変更しておく必要があります。


ダイアログが開いたら、即時実行をクリックします。


10行の文が成功していたら、表EMPLOYEESの作成とデータの投入は完了です。



アプリケーションの作成


空のアプリケーションを作成します。(元の記事では対話モード・レポートのページをアプリケーション作成ウィザードで作成しています)。

アプリケーション作成ウィザードを起動し、名前レポートの新機能とします。アプリケーションの作成を実行します。


アプリケーションが作成されたら、対話モード・レポートのページを作成します。ページの作成を実行し、ページ作成ウィザードを起動します。


レポートを選択します。


対話モード・レポートを選択します。


作成するページの名前従業員一覧とし、へ進みます。


ナビゲーションのプリファレンスとして、新規ナビゲーション・メニュー・エントリの作成を選択します。へ進みます。


データ・ソースローカル・データベースとし、ソース・タイプSQL問合せを選択します。SQL SELECT文を入力として以下を記述します。
select EMPNO,
  ENAME AS NAME,
  JOB,
  SALARY,
  dbms_lob.getlength(IMAGE) AS IMAGE,
  HTML_DETAILS,
  MARKDOWN_DETAILS
  from EMPLOYEES
作成をクリックします。


以上で表EMPLOYEESを一覧する対話モード・レポートのページが作成されました。

列IMAGEに画像が表示されるように調整します。

左ペインのレンダリング・ビューにて列IMAGEを選択します。識別タイプイメージの表示に変更します。BLOB属性表名EMPLOYEESBLOB列IMAGE主キー列1EMPNOをそれぞれ指定します。


列HTML_DETAILSにはHTMLが保存されています。レポート上で適切にフォーマットされるよう設定を調整します。

HTML_DETAILSを選択し、識別タイプリッチ・テキストに変更します。設定書式HTMLを指定します。


同様に列MARKDOWN_DETAILSも調整します。列MARKDOWN_DETAILSを選択し、識別タイプリッチ・テキスト設定書式マークダウンを指定します。


以上で対話モード・レポートのページが完成しました。


レポート出力の確認


ページを実行して、Oracle APEX 21.2の新機能について確認します。


アクション・メニューからダウンロードを呼び出します。リッチ・テキストを削除ONにし、Excel形式でダウンロードします。


ダウンロードされたExcelは以下のようになります。イメージが埋め込まれていること、HTMLおよびマークダウンによる修飾が削除されていることが確認できます。


PDF形式のダウンロードを確認してみます。アクセシビリティ・タグを含めるのスイッチが追加されています。


アクセシビリティ・タグを含めるONにしてダウンロードしたPDFを、Adobe Acrobat Readerで開きアクセシビリティのオプションを確認しました。読み上げ順序タグ付けされた読み上げ順序になっています。これがOFFの場合は、文書の読み上げ順序を推測です。



コードによるレポート出力


画面からレポートを出力する方法に続いて、コードを書いて出力してみます。

最初にコード内から参照できるように、対話モード・レポートのリージョン従業員一覧詳細静的IDemployeesとして設定します。


続いて、リージョン従業員一覧に、コードの実行に使用するボタンの作成を行います。

識別ボタン名B_DOWNLOADラベルレポート出力とします。レイアウト位置対話モード・レポートの検索バーの右とします。外観ボタン・テンプレートText and Iconアイコンfa-downloadとします。動作ページの送信です。


レポート出力を行うプロセスを作成します。

左ペインにてプロセス・ビューを開き、プロセスの作成を実行します。識別名前レポート出力タイプにはコードの実行を選択します。ソース位置ローカル・データベース言語PL/SQLとし、PL/SQLコードとして以下を記述します。参考にした記事とはコードを変えています。対話モード・レポートでの列の選択や検索条件が出力されるレポートに反映されるよう、問合せコンテキストをAPEX_EXEC.OPEN_QUERY_CONTEXTの代わりにAPEX_REGION.OPEN_QUERY_CONTEXTを呼び出して取得しています。
declare
    l_ctx apex_exec.t_context;
    l_rid number;
    l_exp apex_data_export.t_export;
    l_print_config apex_data_export.t_print_config;
    l_cnt pls_integer;
    l_column apex_exec.t_column;
    l_columns apex_data_export.t_columns;
begin
    -- リージョン従業員一覧(statid_id:employees)の内部IDをl_ridに取り出す。
    select region_id into l_rid from apex_application_page_regions
    where application_id = :APP_ID and page_id = :APP_PAGE_ID
      and static_id = 'employees';
    apex_debug.info('region_id of employees is ' || l_rid);
    -- 対話モード・レポートで実行されているSQLをl_ctxに取り出す。
    l_ctx := apex_region.open_query_context (
        p_page_id => :APP_PAGE_ID,
        p_region_id => l_rid );
    -- 出力される列の数を取り出す。
    l_cnt := apex_exec.get_column_count(
        p_context => l_ctx
    );
    -- 検索された列をレポート出力列に置き換える。
    for i in 1..l_cnt
    loop
        l_column := apex_exec.get_column(
            p_context => l_ctx,
            p_column_idx => i);
        if l_column.name = 'IMAGE' then
            -- 列IMAGEは書式を変更する。
            apex_data_export.add_column(
                p_columns => l_columns,
                p_name => l_column.name,
                p_heading => l_column.name,
                p_format_mask => 'IMAGE:EMPLOYEES:IMAGE:EMPNO'
            );
        else
            apex_data_export.add_column(
                p_columns => l_columns,
                p_name => l_column.name,
                p_heading => l_column.name
            );
        end if;
    end loop;
    -- レポートの形式を定義する。
    l_print_config := apex_data_export.get_print_config(
        p_body_font_color => '#4B4540',
        p_page_header => 'Report of Employees', 
        p_page_header_font_color => '#4B4540', 
        p_page_header_font_size => 14, 
        p_page_header_font_weight => apex_data_export.c_font_weight_bold, 
        p_page_footer => 'Generated by '|| :APP_USER, 
        p_page_footer_font_color => '#4B4540', 
        p_page_footer_font_size => 10,
        p_page_footer_font_weight => apex_data_export.c_font_weight_bold,
        p_border_width => 1, p_border_color => '#4B4540'
    );
    -- PDFの出力。
    l_exp := apex_data_export.export (
        p_context   => l_ctx,
        p_format    => apex_data_export.c_format_pdf,
        p_print_config => l_print_config,
        p_columns => l_columns,
        p_file_name => 'Employees' );
    apex_exec.close(l_ctx);
    apex_data_export.download( p_export => l_exp );
end;
ボタンを押したときに実行されるよう、サーバー側の条件ボタン押下時B_DOWNLOADを選します。


以上でコードによるレポート出力が実装できました。ページを実行して動作を確認します。

Job = SALESMANでフィルタし、列HTML_DETAILS、MARKDOWN_DETAILSを表示の対象から外します。その状態でレポート出力をクリックします。


ダウンロードされたPDFは以下のようになります。


対話モード・レポートのサブスクリプション


対話モード・レポートのサブスクリプションはアクション・メニューサブスクリプションより呼び出します。この機能は対話モード・レポートのAttributesアクション・メニューサブスクリプションONであるときにメニューに含まれます。


以前のバージョンと比較して、レポート形式の選択としてCSV、HTML、ExcelおよびPDFの選択が追加されています。また、データが見つからない場合はスキップのオプションが追加されています。



対話グリッド


同じデータ・ソースを使って対話グリッドも作ってみました。対話グリッドでは列のタイプにイメージの表示はありませんが、列に画像を表示することはできます。ただし、編集はできません

ソースとなるSQLは、以下のように変更します。
select EMPNO,
  ENAME AS NAME,
  JOB,
  SALARY,
  -- dbms_lob.getlength(IMAGE) AS IMAGE,
  apex_web_service.blob2clobbase64(IMAGE) as image,
  HTML_DETAILS,
  -- MARKDOWN_DETAILS
  apex_markdown.to_html(MARKDOWN_DETAILS) as markdown_details
  from EMPLOYEES

列IMAGEのタイプをHTML式に変更し、HTML式として以下を記述します。

<img src="data:image/jpeg;base64, &IMAGE.">


以上で対話グリッドに画像が表示されます。ただし、レポート出力にこの画像を含めることはできません。



クラシック・レポート


データ・ソースとなるSQLや列の設定は、対話モード・レポートと同じです。

クラシック・レポートもAttributes出力有効ONにすることにより、PDF、XLSX、HTML形式の出力が可能です。これらのレポートにイメージを含むことができます。


形式はPrinting出力書式で指定します。


デフォルトではレポートの下部に、レポートを出力するリンクが現れます。


以上になります。

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

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