SHOEISHA iD

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

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

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

ActiveReportsJSとWijmoを使って業務システムへ帳票機能を組み込む

第2回

Server Componentからのデータ受け渡し

 前回のサンプルでは、各ページがクライアントコンポーネントとしてモックデータを直接インポートしていました。実際の業務システムでは、データベースからデータを取得してUIに渡す構造が必要です。Next.jsのApp Routerでは、Server Componentでデータを取得し、Client Componentにpropsで渡すパターンが推奨されています。リスト2、リスト3にこのパターンの実装例を示します。

[リスト2]src/app/reports/page.tsx(Server Component)
import { mockProducts, mockPartners, mockOrders } from "@/lib/mockData";
import ReportsPageClient from "@/components/reports/ReportsPageClient";

export default function ReportsPage() {
  const products = mockProducts.map((p) => ({
    ...p,
    createdAt: p.createdAt.toISOString(),
    updatedAt: p.updatedAt.toISOString(),
  }));
  // …中略…
  return (
    <ReportsPageClient products={products} partners={partners} orders={orders} />
  );
}
[リスト3]src/components/reports/ReportsPageClient.tsx(Client Component)
"use client";
import dynamic from "next/dynamic";
const ReportViewerWithData = dynamic(
  () => import("@/components/reports/ReportViewerWithData"),
  { ssr: false }
);

export default function ReportsPageClient(
  { products, partners }: ReportsPageClientProps
) {
  // …中略(selectedReportによるレポート切り替え)…
  const config = getReportConfig();
  return <ReportViewerWithData
    key={selectedReport} reportUri={config.uri} data={config.data} />;
}

 page.tsxはServer Componentとしてデータの取得・シリアライズを担当し、Date型をtoISOString()で文字列に変換します。Client Component側は"use client"で宣言し、dynamic({ ssr: false })でActiveReportsJS ViewerのSSRを無効化しています。このパターンにより、データの取得元をFirestoreや任意のAPIに差し替えるだけで、UIコードを変更せずにデータソースを切り替えられます。

受発注明細レポートの作成

 ここまでは商品一覧のようなフラットなデータを帳票に表示してきました。しかし、業務システムで最もよく使われる帳票は、受発注伝票のようにヘッダー情報と明細行を組み合わせた伝票形式です。

ネストデータの変換

 受発注データ(Order)はitemsプロパティに明細行の配列(OrderItem[])を持つネスト構造です。ActiveReportsJSのJSONデータソースにこのまま渡すと、明細行を個別のフィールドとして扱えません。そこで、コード側でデータをフラット化してからレポートに渡します(リスト4)。

[リスト4]src/components/OrderReportView.tsx(受発注データのフラット化処理)
function flattenOrder(order: SerializedOrder) {
  return order.items.map((item, index) => ({
    // ヘッダー情報を各明細行に展開
    orderNumber: order.orderNumber,
    type: order.type === "purchase" ? "発注" : "受注",
    partnerName: order.partnerName,
    orderDate: formatDate(order.orderDate),
    deliveryDate: formatDate(order.deliveryDate),
    status: order.status,
    totalAmount: order.totalAmount,
    // 明細行の情報
    rowNumber: index + 1,
    productCode: item.productCode,
    productName: item.productName,
    quantity: item.quantity,
    unitPrice: item.unitPrice,
    amount: item.amount,
  }));
}

 この変換により、各明細行がヘッダー情報を含む独立したレコードになります。例えば、3件の明細を持つ受発注データは、orderNumberpartnerNameといったヘッダー情報が各行に複製された3件のフラットなレコードに展開されます。

Designerでのレポートレイアウト設定

 受発注明細レポートでは、Designerでヘッダー情報と明細テーブルを図4のように設定します。

図5:Designerでの受発注明細レポートのレイアウト
図5:Designerでの受発注明細レポートのレイアウト

 伝票番号や取引先名などのヘッダー情報はテキストボックスで表示します。値の式に=First(Fields!orderNumber.Value)のような=First()関数を使用するのがポイントです(Designer上では{First(orderNumber)}と簡略表記されます)。前述のフラット化処理によって全レコードに同じヘッダー情報が含まれているため、=First()で先頭行の値を取得することで正しいヘッダーが表示されます。取引先名・日付・ステータスなど他のヘッダー項目も同様に=First()を使用します。

 明細行はテーブルコンポーネントで表示します。データセット名にOrderItemsを指定し、Details行のセルに=Fields!rowNumber.Value=Fields!productCode.Valueなどのフィールド参照式をバインドします。Details行はDataSetのレコード数だけ自動的に繰り返されます。

 図5は、受発注データをバインドした帳票の表示結果です。

図6:受発注明細レポートの表示結果
図6:受発注明細レポートの表示結果

次のページ
FlexGrid選択行から帳票を表示する

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

ComponentZine(ActiveReports)byメシウス連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川 幸哉(ナカガワ ユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

提供:メシウス株式会社

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/23819 2026/05/22 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング