SHOEISHA iD

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

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

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

Djangoで作成したAPIとActiveReportsJSやWijmoを使用したReactアプリを連携させてみよう

メシウスの「ActiveReportsJS」「Wijmo」と「React」「Django REST framework」を組み合わせた活用例 第2回

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

 本記事では、メシウスのライブラリ「ActiveReportsJS」や「Wijmo」をReactと組み合わせて構築したWebページを、Web APIと接続して活用する事例を紹介します。前回は接続対象のWeb APIをPythonのDjango REST frameworkで作成しました。今回はこのWeb APIから取得したデータをActiveReportsJSやWijmoでWebページに表示していきます。

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

はじめに

 メシウスはHTML/CSS/JavaScriptで実装するWebページ向けに複数のライブラリを提供しています。ActiveReportsJSは帳票ライブラリ、WijmoはさまざまなUI部品を提供するライブラリです。本記事では、ActiveReportsJSやWijmoを利用して、サーバーのWeb APIから取得したデータを表示する方法を説明します。

 前回記事では、サーバー側のWeb APIを、Pythonのフレームワーク「Django REST framework」で作成しました。今回はこのWeb APIからデータを取得して、ActiveReportsJSやWijmoをReactと組み合わせたWebページで表示する実装を行っていきます。

対象読者

  • ActiveReportsJSやWijmoの、実利用により近いサンプルを必要としている方
  • Web APIを手軽に実装したい方
  • Django REST frameworkのWeb APIからデータを取得する例を知りたい方

必要な環境

 前回記事で実装し、本記事で参照するWeb APIのサンプルコードは、以下の環境で動作を確認しています。環境構築の手順や実行の方法は、前回記事を参照してください。

  • Windows 10 64bit版
  • Python 3.11.5
  • XAMPP 8.2.4

 本記事で新たに実装するWebページは、以下の環境で動作を確認しています。

  • Windows 10 64bit版
  • Node.js v18.18.0
  • React 18.2.0
  • ActiveReportsJS 4.1.0
  • Wijmo 5.20231.904
  • Microsoft Edge 117.0.2045.47

 Webページのサンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリをダウンロード後、「npm run start」コマンドを実行して、「https://localhost:3000」をWebブラウザーで表示します。

Web APIの微調整

 前回記事で作成したWeb APIは「http://localhost:8000」のURLでアクセスできます。一方、今回作成するWebページのURLは「http://localhost:3000」です。このままではWebページとWeb APIのオリジン(プロトコル、ホスト、ポート番号の組)が異なるため、WebページからWeb APIにアクセスできません。このアクセスを許可するため、オリジン間リソース共有(CORS)の設定をWeb APIに行います。CORSの詳細はMozillaのページも参考にしてください。

 まずPythonのパッケージマネージャーであるpipコマンドをリスト1の通り実行して、django-cors-headersパッケージをインストールします。

[リスト1]django-cors-headersをインストールするコマンド
pip install django-cors-headers

 次にsettings.pyにdjango-cors-headersの設定をリスト2の通り記述します。

[リスト2]django-cors-headersの設定(django_p002phones/p002phones/settings.py)
INSTALLED_APPS = [
(略)
    'corsheaders', #...(1)
]
MIDDLEWARE = [
(略)
    'corsheaders.middleware.CorsMiddleware', #...(2)
]
# CORSを有効にするオリジン ...(3)
CORS_ORIGIN_WHITELIST = [
     'http://localhost:3000',
]

 INSTALLED_APPS(1)、MIDDLEWARE(2)に、それぞれdjango-cors-headersの設定を追加します。また、CORSを有効にするオリジンを表す(3)のCORS_ORIGIN_WHITELIST項目を追加して、Web APIへのアクセスを許可するWebページのオリジン「http://localhost:3000」を設定します。

 以上の設定により、Django REST frameworkで作成したWeb APIに、今回作成するWebページからアクセスできるようになります。

Web APIから取得できるデータを確認

 Webページの実装に入る前に、Web APIから取得できるデータをもう一度確認しておきましょう。今回利用するdjango_p002phonesサンプルでは、スマートフォン機種と会社をWeb APIから取得できます。まず「http://localhost:8000/vendors/」(以下「Vendors API」と呼びます)にアクセスすると、スマートフォンの会社リストをJSON形式でリスト3の通り取得できます。urlは各項目に対応するURL、nameは会社名、regionは国・地域です。

[リスト3]Web APIで取得するスマートフォンの会社リスト(django_p002phones)
[
  {
      "url": "http://localhost:8000/vendors/1/",
      "name": "Apple",
      "region": "アメリカ"
  },
(略)
]

 また「http://localhost:8000/phones/」(以下「Phones API」と呼びます)にアクセスすると、スマートフォン機種リストをJSON形式でリスト4の通り取得できます。urlのほか、nameで製品名、priceで価格を取得できます。vendorには会社のURL(リスト3のurl項目に対応)が格納されます。

