SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(ActiveReports)byメシウス(AD)

OutSystems上で簡単なシステムを作成し、ActiveReportsJSを活用した帳票機能を構築する

JavaScript帳票ライブラリ「ActiveReportsJS」の活用事例

  • X ポスト
  • このエントリーをはてなブックマークに追加

 メシウスの「ActiveReportsJS」は、帳票開発を総合的にサポートするJavaScriptライブラリです。このライブラリは、ローコードプラットフォームであるOutSystemsでも活用でき、標準で帳票機能が備わっていないOutSystemsにおいて、優れた選択肢となります。本記事では、「ActiveReportsJS」をOutSystemsと連携させる方法について詳しくご紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 OutSystems自体には帳票出力の機能が備わっていません。OSSレポジトリであるForgeにはUltimate PDFを初め、いくつかコンポーネントもありますが、大量の帳票を作成したり、細かい要件がある場合は不足を感じたりすることも多いでしょう。そのため、多くのOutSystems導入企業は何らかの帳票ソフトウェアまたはサービスを導入し、連携させて使うことになります。

 本記事では、JavaScript帳票開発ライブラリのActiveReportsJSをOutSystemsと連携させる方法を紹介します。

対象読者

  • OutSystemsに帳票ソリューションを導入することを検討している方
  • OutSystemsにActiveReportsJSを組み込む方法を知りたい方
  • OutSystemsの開発知識を取得したい方

必要な環境

 本記事のサンプルプログラムを試すためには、以下が必要です。

 OutSystems 11の環境は、無償のPersonal Environmentで問題有りません。環境を持っていない方は、アカウントをサインアップすると作ることができます。

 ActiveReportsJSは、専用のツールでデザインしたレポートを、WebブラウザのJavaScriptのみで出力できるライブラリです。以降、ActiveReportsJSで作る帳票のことを、ActiveReportsJSにあわせてレポートと呼びます。

サンプルアプリケーションのセットアップ

 Service Studio上で、「New Application」をクリックしてアプリケーション作成を開始します。

New Application
New Application

 用意されているテンプレートを基にアプリケーション作成を始める「From an app」を選択してアプリケーションを作ります。

From an app
From an app

 Order Managementのテンプレートを選択し、「Install」ボタンをクリックします。

Order Managementをインストール
Order Managementをインストール

 インストールが終わったら「Customize app」ボタンをクリックして、アプリケーションを開いてください。

インストールが終了したことを示すダイアログ
インストールが終了したことを示すダイアログ

 アプリケーションに属するモジュール一覧が表示されます。

 Order Managementモジュールに参照整合性の問題が発生しているので修正します。OrderManagementモジュールを開いてください。

