Server Componentからのデータ受け渡し
前回のサンプルでは、各ページがクライアントコンポーネントとしてモックデータを直接インポートしていました。実際の業務システムでは、データベースからデータを取得してUIに渡す構造が必要です。Next.jsのApp Routerでは、Server Componentでデータを取得し、Client Componentにpropsで渡すパターンが推奨されています。リスト2、リスト3にこのパターンの実装例を示します。
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} />
);
}
"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)。
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件の明細を持つ受発注データは、orderNumberやpartnerNameといったヘッダー情報が各行に複製された3件のフラットなレコードに展開されます。
Designerでのレポートレイアウト設定
受発注明細レポートでは、Designerでヘッダー情報と明細テーブルを図4のように設定します。
伝票番号や取引先名などのヘッダー情報はテキストボックスで表示します。値の式に=First(Fields!orderNumber.Value)のような=First()関数を使用するのがポイントです(Designer上では{First(orderNumber)}と簡略表記されます)。前述のフラット化処理によって全レコードに同じヘッダー情報が含まれているため、=First()で先頭行の値を取得することで正しいヘッダーが表示されます。取引先名・日付・ステータスなど他のヘッダー項目も同様に=First()を使用します。
明細行はテーブルコンポーネントで表示します。データセット名にOrderItemsを指定し、Details行のセルに=Fields!rowNumber.Value、=Fields!productCode.Valueなどのフィールド参照式をバインドします。Details行はDataSetのレコード数だけ自動的に繰り返されます。
図5は、受発注データをバインドした帳票の表示結果です。