[リスト4]Web APIで取得するスマートフォン機種リスト(django_p002phones)
[
  {
      "url": "http://localhost:8000/phones/1/",
      "name": "iPhone 15",
      "price": 124800,
      "vendor": "http://localhost:8000/vendors/1/"
  },
(略)
]

 以下のサンプルでは、これらのデータを取得してWeb画面に表示していきます。

Web APIから取得したデータをWijmoのFlexGridで表示

 最初のサンプルでは、Web APIからデータを取得して、Wijmoが提供するグリッド部品FlexGridで表示します(図1)。

図1 Web APIのデータを表示するWijmoのFlexGrid(p001-wijmo)
図1 Web APIのデータを表示するWijmoのFlexGrid(p001-wijmo)

Reactプロジェクトを生成してFlexGridの実装を追加

 最初に、Reactのプロジェクトを生成してFlexGridの実装を追加するところまで説明します。ベースとするReactプロジェクトは、今回はCreate React Appツールを利用して、リスト5のコマンドで生成します。

[リスト5]Reactプロジェクトを生成するコマンド
npx create-react-app p001-wijmo

 プロジェクト生成後、プロジェクトフォルダーでリスト6のコマンドを実行して、WijmoのReact用Gridコンポーネントをプロジェクトに追加します。

[リスト6]WijmoのGridコンポーネントをプロジェクトに追加するコマンド
npm install @grapecity/wijmo.react.grid

 Webページに対応するReactコンポーネントであるsrc/App.jsに、リスト7の通り実装を加えていきます。

[リスト7]FlexGridを表示するWebページの実装(p001-wijmo/src/App.js)
import { useEffect, useState } from 'react';
import * as wjcGrid from '@grapecity/wijmo.react.grid'; // ...(1)
import * as wjcCore from '@grapecity/wijmo';            // ...(2)
import './App.css'; // ...(3)

function App() {
  // ライセンスキーを設定 ...(4)
  wjcCore.setLicenseKey('<ライセンスキー>');
  // FlexGridに表示するデータをuseStateフックで定義 ...(5)
  const [data, setData] = useState([]);

(略:Web APIからデータを取得する処理)

  // コンポーネント内容を返却 ...(6)
  return (
    <div>
      <h3>Wijmo(FlexGrid)+React+REST API</h3>
      <wjcGrid.FlexGrid itemsSource={data}
        isReadOnly={true} autoGenerateColumns={false}>{/*(6a)*/}
        <wjcGrid.FlexGridColumn
          binding="name" header="機種" width={150} />{/*(6b)*/}
        <wjcGrid.FlexGridColumn
          binding="price" header="価格" width={100} />
        <wjcGrid.FlexGridColumn
          binding="vendorName" header="メーカー" width={100} />
        <wjcGrid.FlexGridColumn
          binding="vendorRegion" header="国・地域" width={100} />
      </wjcGrid.FlexGrid>
    </div>
  );
}
export default App;

 まずimport部では、(1)でWijmoのReact用Gridコンポーネント、(2)でWijmo本体をインポートします。なお(3)のApp.cssではWijmoのCSSを参照するよう記述します(詳細はサンプルコードを参照)。

 Appコンポーネントの実装では、最初に(4)でライセンスキーを設定します。Wijmoのライセンスキーについては公式ドキュメントも参考にしてください。

 (5)では、FlexGridに設定するデータ配列dataと、それを設定する関数setDataを、ReactのuseStateフックで生成します。

 コンポーネントの内容は(6)で返却します。FlexGrid全体を(6a)の<wjcGrid.FlexGrid>コンポーネントで記述します。itemsSource属性は表示するデータの指定、isReadOnly属性(=true)は読み取り専用の指定、autoGenerateColumns属性(=false)は列の自動生成をしない指定です。

 FlexGridの列は(6b)の<wjcGrid.FlexGridColumn>コンポーネントで記述します。binding属性は表示するデータ名、header属性はヘッダーの文言、width属性は列の幅です。ここではname(名前)、price(価格)、vendorName(メーカー名)、vendorRegion(メーカーの国・地域)の4列を表示するようにしています。

Web APIからデータを取得する処理を実装

 次に、Web APIからデータを取得する処理をリスト8の通り実装します。