[作成されたアプリケーションを開いたところ
作成されたアプリケーションを開いたところ

 参照整合性の問題があるので、Manage Dependenciesダイアログを開きます。ダイアログ右下の「Refresh all」ボタンをクリックし、続いて「Apply」ボタンをクリック。これで今開いているモジュールの参照は更新されました。

Manage Dependenciesダイアログ
Manage Dependenciesダイアログ

 ダイアログが閉じたら、忘れずにPublishもしておきましょう。

実装シナリオ

 サンプルアプリケーションで管理されている注文データを使い、請求書レポートを作成していきます。

シナリオ実装後の操作の流れ

 この記事で紹介する手順を行った後のアプリケーションでの、レポート表示までの操作手順を確認しておきましょう。

 OrderManagementモジュールをブラウザで開きます。

 トップメニューから「Orders」をクリックしてOrderManagement画面を、続いて一覧上の適当な行のNumber列に表示されるリンクを開きます。

OrderDetail画面を開く
OrderDetail画面を開く

 1件の注文の詳細を示すOrderDetail画面が開きます。この画面右上、「Delete Order」ボタンの隣に、「Report」ボタンを追加します(※)。

※詳しくは解説しませんが、ボタンを追加し、画面を開く処理を実装します。ボタン動作の実装に関する内容はリファレンスを参照の上、実装してください。
Reportボタンを追加
「Report」ボタンを追加

 クリックしたらActiveReportsJSのビューワーを配置したOrderDetailReport画面が開きます。

OrderDetailReport画面例
OrderDetailReport画面例

作成するもの

 上記のシナリオを実装するために、以下の要素を作成します。

  1. p2で作成:ActiveReportsJSをOutSystemsアプリケーションから利用するためのUI部品(ActiveReportsJS_Patモジュール)
  2. p3で作成:ActiveReportsJSのレポート定義
  3. p4で作成:OrderDetailReport画面(OrderManagementモジュール)

 OutSystemsのアーキテクチャ設計図であるArchitecture Canvasを使って表すと以下のようになります。

Architecture Canvas
Architecture Canvas

ActiveReportsJS部品(Block)を用意

アプリケーションとモジュールを作成する

 OutSystemsにおいて、モジュールがWebやMobileの一塊のソフトウェア、あるいはそれらから参照するライブラリを表します。アプリケーションは、複数のモジュールをまとめて管理するフォルダ的な位置づけです。リリース単位でもあります。

 部品は、すでに作成したサンプルアプリケーションとは別に作ります。帳票出力部品は通常複数のアプリケーションから利用されるため、利用側のサンプルアプリケーションと独立させ、独自のライフサイクルで開発・保守を行いたいからです。

 Service Studioで、サンプルアプリケーションのときと同じく「New Application」をクリックしてダイアログを表示します。今度はテンプレートが無いので、「From scratch」のオプションを選択します。次に、Reactive Web Appを選択してください。SPAのWebアプリケーションを作成するオプションです。

Reactive Web Appを作成
Reactive Web Appを作成

 Name=ActiveReportsJSとしました。

名前と説明を入力してアプリケーション作成を実行
名前と説明を入力してアプリケーション作成を実行

 続いて、モジュールを作成します。

 Name=ActiveReportsJS_Pat、module type=Blankを選択(Blankを選択するのは、UI部品用モジュールに不要な要素を含めないため)。

モジュールを作成
モジュールを作成

ライセンスを保持するSite Propertyを用意する

 Site Propertyは、運用中に変更される可能性のある設定値を定義する方法です。LicenseKeyという名前でSite Propertyを作成します。Data TypeはText、Is secretはYesにします(ライセンスキーは一般にセキュアに保つべき情報であるため。ActiveReportsJSはクライアント側で動作するため、実行時には知識のあるユーザーには見えてしまいますが)。

Site Propertyにライセンスキー項目を作成
Site Propertyにライセンスキー項目を作成

 いったん、Publishします。管理コンソールのService CenterでActiveReportsJS_Patのページを開いてください。Site Propertiesタブ > LicenseKeyリンクの順にクリック。

License KeyのSite Propertyを開く
License KeyのSite Propertyを開く

 ActiveReportsJSのライセンスキーをEffective Valueに設定し、「Apply」ボタンをクリックしてください。これで部品にライセンスキーの設定ができました。

ライセンスキーを設定
ライセンスキーを設定

ライブラリのCSSを読み込むためのBlock

 ActiveReportsJSのビューワーを表示するには、2つの.cssファイルを読み込む必要があります(ダウンロードしたライブラリ内の、activereportsjs-5\dist\css)。

  • ar-js-ui.css
  • ar-js-viewer.css

 以下、ar-js-ui.cssを例に作成手順を説明します。ar-js-viewer.cssにも同じ手順を行ってください。

 UI FlowをStylesという名前で追加します。作成したStylesに、CSSを配置するBlockを作成し、NameはArJsUiCssとしました。Descriptionは保守のために設定しておきましょう。

NameとDescriptionを設定
NameとDescriptionを設定

 Block内に以下のように配置します。

Block内の配置
Block内の配置

 Condition=FalseのIfはBlockを部品提供するときによく使う方法です。True Branchに、他のBlockやScreenに配置したときに見せたい要素、False Branchに実際に使う要素を配置します(このBlockの場合は空なので何も表示されません)。

 画面上部のCSSアイコンをクリックして開いたダイアログに、ar-js-ui.cssの中身を貼り付けて完成。

CSSを配置
CSSを配置

ライブラリのJavaScriptを登録

 以下のライブラリをactivereportsjs-5\dist\scriptsフォルダからScriptsフォルダにImportしてください。

  • 必須のスクリプト
    • ar-js-core.js
    • ar-js-viewer.js
  • 任意のスクリプト(エクスポート機能で使用)
    • ar-js-pdf.js
    • ar-js-xlsx.js
    • ar-js-html.js
    • ar-js-tabular-data.js
  • UIの日本語化用スクリプト
    • locales\ar-js-locales.js

 上記のファイルをすべて登録すると、以下のようになります(見やすいようにフォルダ分けしています)。

JavaScriptスクリプト登録後
JavaScriptスクリプト登録後

ActiveReportsJSビューワーBlock

イメージ画像

 他のアプリケーションに配置した際に、どういった機能がそこに置かれているかを示す画像が表示されるとわかりやすいです。後で使うので、ビューワーのイメージ画像をImagesにImportしておきましょう。

Service Studio内での、Block配置イメージ用画像
Service Studio内での、Block配置イメージ用画像
Block定義

 CSSの場合と同じように、UI FlowとBlockを用意します。

Blockの定義
Blockの定義

①Blockのプロパティ

 Name=ActiveReportsJS_Viewerとしました。他のモジュールから参照されるときは、この名前で見えます。他のモジュールから参照できるように、Public=Yesに。

②スクリプトを参照

 登録しておいたJavaScriptファイルを参照します。ここで指定したJavaScriptファイルは、Blockを実行するときに自動で読み込まれます。

③Input Parameter

 以下2つのInput Parameterを追加します。Input Parameterを追加するには、③の位置でActiveReportsJS_Viewer  Blockを右クリックし、「Add Input Parameter」を選択します。

  • ReportDefinitionJSON
    • Name: ReportDefinitionJSON
    • Description: ActiveReportsJSのレポート定義ファイルに含まれるJSON
    • Data Type: Text
    • Is Mandatory=Yes
  • DataSourceJSONs
    • Name: DataSourceJSONs
    • Description: 実行時に埋め込み形式のデータソースに連結したいJSONのリスト
    • Data Type: Text List
    • Is Mandatory=No
Input Parameterの設定例(ReportDefinitionJSONの場合)
Input Parameterの設定例(ReportDefinitionJSONの場合)

 前者にActiveReportsJSのレポート定義ファイルのJSON形式、後者にはレポートに渡すデータをJSON化したものをListで渡します(レポート定義によって必要なデータソースの数は可変であるためListにしています)。

 Block内部には以下のようにWidgetを配置します。CSSのBlockと同じ理由でIfを使っています。True BranchにおいたImageにはImagesにImportしておいた画像を指定。False Branchには、CSSを読み込むBlockを2つ、ビューワーを表示するためのContainerを配置します。

Blockの定義
Blockの定義
Style設定

 ar-js-ui.css を読み込むBlockを作ったときと同じく、Service Studio上部のcssボタンをクリックし、外観定義用classを作成します。このcssボタンはBlockのUI編集中でないと表示されないため、もし表示されていなかったら、Block名(ActiveReportsJS_Viewer)をダブルクリックしてUI編集状態にしてみてください。

Containerに適用するclass
Containerに適用するclass
css
.activereports-viewer-host {
    margin: 0 auto;
    width: 100%;
    height: 100vh;
}

 ContainerのStyle Classesプロパティに設定します。Containerに対応するHTMLタグにこのclass名がつくようになります。

Containerのプロパティ
Containerのプロパティ
ライセンスキー取得

 ActiveReportsJSは実行時にライセンスキーを必要とします。そこで、Data ActionでSite Propertyから設定値を取得していきましょう。Data Actionは画面専用のサーバーサイド処理で、サーバー側からデータを取得してくるのに使います。

  ActiveReportsJS_Viewer Blockを右クリックし、Fetch Data from Other Sourcesを選択して作成します。

Data Action追加
Data Action追加
LicenseKeyを取得するData Actionの定義
LicenseKeyを取得するData Actionの定義

 FetchプロパティはAt startのままにします(画面を開くと自動でデータ取得を開始する)。

 Output Parameter LicenseKeyには、Site PropertyのLicenseKeyの値をそのまま編集してください。Output Parameterは、作成したData Action(上の例ではDataActionGetLicenseKey)を右クリックし、Add Output Parameterを選択すると作れます。

Data ActionへのOuput Parameter追加
Data ActionへのOuput Parameter追加
Data Actionの実装
Data Actionの実装
ビューワーのロード

 LicenseKeyの取得を待ちたいのでData ActionのOn After Fetch(Data Action取得終了時に発生するイベント)イベントハンドラーを作成します。

 On After Fetchイベントに対するハンドラーを作成するには、Data Actionを選択するとService Studio右下に表示されるプロパティから、Events > On After Fetchのドロップダウンリストを展開し、New Client Actionを選択します。

On After Fetchイベントハンドラーを追加
On After Fetchイベントハンドラーを追加
On After Fetchの実装
On After Fetchの実装
  1. Service Studio左側にあるツールボックスから、JSON SerializeとJavaScriptをドラッグ&ドロップで、作成されたイベントハンドラーのフローに配置します。
  2. JSON SerializeでInput ParameterのList DataSourceJSONsをJSON形式の文字列に変換します(ListのままではJavaScriptに渡せないため)。
  3. JavaScript要素には、図のようにJavaScriptのInput Parameterを設定します。
    • LicenseKey: Data Actionから取得したActiveReportsJSのライセンスキー
    • ViewerHostId: ビューワーを表示するHTMLタグのId。ContainerのIdは<ContainerのName>.Idで取得できます(このためにNameプロパティは設定必須)
    • ReportDefinitionJSON: Blockの同名のInput Parameter (レポート定義)をそのまま渡す
    • DataJSON: JSON Serializeの結果

 JavaScript要素内の設定は以下の通り。Input Parameterは全て、Data Type=Textです。

JavaScript要素
JavaScript要素
js
// ライセンスキー
MESCIUS.ActiveReportsJS.Core.setLicenseKey($parameters.LicenseKey);
// ビューワー初期化
const viewer = new MESCIUS.ActiveReportsJS.ReportViewer.Viewer("#" + $parameters.ViewerHostId, { language: "ja" });
// レポート定義をJSONからオブジェクトに変換
const report = JSON.parse($parameters.ReportDefinitionJSON);
// レポートオブジェクトに、データソースを読み込む
const dataArray = JSON.parse($parameters.DataJSON);
for (let i = 0; i < dataArray.length; i++) {
    report.DataSources[i].ConnectionProperties.ConnectString = "jsondata=" + dataArray[i];
}
// ビューワーを開く
viewer.open(report);

 開発が終了したら、Publishしておきましょう。

ActiveReportsJSのレポート定義

 ActiveReportsJSが提供するデザイナーアプリケーションを使ってレポート定義を作っていきます。

作成するレポート

 個別の注文情報に対する請求書を、以下のようなレポートとして作成します。

[レポートイメージ
レポートイメージ

 サンプルアプリケーションのOrderDetail画面で持っている以下のAggregateがデータソースとして使えます。

  • GetOrder: 見出し部分のデータソースとして
  • GetOrderItemsByOrderId: 一覧部分のデータソースとして
[OrderDetail画面で取得しているデータ
OrderDetail画面で取得しているデータ

サンプルデータを準備する

 ActiveReportsJSのレポートへのデータソース設定には、以下の方法があります。

  • 外部URLから取得する
  • レポート自体に埋め込む

 OutSystemsは簡単にREST APIを作成できますが、REST APIとWebアプリケーションは、ユーザーの認証を共有しないので、レポート自体に埋め込む方法を取ります。このとき、レポートにデータ構造を知らせるため、サンプルデータが必要になります。

 OrderDetailのAggregateをレポート用画面に一時的にコピーし、結果をJSON Serializeすることでサンプルデータを取得しましょう。OrderManagementモジュールを開き、Order UI Flowに新しい画面を作り、名前はOrderDetailReportに変更。続いて、OrderDetail画面から、Input ParameterのOrderId、AggregateのGetOrder(見出しデータ)とGetOrderItemsByOrderId(一覧データ)をコピーして下さい。

元々あるOrderDetailの3つの要素をOrderDetailReportにコピー&ペースト
元々あるOrderDetailの3つの要素をOrderDetailReportにコピー&ペースト

 ここまでで、作成したOrderDetailReport画面を開く際に、必要なデータが取得されるようになっています。続いて、このデータをJSONに変換したうえで画面に表示しましょう。

 以下の手順は見出しデータ(GetOrder)、一覧データ(GetOrderItemsByOrderId)それぞれに対して行います。ここでは一覧データを例に説明します。

 GetOrderItemsByOrderId AggregateにOn After Fetchイベントハンドラーを作成(GetOrderItemsByOrderIdを選択し、画面右下のプロパティから、Events > On After Fetchのドロップダウンリストを展開、New Client Actionを選択)。

 On After Fetchでは、JSONSerializeによって、GetOrder Aggregateの結果をJSON文字列に変換し、画面表示用のLocal VariableにAssignします(JSONSerializeとAssignはService Studio左側のToolboxからドラッグ&ドロップでFlowに配置)。

On After Fetchの実装
On After Fetchの実装

 JSONSerializeでは、Aggregateの結果(Aggregate名.Listで、DBから出力したレコードのリストを表す)を指定します。

Aggregateの結果をJSON Serializeする
Aggregateの結果をJSON Serializeする

 JSON Serializeした結果を後続のAssignで画面のLocal Variableに保存します(Local Variableは、画面を選択して右クリックし、Add Local Variableを選択。Data TypeはText)。

 Local Variableを画面上にドラッグ&ドロップすると、値を表示するExpressionが配置されます。ここまで実装したらPublishし、ブラウザで画面を表示します(※)。画面に表示されたJSON文字列をテキストエディタなどに一時保存しておいて下さい。

 (※)Service Studio上で画面を選択して右クリック、Open in Browserでその画面がブラウザで開きます。Input Parameter OrderIdが必要なので、ブラウザが開いたら、URLの末尾に「&OrderId=1」を追加してください。1は実在するOrderレコードのIdにする必要があるので、もしIdがお使いの環境でずれて発番されているようなら合わせてください。

レポート定義ファイルを作成

 ActiveReportsJS Designerアプリケーションを起動します。画面上部のファイルメニューをクリックし、新規作成 > 新規レポートの作成からページレポートを選択します。

新規レポートの作成
新規レポートの作成

データを連結

 コピーしておいたサンプルデータのJSONをレポートに埋め込みます。見出しデータで説明しますが、一覧データでも同じ手順を行って下さい。どこからデータを取得するかを定義するデータソースを作成します。画面右上のデータタブを開き、データソース右側の「+ 追加」をクリック。

データソースの追加
データソースの追加

 表示されたダイアログで、以下を入力し、「変更を保存」ボタンをクリック。

  • 名前:DataSource見出し
  • 形式:埋め込みを選択(ダイアログの下半分がJSONデータ入力用に変わる)
  • JSONデータ:用意しておいた見出しデータのサンプルを貼り付ける
データソースの追加 - ダイアログ
データソースの追加 - ダイアログ

 次に、データソースからデータセットを作成します。作成したデータソース右側の「+」アイコンをクリック。

データセットの追加
データセットの追加
  • 名前:DataSource見出し
  • JSONパス:全てのデータを指す「$.*」

 と入力し、「検証」ボタンをクリック。データソースに含まれるフィールドの数が、データベースフィールド項目に反映されます。「変更を保存」ボタンをクリックして入力を保存。

データセットの追加 - ダイアログ
データセットの追加 - ダイアログ

 一覧データでも同じことをすると、以下のようになります。

データセット設定完了後
データセット設定完了後

レポートデザイン

 ActiveReportsJSのレポートデザインは、OutSystemsで画面をデザインする操作と似ています。画面左側のメニューからレポートコントロールをUI上にドラッグ&ドロップで配置し、画面右側でプロパティを設定します。

固定の文字列にはTextBoxコントロール

 画面左側からTextBoxコントロール(コントロール名はマウスオーバーすると表示される)をドラッグ&ドロップして、レポート内に配置します。

TextBoxコントロールの配置
TextBoxコントロールの配置

 配置したコントロールを選択した状態で、画面上部のツールバーや右側のプロパティタブを使って表示内容を調整します。

 「請求書」項目の場合の設定例。

請求書項目のプロパティ
請求書項目のプロパティ
画像はImageコントロールで

 画像を配置したい場所にImageコントロールをドラッグ&ドロップ。

Imageコントロール
Imageコントロール

 手元の画像をレポート内に埋め込みたいときは、外観 > 画像プロパティのリストを展開し、「埋め込み」を選択します。「+ 読み込む」から、使いたい画像ファイルを選択して下さい。

Imageコントロールのプロパティ
Imageコントロールのプロパティ

 この記事のサンプルレポートでは以下の画像を使っています。

社印イメージ
社印イメージ
動的な文字列をTextBoxに表示する

 以下の2か所を、見出しデータセットから動的に表示します。

動的に表示するTextBoxコントロール
動的に表示するTextBoxコントロール

①注文番号

 見出しデータセットの、注文番号(Order.Code)を表示する設定を行います。TextBoxコントロールを選択し、プロパティの値項目右の「●」と式をクリックすると、式エディタが開きます。

式エディタを起動
式エディタを起動

 式欄に出力したい文字列を設定しますが、波括弧({})で囲んだ部分(補間構文)は実行時に評価された結果で置き換えられます。また、ダイアログ左のツリーからデータセット > DataSet見出しと展開し、その下にあるOrder.Codeをダブルクリックすると、この項目を出力する補間構文を式のカーソル位置に挿入してくれます。

 First関数呼び出しが挿入されますが、見出しデータには1件しかデータがないはずなので問題ないでしょう。実際の出力は「注文番号:ORD0001」のようになります。

Order.Codeを編集する式
Order.Codeを編集する式

②宛先

 こちらは請求書送付先となる企業名(Account.Company)を出力します。式は「{First([Account.Company], "DataSet見出し")} 御中」、実行結果例は「Business fluence 御中」のようになります。

Tableへのバインディング

 一覧データには、Tableコントロールを使います。他のコントロールと同じようにドラッグ&ドロップで配置します。

Tableコントロールを配置
Tableコントロールを配置

 配置したTable上でクリックすると以下の状態になります。

Tableの調整
Tableの調整

 列間にマウスオーバーし、現れた+のアイコンをクリックして5列に増やして下さい。次に行ヘッダの位置にあるヘッダ、詳細、フッタを表すアイコンの内、フッタを表すものを選択し、Deleteキーで削除します。このレポートでは一覧内に集計行を表示しないためです。

 各セルにはTextBoxコントロールがあるため、値の設定を行います。ヘッダ行のセルには、固定の文字列を入力して下さい。詳細行には式を入力します。

  1. 商品名の詳細: {[Product.Name]}
  2. 単価の詳細: {[Product.Price]}
  3. 数量の詳細: {[OrderItem.Quantity]}
  4. 値引の詳細: {IIF([OrderItem.Discount] = 0, "", ToString([OrderItem.Discount]) + "%")}
  5. 小計の詳細: {PricePerRow}

 「値引」項目は、IIF(条件式,条件がTrueのときの式, 条件がFalseのときの式)という関数を使っています。OutSystemsにもIfという同じ役割を果たすBuilt-in Functionがありますね。

 「小計」項目は、計算フィールドという機能を使って、DataSetにあらかじめ計算式結果に対応する項目をPricePerRowという名前で用意しておき、その値を表示する指定です。

 計算フィールドを追加するには、一覧データのDataSet右側の編集アイコン(ペンのアイコン)をクリックしてダイアログを表示し、計算フィールド右側の表示アイコン(ハンバーガーアイコン)をクリック。

DataSet一覧の編集 - 開始
DataSet一覧の編集 - 開始

 フィールド名=PricePerRow、値={[OrderItem.Quantity] * [Product.Price] * ((100 - [OrderItem.Discount]) / 100)}と入力し、「変更を保存」ボタンをクリックして確定します。式の意味は、数量 × 単価 × (1-割引率)で割引適用後の小計を出しています。

DataSet一覧の編集 - 計算フィールド
DataSet一覧の編集 - 計算フィールド
集計項目

 Table内で計算フィールドを作っておいたのはここで計算結果を流用するためです。「ご請求金額」の右隣のTextBoxコントロールの値に以下の式を入力して下さい。

 {Sum(PricePerRow, "DataSet一覧")}

 DataSet一覧というDataSet内のPricePerRowをSumという関数で足し合わせた結果を表示する式です。

レポート画面を実装する

 レポート画面は、p2でサンプルデータ取得に使ったOrderDetailReportを修正して作ります。

レポート定義ファイルをJSONとして保存する

 作成したレポートは、アプリケーションからJSON形式のデータとして部品に渡します。そこで、レポート定義をJSONファイルとして保存しておきましょう。デザイナーで、ファイルメニュー > 名前をつけて保存を選択し、ファイル名を「Invoice.rdlx-json」として保存します。保存後、ファイルの拡張子をjsonに変更します(OutSystemsのResourcesに登録するときに許可された拡張子でないとアクセスできないため)。

レポート定義ファイル配置

 Service StudioでOrderManagementモジュールを開き、保存しておいたInvoice.jsonをResourcesにImportします。

Resourcesへのレポート定義ファイル配置
Resourcesへのレポート定義ファイル配置

レポート定義とデータを取得するData Actionを用意

 用意しておいたBlockには、以下2つのInput Parameterが必要です。

  • レポート定義のJSON (Text型)
  • データ(JSON)のList(Text List型)

 そこで、画面にData Actionを作成し、この2つの値を返すことにします。名前はGetJsonにしました。

Screenの実装
Screenの実装
レポート定義のJSON取得部分

 GetJSON Data Actionの中身を作っていきます。Resourcesに登録したInvoice.jsonのContentプロパティでファイルのバイナリを取り出しますが、欲しいのはJSON文字列なのでBinaryDataにあるBinaryDataToTextでText型に変換します。

 BinaryDataはOutSystems公式から提供されている部品で、文字通り、Binary Data型を操作する機能を提供するものです。参照を追加するには、ショートカットキー「Ctrl+Q」か画面上部の電源プラグのアイコンをクリックして「Manage Dependencies」ダイアログを使います。参照手順は次のスクリーンショットをご覧ください。

BinaryDataのBinaryDataToText Actionを参照する手順
BinaryDataのBinaryDataToText Actionを参照する手順

 追加が終わったら、画面左のToolboxからServer Actionのアイコンをドラッグ&ドロップでFlowに追加し、Actionプロパティで今参照したBinaryDataToTextを指定してください。指定するプロパティは次のスクリーンショットを参照します。

Data ActionのAction Flow - レポート定義のJSON取得部分
Data ActionのAction Flow - レポート定義のJSON取得部分
データ(JSON)のList取得部分

 上の行が見出しデータ、下の行が一覧データの取得に対応しています。どちらも以下の流れです。

  1. Aggregateでデータを取得、
  2. JSON SerializeでAggregate結果のListをJSONに変換
  3. ListAppendでData ActionのOutput ParameterにSerializeしたJSONを追加
Data ActionのAction Flow - データ(JSON)のList取得部分
Data ActionのAction Flow - データ(JSON)のList取得部分

画面にBlockを配置

 ActiveReportsJS_PatモジュールのActiveReportsJS_Viewer Blockへの参照を追加しておきます。追加手順はBinaryDataToText Actionのときと同じです。参照を追加すると、以下のようにツリービューにどのモジュールから参照したかがわかるように表示されます。ここに表示されたActiveReportsJS_Viewer Blockを画面にドラッグ&ドロップして配置してください。

Block配置

 追加したら、Blockを画面に配置し、Input Parameterには、Data Actionで取得した値(Output Parameter)を設定します。

Block配置
Block配置

 このBlockはIf Widgetで囲んでおきます。IfのConditionはData Actionの取得終了を表す「GetJSON.IsDataFetched」です。

Block

 Data Actionの取得が終わる前にBlockのロード処理が進んでしまうと、画面から渡すレポート定義が空文字列の状態でビューワーを表示しようとして、エラーになってしまいます。

CSPの設定

 ActiveReportsJSでは、帳票生成をバックグラウンドで行うためにWeb Workerを使用しています。そのため、以下の設定が必要になることがあります。

 ActiveReportsJSのビューワーを表示する際に、「Refused to create a worker from 'blob'」「Failed to construct 'workder': Access to the script at 'blob'」のようなJavaScriptのエラーが出ることが有りました。これはCSP(Content Security Policy) の設定によるエラーなので、LifeTimeで、特定のディレクティブを許可する必要があります。

 ActiveReportsJSはWeb Workerを動的に生成されたスクリプトからロードするので、worker-srcディレクティブにblob:スキームを含める必要があります。

 LifeTimeを開き、Environments > More Security Settingsとリンクをクリックします。

LifeTime
LifeTime

 画面を一番下までスクロールします。

 Other-Directivesに「worker-src blob:;」を追加して「Save」ボタンをクリックします。OutSystemsのOrderManagementモジュールをPublishしなおすと動作するようになりました。

LifeTime - CSP設定
LifeTime - CSP設定

 OutSystemsのCSP設定では、worker-srcディレクティブに対する専用の設定場所がなく(上位に当たるchild-srcの設定はある)、任意のディレクティブを設定できるOther-Directoriesを使っています。上記の設定の代わりに、child-srcディレクティブに「blob:」を追加してもうまくいきます。

動作確認

 ここまでの作業が終わったら、Publishして動作を確認します。OrderDetail画面上で、「Report」ボタンをクリックして、OrderDetailReport画面を開いてみて下さい。以下のようにレポートが埋め込まれた状態で表示されたら、完成です。

完成イメージ
完成イメージ

PDFへのエクスポート

 PDFへのエクスポート機能そのものは、特に設定しなくても使えますが、日本語フォントを使うには準備が必要です。

フォントファイルを準備

 以下のgithubレポジトリにあるフォントを例に手順を説明します。

 ActiveReportsJS-Invoice-IPA-Sampleのレポジトリからfontsフォルダをダウンロードして下さい。Personal Environmentでもテストできるように、フォントファイルをモジュールのResourcesフォルダへ登録する手順で説明します。

 ダウンロードしたフォルダにある、ipag.ttfをActiveReportsJS_PatモジュールのResourcesにインポートして下さい。URLでアクセスできるように、Deploy Actionを「Deploy to Target Directory」に設定します。

フォントファイルをResourcesに登録
フォントファイルをResourcesに登録

レポート定義へのフォント適用

 レポート定義内の項目を、用意したファイル内のフォントを利用するように設定します。デザイナーはデフォルトでは用意したフォントファイルを選択できません。

 以下のドキュメントに従って、設定ファイルを修正していきましょう。

 Windowsの場合は、「C:\Users\\<ユーザ名>\AppData\Roaming\ActiveReportsJS Designer\fontsConfig.json」を開き、"descriptors"配列の最後に以下のように追記して下さい (追加したのは最後のIPAゴシック項目。配列なので、前の項目末尾に「,」を加えるのを忘れずに。また、<OutSystemsのドメイン名>の部分は実際のドメイン名で置き換えて下さい)。

js
(前略)
		{
			"name": "游ゴシック",
			"locals": [
				"游ゴシック",
				"Yu Gothic"
			]
		},
		{
		    "name": "IPAゴシック",
		    "source": "https://<OutSystemsのドメイン名>/ActiveReportsJS_Pat/ipag.ttf"
		}
	]
}

 設定ができたら、レポート定義ファイル(invoice.rdlx-json)をデザイナーで開き、各項目のフォント名の値をIPAゴシックに変更します。変更が終わったら、レポート定義ファイル保存後、invoice.jsonに名前を変え、OrderManagementモジュールのResourcesへインポートし直して下さい。

実行時にライブラリへフォントを適用

 使いたいフォントが標準のものではない場合、以下のドキュメントの手順で、実行時にライブラリに登録する必要があります。

 p2で作成した、ActiveReportsJS_Patモジュール > ActiveReportsJS_Viewer Block > DataActionGetLicenseKeyOnAfterFetch Actionに配置したJavaScriptのコードを修正します。

 ライセンスキー登録とビューワー初期化の間にフォント登録処理を追加しました。

js
// ライセンスキー
MESCIUS.ActiveReportsJS.Core.setLicenseKey($parameters.LicenseKey);
// IPAゴシックフォント登録(PDFエクスポートに使うフォント)
const font = {
    name: "IPAゴシック",
    source: $parameters.FontURL
};
MESCIUS.ActiveReportsJS.Core.FontStore.registerFonts(font);
// ビューワー初期化
const viewer = new MESCIUS.ActiveReportsJS.ReportViewer.Viewer("#" + $parameters.ViewerHostId, { language: "ja" });
(後略)

 JavaScriptのInput ParameterとしてFontURLを追加しています(この値はfontオブジェクトのsourceプロパティへの設定に使用)。

JavaScript要素にInput Parameter FontURLを追加
JavaScript要素にInput Parameter FontURLを追加

 このパラメータには、以下の通り、Resourcesに登録したttfファイルのURLを渡します。

ttfファイルのURLを渡す
ttfファイルのURLを渡す

動作確認

 Publishしたら動作確認してみましょう。ビューワーを開いたら、左側のサイドバーの上から3番目にあるエクスポートのアイコンをクリックし、ファイル形式でPDFファイル(PDF)を選択します。

エクスポート > PDFを選択
エクスポート > PDFを選択

 最下部にある「エクスポート」ボタンをクリックすると、PDFファイルを出力できます。

エクスポートボタン
「エクスポート」ボタン
出力したPDF
出力したPDF

今後の展開

 Blockはこのままの状態でも十分に使えると思いますが、業務アプリケーションで使う帳票にはさまざまな要件があります。その要件を収集し、共通部品として機能を拡張していくともっといいでしょう。

 以下にいくつかの修正例を示します。

必要な帳票の要件を整理し、Blockに不足する機能を追加する

 現在は、ビューワーをデフォルト設定で表示していますが、不要な機能を隠したり、Blockのパラメータで表示する機能を制御したりする要望が出てくるかもしれません。Structureで設定値を受け取るInput Parameterを追加し、その値に応じてビューワーをカスタマイズするといいでしょう。

レポート定義を管理する機能を共通部品に持つ

 この記事では、レポート定義をResourcesに登録していましたが、この方法では、レポート定義の追加・変更に常にプログラムのリリースを伴ってしまいます。レポート定義格納用のEntityを共通部品に保持し、開発者はそのIdを指定することで出力するという変更が考えられます。こうすることで、Publishせずに運用中にレポート定義を追加したり変更したりできるようになります。

APIをラップするAction

 APIを使ってレポートを出力するオプションもあるようです。場合によっては、そのAPIをラップしたClient Actionの部品を用意することも考えられます。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加

提供:メシウス株式会社

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/20262 2024/10/30 12:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング