
在 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
- 前置准备
- Java 中将 Excel 转换为 JSON——分步详解
- 将 XLS 和 XLSX 文件转换为 JSON
- 处理多工作表工作簿与嵌套 JSON
- 处理空单元格与数据类型
- 常见陷阱
- 总结
- 常见问题
1. 为什么要在 Java 中将 Excel 转换为 JSON
Excel 和 JSON 在现代软件系统中被广泛使用,但它们的定位截然不同。Excel 专为结构化数据录入、分析和报表而设计,支持公式、格式化和多工作表工作簿。而 JSON(JavaScript 对象表示法)是一种轻量级数据格式,用于机器间通信、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.cn/repository/maven-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 支持。本指南使用 Jackson——Java 生态中最广泛使用的 JSON 处理库:
<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. Java 中将 Excel 转换为 JSON——分步详解
整个转换过程分为四个步骤:加载工作簿、读取标题行、遍历数据行以及组装 JSON 输出。本节将逐步讲解,最后给出完整代码。
步骤一:加载 Excel 文件
使用 Workbook 类打开 Excel 文件,然后通过索引获取目标工作表:
Workbook workbook = new Workbook();
workbook.loadFromFile("EmployeeData.xlsx");
Worksheet worksheet = workbook.getWorksheets().get(0);
步骤二:读取标题行
电子表格的第一行通常为列标题。这些标题将作为每条 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();
}
步骤三:遍历数据行并构建 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);
}
步骤四:导出 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);
// 从第一行读取列标题
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" : "John",
"LastName" : "Smith",
"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() 时会自动检测文件格式,因此同一段 Java 代码无需任何修改即可将 XLS 和 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();
// 从第一行读取标题
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"两个工作表的工作簿为例):
{
"East Region": [
{"Employee": "Alice", "Product": "Laptop", "Amount": "1200"},
{"Employee": "Bob", "Product": "Monitor", "Amount": "450"}
],
"West Region": [
{"Employee": "Carol", "Product": "Keyboard", "Amount": "150"},
{"Employee": "Dave", "Product": "Mouse", "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": "Website Redesign",
"tasks": [
{"task": "Design mockups", "assignee": "Alice", "status": "Complete"},
{"task": "Frontend implementation", "assignee": "Bob", "status": "In Progress"}
]
},
{
"name": "Mobile App",
"tasks": [
{"task": "API integration", "assignee": "Carol", "status": "Pending"},
{"task": "UI testing", "assignee": "Dave", "status": "Not Started"}
]
}
]
下图展示了扁平的 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());
}
这种方式确保日期以标准格式(如 "2026-07-02")输出,而非 Excel 内部的数值表示。
7. 常见陷阱
跳过标题行
最常见的错误之一是从第 1 行而非第 2 行开始遍历数据。当第一行包含列标题时,将其包含在数据循环中会产生键和值重复的 JSON 对象。
解决方案: 始终先从第 1 行读取标题,然后从第 2 行开始数据循环。
硬编码列索引
硬编码列位置(如用 worksheet.get(row, 1) 表示"Name")会使代码变得脆弱。一旦 Excel 模板变更、列顺序调整,JSON 的键就无法正确匹配对应的数据。
解决方案: 从第一行动态读取标题,并使用标题数组来分配 JSON 键。这样即使列顺序变更也不会影响转换结果。
数值精度丢失
Excel 以双精度浮点数存储数字。使用 getValue() 返回的是单元格的显示内容(字符串形式)。如果 JSON 输出需要包含原始数值而非字符串,则需进行额外的类型转换。
解决方案: 通过 getType() 检查单元格类型,对数值型单元格使用 getNumberValue() 获取实际数值而非字符串表示。
忽略日期格式
Excel 将日期存储为序列号(如 45109 代表 2023 年 6 月 15 日)。虽然 getValue() 会返回日期单元格的显示内容,但具体格式取决于单元格的数字格式,不同工作簿之间可能不一致。
解决方案: 对日期格式的单元格使用 getDateTimeValue(),并将结果转换为标准 ISO 8601 字符串(yyyy-MM-dd 或 yyyy-MM-dd'T'HH:mm:ss),以确保 JSON 输出格式一致。
未释放工作簿导致内存泄漏
Spire.XLS 的工作簿对象持有非托管资源。如果在处理完成后未调用 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 以简洁的 API 简化了整个转换流程,且无需安装 Microsoft Office。除了 Excel 转 JSON 之外,该库还提供了全面的电子表格功能,包括 PDF 导出、图表创建、公式计算和数据验证。您可以申请 30 天免费许可证,在项目中体验完整功能。
9. 常见问题
如何在 Java 中将 Excel 转换为 JSON?
使用 Spire.XLS for Java 加载 Excel 文件,读取标题行确定 JSON 的键,从第 2 行开始遍历数据行,并将每个单元格的值映射到 Jackson ObjectNode 中对应的键。将所有对象收集到 ArrayNode 中,然后使用 ObjectMapper 将结果写入文件或作为字符串返回。完整代码示例请参见第 3 节。
哪个 Java 库最适合 Excel 转 JSON?
Spire.XLS for Java 提供了全面的 API 来读取 Excel 数据,同时支持 XLS 和 XLSX 格式。它能原生处理单元格类型、公式和格式化,可以方便地提取结构化数据用于 JSON 转换,无需依赖 Microsoft Office 或其他外部组件。
Spire.XLS 能同时处理 XLS 和 XLSX 格式吗?
可以。Spire.XLS for Java 会自动检测文件是传统 XLS 格式(Excel 97–2003)还是现代 XLSX 格式(Excel 2007 及更高版本)。同一段代码适用于两种格式,无需额外配置。详见第 4 节。
getValue() 和 getCellValue() 在 Spire.XLS 中有什么区别?
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 天免费许可证,在购买前体验完整功能。