[リスト8]Web APIからデータを取得する処理(p001-wijmo/src/App.js)
async function fetchData() {
  // Phones/VendorsのWeb APIを実行するPromise ...(1)
  const phonesPromise
    = fetch('http://localhost:8000/phones/').then(res => res.json());
  const vendorsPromise
    = fetch('http://localhost:8000/vendors/').then(res => res.json());
  // 2つのPromise実行を待ち合わせて結果を取得 ...(2)
  const [phonesArray, vendorsArray]
    = await Promise.all([phonesPromise, vendorsPromise]);
  // API結果のJSON配列に含まれるvendor列内に示されたWeb APIのURLから
  // ベンダー情報を取得してjsonObjに追加設定 ...(3)
  for (let i = 0; i < phonesArray.length; i++) {
    const vendorJsonObj = vendorsArray.filter(
      a => a.url === phonesArray[i]['vendor'])[0]; //...(3a)
    phonesArray[i]['vendorName'] = vendorJsonObj.name; //...(3b)
    phonesArray[i]['vendorRegion'] = vendorJsonObj.region; //...(3c)
  }
  // setData関数でdataステートを更新 ...(4)
  setData(phonesArray);
}

 まず(1)で、Phones APIとVendors APIを実行するPromiseを定義します。fetchメソッドにURLを指定して実行後「then(res => res.json())」でレスポンスのJSON文字列をJavaScriptオブジェクトに変換します。

 (2)は、2つのPromise実行を待ち合わせる処理です。2つのWeb API実行を並列で行い、両方のAPIからデータが返却された後に、各Web APIの戻り値がそれぞれphonesArray、vendorsArrayに格納されます。

 (3)では、返却されたスマートフォン機種のそれぞれについて、対応する会社を検索します。phonesArray配列要素のvendor属性に、スマートフォン機種に対応した会社のURLが格納されるため、(3a)のvendorsArray.filterメソッドで、会社データのurlとスマートフォン機種データのvendorが同一のデータを抽出して、スマートフォン機種に対応する会社のJavaScriptオブジェクトvendorJsonObjを取得します。

 その後、会社のJavaScriptオブジェクトから(3b)では名前、(3c)では国・地域を取得して、それぞれvendorName、vendorRegion属性に格納します。ここで追加されたvendorName、vendorRegion属性を参照して、リスト7(6)でFlexGridにデータを表示します。

 リスト8のデータ取得処理は、レンダリング終了後に実行されるReactの副作用フックに、リスト9の通り記述します。

[リスト9]データ取得処理を実行する副作用フック(p001-wijmo/src/App.js)
useEffect(() => {
  // Web APIからデータ取得
  fetchData();
}, []);

 useEffectの第2引数は、変更されたときに副作用を再実行する変数の指定です。ここでは[]、つまり変数が何も指定されないため、最初のレンダリング後のみ副作用(=データ取得処理)が実行されます。

 以上の実装により、Web APIから取得したデータを、FlexGridで図1の通り表示できるようになります。

Web APIから取得したデータをActiveReportsJSの帳票で表示

 同様に、Web APIのデータを、ActiveReportsJSの帳票でも表示していきます(図2)。

図2 Web APIのデータを表示するActiveReportsJSの帳票(p002-activereportsjs)
図2 Web APIのデータを表示するActiveReportsJSの帳票(p002-activereportsjs)

ActiveReportsJSの帳票を表示する処理をReactプロジェクトに追加

 最初に、ReactのプロジェクトにActiveReportsJSの帳票を表示する実装を追加するところまで説明します。Wijmo同様にCreate React AppでReactプロジェクトを生成後、リスト10のコマンドでActiveReportJSをプロジェクトに追加します。「@grapecity/activereports-react」はActiveReportJSのReact用コンポーネント、「@grapecity/activereports-localization」は日本語表示用のパッケージです。

[リスト10]ActiveReportJSをプロジェクトに追加するコマンド
npm install @grapecity/activereports-react @grapecity/activereports-localization

 src/App.jsはリスト11の通り実装します。

[リスト11]ActiveReportsJSの帳票を表示するWebページの実装(p002-activereportsjs/src/App.js)
import '@grapecity/activereports/styles/ar-js-ui.css';
import '@grapecity/activereports/styles/ar-js-viewer.css';
import '@grapecity/activereports-localization';
import { Viewer } from '@grapecity/activereports-react';
import { Core } from '@grapecity/activereports';
import './App.css';

