Java で Excel を JSON に変換することは、API、ETL パイプライン、データ連携ワークフローを構築するバックエンド開発において頻繁に求められる処理です。本ガイドでは、Spire.XLS for Java を使用して Excel を JSON に変換する方法を紹介します。XLS 形式と XLSX 形式の両方に対応しており、最小限のコードで実装できます。 Excel ファイルはデータ保管やレポート作成に広く利用されていますが、JSON はモダンアプリケーションにおけるデータ交換の標準形式となっています。しかし、Java で手動で Excel から JSON への変換を実装するのは容易ではありません。ファイル解析、データ型の扱い、空セル、複数シート構造などに対応する必要があり、すぐに複雑でエラーの多いコードになってしまいます。 Spire.XLS for Java と Jackson を組み合わせることで、Excel スプレッドシートを構造化された JSON データに、クリーンで保守性の高いコードで変換できます。本記事では、Java による Excel から JSON への変換について、単一シート変換、複数シート処理、ネスト JSON 構造までを含む完全なチュートリアルを提供します。 目次 Java で Excel を JSON に変換する理由 事前準備 Excel を JSON に変換する手順 XLS ファイルと XLSX ファイルの JSON 変換 複数シートブックとネスト JSON の処理 空セルとデータ型の処理 よくある落とし穴 まとめ よくある質問 1. Java で Excel を JSON に変換する理由 Excel と JSON はモダンなソフトウェアシステムで広く利用されていますが、その役割は大きく異なります。Excel は構造化データの入力、分析、レポート作成に特化しており、数式、書式設定、複数シートブックをサポートしています。一方、JSON(JavaScript Object Notation)は軽量なデータ形式で、マシン間通信、REST API、設定ファイル、NoSQL データベースなどに使用されます。 この違いから、Java 開発者はスプレッドシートベースのデータをバックエンドシステムに統合する際に、Excel を JSON に変換する必要がよくあります。 代表的なユースケース: REST API 連携 —— ユーザーがアップロードした Excel データを JSON に変換して API レスポンスとして返す ETL ワークフロー —— スプレッドシートデータを抽出し、JSON に変換してデータベースやデータレイクへ投入 設定マイグレーション —— Excel ベースのレガシー設定を JSON ベースのマイクロサービスに移行 自動レポート生成 —— Excel テンプレートを構造化 JSON に変換して下流処理に連携 Java アプリケーションにおいて、Excel を JSON に変換する処理は、単に行を読み込んで列をマッピングするだけではありません。実際のファイルには、一貫性のないデータ型、空セル、日付書式の問題、複数シート構造などが含まれることが多く、手動での解析は複雑かつエラーが発生しやすくなります。 Spire.XLS for Java はこのプロセスを簡素化し、XLS と XLSX の両形式に対応した統合 API を提供します。セル値、データ型、書式情報に直接アクセスできるため、低レベルのファイル解析に煩わされることなく、堅牢な Excel から JSON への変換ロジックを実装できます。 2. 事前準備 Excel から JSON への変換を始める前に、以下の依存関係をプロジェクトに設定してください。 Maven で Spire.XLS for Java をインストール(推奨) Spire.XLS for Java は e-iceblue Maven リポジトリから入手できます。pom.xml にリポジトリと依存関係を追加してください: <repositories> <repository> <id>com.e-iceblue</id> <name>e-iceblue</name> <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url> </repository> </repositories> <dependency> <groupId>e-iceblue</groupId> <artifactId>spire.xls</artifactId> <version>16.6.5</version> </dependency> Spire.XLS for Java をダウンロードして、手動でプロジェクトに追加することも可能です。 JSON ライブラリの追加 Java にはビルトインの JSON サポートがありません。本ガイドでは、Java エコシステムで最も広く採用されている Jackson を使用します: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.17.2</version> </dependency> 必要なクラスのインポート Java ソースファイルに以下のインポート文を含めてください: import com.spire.xls.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.File; import java.io.IOException; 3. Excel を JSON に変換する手順 変換プロセスは 4 つのステップで構成されます。ワークブックの読み込み、ヘッダー行の読み取り、データ行の走査、そして JSON 出力の組み立てです。各ステップを順に説明し、最後に完全なコードを示します。 ステップ 1:Excel ファイルを読み込む Workbook クラスを使用して Excel ファイルを開き、インデックスで対象シートを取得します: Workbook workbook = new Workbook(); workbook.loadFromFile("EmployeeData.xlsx"); Worksheet worksheet = workbook.getWorksheets().get(0); ステップ 2:ヘッダー行を読み取る スプレッドシートの 1 行目には通常、列見出しが含まれています。これらが各 JSON レコードのキーになります。String 配列に読み取ります: int columnCount = worksheet.getLastColumn(); String[] headers = new String[columnCount]; for (int col = 1; col <= columnCount; col++) { headers[col - 1] = worksheet.get(1, col).getValue(); } ステップ 3:データ行を走査して JSON オブジェクトを構築する 2 行目から順に走査し、各行に対して ObjectNode を作成します。各セルの値を対応するヘッダーキーにマッピングします: ObjectMapper mapper = new ObjectMapper(); ArrayNode arrayNode = mapper.createArrayNode(); for (int row = 2; row <= worksheet.getLastRow(); row++) { ObjectNode record = mapper.createObjectNode(); for (int col = 1; col <= columnCount; col++) { record.put(headers[col - 1], worksheet.get(row, col).getValue()); } arrayNode.add(record); } ステップ 4:JSON を出力する Jackson の ObjectMapper を使用して、ArrayNode を整形付きでファイルに書き出します: try { mapper.writerWithDefaultPrettyPrinter().writeValue(new File("EmployeeData.json"), arrayNode); System.out.println("JSON exported successfully."); } catch (IOException e) { System.err.println("Failed to write JSON file: " + e.getMessage()); } workbook.dispose(); 完全なコード例 以下は、Excel ファイルを読み込んで JSON に変換する完全なプログラムです: import com.spire.xls.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.File; import java.io.IOException; public class ExcelToJsonConverter { public static void main(String[] args) { // Excel ワークブックを読み込む Workbook workbook = new Workbook(); workbook.loadFromFile("EmployeeData.xlsx"); // 最初のシートを取得 Worksheet worksheet = workbook.getWorksheets().get(0); // 1 行目から列ヘッダーを読み取る int columnCount = worksheet.getLastColumn(); String[] headers = new String[columnCount]; for (int col = 1; col <= columnCount; col++) { headers[col - 1] = worksheet.get(1, col).getValue(); } // Jackson ObjectMapper と ArrayNode を作成 ObjectMapper mapper = new ObjectMapper(); ArrayNode arrayNode = mapper.createArrayNode(); // 各データ行を JSON オブジェクトに変換 for (int row = 2; row <= worksheet.getLastRow(); row++) { ObjectNode record = mapper.createObjectNode(); for (int col = 1; col <= columnCount; col++) { record.put(headers[col - 1], worksheet.get(row, col).getValue()); } arrayNode.add(record); } // JSON を整形してファイルに書き出す try { mapper.writerWithDefaultPrettyPrinter().writeValue(new File("EmployeeData.json"), arrayNode); System.out.println("Excelデータは正常にJSONへ変換されました。"); } catch (IOException e) { System.err.println("JSONファイルの書き込みエラー:" + e.getMessage()); } // ワークブックのリソースを解放 workbook.dispose(); } } 出力 JSON の例(Name、Department、Email、Salary 列を持つ Excel ファイルの場合): [ { "EmployeeID" : "E001", "FirstName" : "ジョン", "LastName" : "スミス", "Department" : "エンジニアリング", "Position" : "ソフトウェアエンジニア", "Salary" : "85000", "HireDate" : "2022/3/15 0:00:00" } ] 下図は、元の Excel データと変換後の JSON 出力を比較したものです。 Spire.XLS の主要クラスとメソッド Workbook —— Excel ファイルを表し、ワークブックの読み込み、保存、管理を行います。 Worksheet —— ワークブック内の単一シートを表し、行、列、セルへのアクセスを提供します。 get(int row, int column) —— 指定されたセルの CellRange オブジェクトを返します。行と列のインデックスは 1 から始まります。 getValue() —— セルの表示値を返します。getText() とは異なり、セルのデータ型(テキスト、数値、日付など)に関係なく正しく値を取得できます。 getLastRow() / getLastColumn() —— データが含まれる最終行番号と最終列番号を返します。 また、Java で Excel を CSV に変換する方法も参考になります。軽量な表形式でのデータ交換・保管が必要な場合に有用です。 4. XLS ファイルと XLSX ファイルの JSON 変換 Spire.XLS for Java は、従来の XLS 形式(Excel 97–2003)と最新の XLSX 形式(Excel 2007 以降)の両方をサポートしています。loadFromFile() を呼び出す際にファイル形式が自動検出されるため、XLS を JSON に変換する場合も XLSX を JSON に変換する場合も、同じコードで対応できます。 // XLSX を JSON に変換(最新形式) Workbook xlsxWorkbook = new Workbook(); xlsxWorkbook.loadFromFile("SalesReport.xlsx"); // XLS を JSON に変換(レガシー形式) Workbook xlsWorkbook = new Workbook(); xlsWorkbook.loadFromFile("SalesReport.xls"); // 両方のワークブックを同じ方法で処理 Worksheet sheet = xlsxWorkbook.getWorksheets().get(0); int rowCount = sheet.getLastRow(); int colCount = sheet.getLastColumn(); // ... 基本サンプルと同じ変換ロジック 追加設定、形式フラグ、分岐コードは不要です。レガシーシステムからの .xls ファイルでも、最新アプリケーションからの .xlsx ファイルでも、Spire.XLS は透過的に解析を行います。Excel ファイルが異なるソースから提供され、複数の形式世代にまたがるエンタープライズ環境で特に有用です。 また、Java で XLS と XLSX を相互に変換する方法も参考になります。ファイル形式のマイグレーションやレガシー形式のアップグレードが必要な場合に有用です。 5. 複数シートブックとネスト JSON の処理 実務で利用される Excel ブックには複数のシートが含まれていることが一般的です。各シートを個別の JSON 配列に変換することで、ブックの構造を保持した構造化出力が得られます。また、データの階層関係を反映したネスト JSON オブジェクトを構築する必要がある場合もあります。 複数シートを JSON に変換 以下の例では、ブック内のすべてのシートを読み込み、各キーがシート名、各値がそのシートのレコード配列である JSON オブジェクトを作成します: import com.spire.xls.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.File; import java.io.IOException; public class MultiSheetExcelToJson { public static void main(String[] args) { Workbook workbook = new Workbook(); workbook.loadFromFile("SalesReport.xlsx"); ObjectMapper mapper = new ObjectMapper(); ObjectNode fullReport = mapper.createObjectNode(); // ワークブック内の各シートを走査 for (int s = 0; s < workbook.getWorksheets().getCount(); s++) { Worksheet worksheet = workbook.getWorksheets().get(s); String sheetName = worksheet.getName(); // 1 行目からヘッダーを読み取る int columnCount = worksheet.getLastColumn(); String[] headers = new String[columnCount]; for (int col = 1; col <= columnCount; col++) { headers[col - 1] = worksheet.get(1, col).getValue(); } // データ行を JSON オブジェクトに変換 ArrayNode sheetData = mapper.createArrayNode(); for (int row = 2; row <= worksheet.getLastRow(); row++) { ObjectNode record = mapper.createObjectNode(); for (int col = 1; col <= columnCount; col++) { record.put(headers[col - 1], worksheet.get(row, col).getValue()); } sheetData.add(record); } // このシートのデータを最終出力に追加 fullReport.set(sheetName, sheetData); } // 統合した JSON を整形してファイルに書き出す try { mapper.writerWithDefaultPrettyPrinter().writeValue(new File("SalesReport.json"), fullReport); System.out.println("複数シートのワークブックはJSONに変換されました。"); } catch (IOException e) { System.err.println("JSONファイルの書き込みエラー:" + e.getMessage()); } workbook.dispose(); } } 出力例(「East Region」と「West Region」シートを含むブックの場合): { "東部地域": [ {"Employee": "佐藤", "Product": "ノートパソコン", "Amount": "1200"}, {"Employee": "鈴木", "Product": "モニター", "Amount": "450"} ], "西部地域": [ {"Employee": "高橋", "Product": "キーボード", "Amount": "150"}, {"Employee": "田中", "Product": "マウス", "Amount": "75"} ] } 下図は、複数の Excel シートが単一の JSON オブジェクト構造にどのようにマッピングされるかを示しています。 Excel データからネスト JSON を構築する フラットな配列ではなく、ネスト構造の JSON が必要となる場面もあります。例えば、プロジェクト管理スプレッドシートで、プロジェクトとそのタスクが隣接する列に記載されている場合です。以下のコードでは、タスクを親プロジェクトごとにグループ化します: import com.spire.xls.*; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ArrayNode; import java.util.LinkedHashMap; import java.util.Map; import java.io.File; import java.io.IOException; public class NestedExcelToJson { public static void main(String[] args) { Workbook workbook = new Workbook(); workbook.loadFromFile("ProjectTasks.xlsx"); Worksheet worksheet = workbook.getWorksheets().get(0); ObjectMapper mapper = new ObjectMapper(); // LinkedHashMap を使用してプロジェクトの挿入順を保持 Map<String, ObjectNode> projectMap = new LinkedHashMap<>(); for (int row = 2; row <= worksheet.getLastRow(); row++) { String projectName = worksheet.get(row, 1).getValue(); String taskName = worksheet.get(row, 2).getValue(); String assignee = worksheet.get(row, 3).getValue(); String status = worksheet.get(row, 4).getValue(); // 初出のプロジェクトはエントリを作成 if (!projectMap.containsKey(projectName)) { ObjectNode project = mapper.createObjectNode(); project.put("name", projectName); project.set("tasks", mapper.createArrayNode()); projectMap.put(projectName, project); } // タスクオブジェクトを構築してプロジェクトのタスク配列に追加 ObjectNode task = mapper.createObjectNode(); task.put("task", taskName); task.put("assignee", assignee); task.put("status", status); ((ArrayNode) projectMap.get(projectName).get("tasks")).add(task); } // 最終的な JSON 配列を組み立て ArrayNode projectsJson = mapper.createArrayNode(); for (ObjectNode project : projectMap.values()) { projectsJson.add(project); } try { mapper.writerWithDefaultPrettyPrinter() .writeValue(new File("ProjectTasks.json"), projectsJson); System.out.println("ネストされたJSONファイルの生成に成功しました。"); } catch (IOException e) { System.err.println("JSONファイルの書き込みエラー:" + e.getMessage()); } workbook.dispose(); } } 出力例(プロジェクト・タスク管理スプレッドシートの場合): [ { "name": "ウェブサイトリニューアル", "tasks": [ {"task": "デザインモックアップ作成", "assignee": "佐藤", "status": "完了"}, {"task": "フロントエンド実装", "assignee": "鈴木", "status": "進行中"} ] }, { "name": "モバイルアプリ", "tasks": [ {"task": "API連携", "assignee": "高橋", "status": "保留中"}, {"task": "UIテスト", "assignee": "田中", "status": "未着手"} ] } ] 下図は、フラットな Excel 行データがプロジェクト単位でグループ化されたネスト JSON 構造に変換される様子を示しています。 このパターンは、Excel データを API スキーマやデータベースのドキュメントモデルに適合する階層形式に再構成する場合に有用です。 また、Java で Excel ファイルを解析する方法も参考になります。変換前に生のスプレッドシートデータを抽出・処理する必要がある場合に有用です。 6. 空セルとデータ型の処理 本番環境の Excel ファイルに、整った完全なデータが含まれていることは稀です。空セル、混在するデータ型、書式の不整合は日常的に発生します。堅牢な Java の Excel→JSON 変換プログラムは、こうした状況に適切に対応できなければなりません。 空セルの検出と処理 CellRange.getType() を使用して、値を読み取る前にセルが空かどうかを確認します。JSON 出力に null が含まれないよう、デフォルト値を設定します: CellRange cell = worksheet.get(row, col); String value; if (cell.getType() == CellValueType.Empty) { value = ""; // または "N/A" などのデフォルト値 } else { value = cell.getValue(); } record.put(headers[col - 1], value); 注: Jackson では、ObjectNode.put(String, String) は文字列値用です。他の型には put(String, double) や put(String, boolean) などのメソッドを使用してください。 JSON 出力でデータ型を保持する getValue() メソッドはセルの表示値を文字列として返します。数値データについては、getNumberValue() を使用することで、JSON 出力で元の型を保持できます: CellRange cell = worksheet.get(row, col); if (cell.getType() == CellValueType.Number) { record.put(headers[col - 1], cell.getNumberValue().doubleValue()); } else if (cell.getType() == CellValueType.Boolean) { record.put(headers[col - 1], cell.getBooleanValue()); } else { record.put(headers[col - 1], cell.getValue()); } 日付書式セルの処理 Excel は日付を内部的にシリアル番号として保存しています。JSON に ISO 8601 形式の文字列で日付を出力するには、日付書式を検出し、適切に変換する必要があります: CellRange cell = worksheet.get(row, col); if (cell.getType() == CellValueType.DateTime) { java.util.Date date = cell.getDateTimeValue(); java.text.SimpleDateFormat iso = new java.text.SimpleDateFormat("yyyy-MM-dd"); record.put(headers[col - 1], iso.format(date)); } else { record.put(headers[col - 1], cell.getValue()); } この方法により、日付が Excel の内部数値表現ではなく、標準的な形式(例:"2026-07-02")で出力されます。 7. よくある落とし穴 ヘッダー行を読み飛ばしてしまう 最もよくあるミスの一つは、データ走査を 2 行目ではなく 1 行目から始めてしまうことです。1 行目に列見出しが含まれている場合、データループに含めるとキーと値が重複した JSON オブジェクトが生成されます。 対策: 必ず 1 行目からヘッダーを読み取り、データループは 2 行目から開始してください。 列インデックスのハードコード 列位置をハードコードする(例:worksheet.get(row, 1) で「Name」を取得)と、コードが脆くなります。Excel テンプレートが変更され列順が変わると、JSON のキーが意図したデータに対応しなくなります。 対策: 1 行目から動的にヘッダーを読み取り、ヘッダー配列を使って JSON のキーを割り当ててください。これにより、列順の変更があっても変換処理が壊れることはありません。 数値精度の損失 Excel は数値を倍精度浮動小数点数で保存します。getValue() を使うとセルの表示内容が取得できますが、結果は常に文字列になります。JSON 出力に文字列ではなく生の数値を含めたい場合は、追加の型変換が必要です。 対策: getType() でセル型を確認し、数値セルには getNumberValue() を使用して、文字列表現ではなく実際の数値を取得してください。 日付書式を無視する Excel は日付をシリアル番号(例:2023年6月15日 = 45109)として表現します。getValue() は日付セルの表示内容を返しますが、正確な形式はセルの数値書式に依存し、ブック間で一貫しない場合があります。 対策: 日付書式のセルには getDateTimeValue() を使用し、結果を標準的な ISO 8601 文字列(yyyy-MM-dd または yyyy-MM-dd&#39;T&#39;HH:mm:ss)に変換して、JSON 出力の形式を統一してください。 ワークブックを解放しないことによるメモリリーク Spire.XLS の Workbook オブジェクトはアンマネージドリソースを保持しています。処理後に dispose() を呼び出さないと、特に複数ファイルを一括変換する際にメモリリークが発生する可能性があります。 対策: 変換完了後は必ず workbook.dispose() を呼び出してください。例外が発生した場合でも確実にリソースを解放するため、try-finally ブロックを使用します: Workbook workbook = new Workbook(); try { workbook.loadFromFile("EmployeeData.xlsx"); // ... 変換処理 ... } finally { workbook.dispose(); } 8. まとめ 本記事では、Spire.XLS for Java を使用して Excel を JSON に変換する方法を解説しました。基本的な単一シート変換から始まり、ワークブックの読み込み、ヘッダーベースのキーマッピング、JSON 出力の生成を順を追って説明しました。さらに、XLS/XLSX 形式の処理、複数シートブック、ネスト JSON 構造、空セルの処理、データ型の保持までを扱いました。 Spire.XLS for Java は、Microsoft Office のインストールを必要とせず、クリーンな API で変換プロセス全体を簡素化します。Excel→JSON 変換に加え、PDF エクスポート、グラフ作成、数式計算、データ検証など、包括的なスプレッドシート機能を提供しています。30日間の無料ライセンスを申請して、すべての機能をプロジェクトで試してみてください。 9. よくある質問 Java で Excel を JSON に変換するには? Spire.XLS for Java で Excel ファイルを読み込み、ヘッダー行を読み取って JSON のキーを決定し、2 行目からデータ行を走査して、各セルの値を Jackson の ObjectNode 内の対応するキーにマッピングします。すべてのオブジェクトを ArrayNode に収集し、ObjectMapper を使ってファイルに書き出すか文字列として返します。完全なコード例はセクション 3を参照してください。 Excel→JSON 変換に最適な Java ライブラリは? Spire.XLS for Java は、XLS と XLSX の両形式をサポートする包括的な API を提供します。セル型、数式、書式をネイティブで処理できるため、Microsoft Office やその他の外部依存を必要とせず、JSON 変換用の構造化データを簡単に抽出できます。 Spire.XLS は XLS と XLSX の両形式に対応していますか? はい。Spire.XLS for Java は、ファイルが従来の XLS 形式(Excel 97–2003)か最新の XLSX 形式(Excel 2007 以降)かを自動的に検出します。追加設定なしで、同じコードで両方の形式を処理できます。詳しくはセクション 4を参照してください。 Spire.XLS の getValue() と getCellValue() の違いは? getValue() はセルの表示値を返します。すべてのデータ型(テキスト、数値、日付、ブール値など)に対応し、ユーザーがセルで見る内容をそのまま返します。getCellValue() は基となる生の値を Object 型で返します。JSON 出力を Excel でユーザーが見る内容と一致させたい場合は getValue() を、数値やブール値の型付き値が必要な場合は getNumberValue() や getBooleanValue() を使用してください。 Excel→JSON 変換時に空セルをどう処理すればよいですか? 値を読み取る前に CellRange.getType() でセル型を確認してください。型が CellValueType.Empty の場合は、空文字列や "N/A" などのデフォルト値を割り当てます。これにより null エントリを防ぎ、すべてのレコードで一貫した JSON 構造を確保できます。コード例はセクション 6を参照してください。 Spire.XLS for Java は無料ですか? Spire.XLS for Java は商用ライブラリです。無料版の Free Spire.XLS for Java も提供されていますが、シート数や機能に制限があります。30日間の無料ライセンスを申請して、購入前にフル機能をお試しいただくことも可能です。