記事一覧 プロジェクト集 検索 このサイトについて
RSS English

Next.js APIルートでExcelJSを使い、別シート参照ドロップダウン付きテンプレートを動的生成する

Webアプリケーションで「Excelテンプレートをダウンロードしてもらい、記入後にアップロードしてもらう」というワークフローを実装する機会がありました。 要件は以下の通りです。 テンプレートの内容がプロジェクトごとに異なる(メンバーやファイルの一覧が動的に変わる) Excelのドロップダウン(入力規則)で、別シートのデータを選択肢として参照させたい サーバーサイド(Next.js APIルート)でExcelを生成し、ブラウザにダウンロードさせたい これらを ExcelJS で実現できたので、方法を記録します。 ExcelJS ExcelJSは、Node.jsおよびブラウザ上でExcelファイル(.xlsx)の読み書きを行えるライブラリです。GitHubスター14,000以上、npm週間ダウンロード約200万の定番パッケージです。 npm install exceljs スタイル設定、数式、画像挿入など多彩な機能を持ちますが、本記事では**データバリデーション(入力規則)**に焦点を当てます。 テンプレートの構成 今回は4シート構成のExcelを生成します。 シート 役割 Activity 行為の記録(ユーザー入力用) Entity 情報資源の記録(ユーザー入力用) Members メンバー一覧(参照データ) Files ファイル一覧(参照データ) Activityシートの「担当者」列ではMembersシートの値をドロップダウンで選択、Entityシートの「生成元」列ではActivityシートのIDをドロップダウンで選択、という構成です。 APIルートの基本構造 Next.js App RouterのRoute Handlerとして実装します。 // src/app/api/projects/[id]/template/route.ts import { NextRequest, NextResponse } from "next/server"; import ExcelJS from "exceljs"; export async function GET( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { id: projectId } = await params; // 外部APIからデータを取得 const members = await fetchMembers(projectId); const workbook = new ExcelJS.Workbook(); // ... シート作成(後述) const buffer = await workbook.xlsx.writeBuffer(); return new NextResponse(buffer, { status: 200, headers: { "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Content-Disposition": `attachment; filename="template.xlsx"`, }, }); } writeBuffer() でExcelをバイナリに変換し、適切なContent-Typeでレスポンスを返します。 参照データシートの作成 ドロップダウンの選択肢ソースとなるシートを先に作ります。 const membersSheet = workbook.addWorksheet("Members"); membersSheet.columns = [ { header: "表示名", key: "displayName", width: 30 }, { header: "ID", key: "userId", width: 15 }, { header: "URI", key: "uri", width: 50 }, ]; // ヘッダースタイル membersSheet.getRow(1).eachCell((cell) => { cell.font = { bold: true, color: { argb: "FFFFFFFF" } }; cell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FF4472C4" }, }; }); for (const m of members) { membersSheet.addRow({ displayName: `${m.name} (${m.id})`, userId: m.id, uri: m.uri, }); } ドロップダウンの設定 ここが本記事の核心です。ExcelJSの dataValidation プロパティでセルに入力規則を設定します。 ...