function App() {
  // ライセンスキーを設定 ...(1)
  Core.setLicenseKey('<ライセンスキー>');
  // コンポーネント内容を返却 ...(2)
  return (
    <div id="viewer-host">
      {/* ビューワを指定 ...(2a) */}
      <Viewer report={{ Uri: '/phones.rdlx-json' }}
        language="ja" availableExports={['']} />
    </div>
  )
}
export default App;

 import部で、ActiveReportsJSのCSS(ar-js-ui.css、ar-js-viewer.css)と日本語表示用のパッケージ、ビューワ(Viewer)と本体(Core)をインポートします。App.cssにはActiveReportsJSを全画面表示する記述を行います(詳細はサンプルコードを参照)。

 Appコンポーネントの(1)でライセンスキーを設定します。ActiveReportsJSのライセンスキーについては公式ドキュメントも参考にしてください。

 コンポーネントの内容は(2)で返却します。ActiveReportsJSのビューワに対応するのは(2a)の<Viewer>コンポーネントで、report属性にはレポートファイル(後述)、language属性には言語(ja:日本語)、availableExports属性にはエクスポートできるファイル種類を指定します。エクスポートには追加設定が必要なものがあるため、本サンプルではavailableExports属性に['']を指定して、エクスポート自体を無効にしています。

Web APIからデータを取得するレポートファイルを作成

 ActiveReportsJSで表示するレポートのフォーマットは、ActiveReportsJSに付属するデザイナアプリで作成します。以下では、リスト11(2a)で指定した「phones.rdlx-json」レポートファイルを作成します。ActiveReportsJSデザイナの利用方法は、過去記事でも紹介しているので参考にしてください。

 最初に、レポートに表示するデータを設定します。画面右の「データ」タブでデータソースを追加して、エンドポイントに「http://localhost:8000」を設定します。

図3 データソースの作成(p002-activereportsjs/public/phones.rdlx-json)
図3 データソースの作成(p002-activereportsjs/public/phones.rdlx-json)

 次に、データソースに対応するデータセットを作成します。まずPhones APIに対応するデータセット「PhonesDataSet」を、図4の通り作成します。「Uri/パス」には「/phones/」、「JSONパス」は全てのJSONデータに対応する「$.*」を指定後、「検証」ボタンをクリックすると、API戻り値に対応したフィールド「url」「name」「price」「vendor」が設定されるので、「変更を保存」をクリックして保存します。

図4 データセットの作成(p002-activereportsjs/public/phones.rdlx-json)
図4 データセットの作成(p002-activereportsjs/public/phones.rdlx-json)

 同様の手順で「Uri/パス」に「/vendors/」を指定して、Vendors APIに対応するデータセット「VendorsDataSet」を作成します。データソース、データセットの設定については、ActiveReportsJSの公式ドキュメントも参考にしてください。

 デザイナ画面中央のデザイン面に、繰り返しデータを表示するListをドラッグアンドドロップします。このリストにはスマートフォン機種を表示するので、「プロパティ」-「データセット」は上で設定したPhonesDataSetを設定します。

図5 ListのデータセットにPhonesDataSetを設定(p002-activereportsjs/public/phones.rdlx-json)
図5 ListのデータセットにPhonesDataSetを設定(p002-activereportsjs/public/phones.rdlx-json)

 データを表示するTextBoxをList内に配置します。TextBoxの「...」をクリックして、表示するPhonesDataSetのフィールドを設定します。

図6 TextBoxにPhonesDataSetのフィールドを設定(p002-activereportsjs/public/phones.rdlx-json)
図6 TextBoxにPhonesDataSetのフィールドを設定(p002-activereportsjs/public/phones.rdlx-json)

 スマートフォン機種の各項目にメーカーの情報を表示するため、Listの中にさらにListを入れ子にして配置し、プロパティを図7の通り設定します。データセットにはVendorsDataSetを設定し、また「フィルタ」を追加して設定します。このフィルタ設定により、VendorsDataSetから、urlフィールドがPhonesDataSetのvendorフィールドと等しいデータを抽出するようになります。

図7 メーカーの情報を表示するListの設定(p002-activereportsjs/public/phones.rdlx-json)
図7 メーカーの情報を表示するListの設定(p002-activereportsjs/public/phones.rdlx-json)

 図8のフィルタ設定を行ったListの中にTextBoxを配置すると、図6と同じ手順で、表示するVendorsDataSetのフィールド(name、region)を指定できます。

 表示内容を調整したレポートファイルを図8に示します。ここで網掛け部分はListを繰り返し表示する範囲で、Listの外側に表示される●記号ボタンをドラッグしてページ全体に広げます。このレポートファイルをリスト11(2a)に設定すると、図2の通りデータが表示されます。

図8 完成したレポートファイル(p002-activereportsjs/public/phones.rdlx-json)
図8 完成したレポートファイル(p002-activereportsjs/public/phones.rdlx-json)

まとめ

 本記事では、メシウスのライブラリであるActiveReportsJSやWijmoをReactと組み合わせて使うWebページを作成して、Web APIから取得したスマートフォン機種とメーカーのデータを表示させました。ActiveReportsJSやWijmoの機能を利用すると、Web APIから取得したデータを整形して表示できます。

参考資料

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

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

提供:メシウス株式会社

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

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

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18541 2023/11/27 12:00

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング