使用Java将Excel文件转换为JSON的代码详解
引言
在企业数据整合与系统对接场景中,Excel 文件是最常见的数据载体之一。然而,当需要将 Excel 中的业务数据导入到 Web 应用、移动端或微服务接口时,Excel 的二进制格式并不适合直接传输和解析。JSON 作为轻量级的数据交换格式,已成为 API 通信和数据存储的事实标准。手动将 Excel 数据逐条录入 JSON 不仅效率低下,还极易出错,特别是在处理大量数据或多批次文件时。
通过编程方式将 Excel 转换为 JSON,可以实现批量、自动化的数据提取与结构化输出,将表格中的行列数据映射为标准的键值对结构,便于 RESTful API 传输、数据库存储或前端页面直接消费。
本文将介绍如何使用 Java 从 Excel 文件中读取数据,并将其转换为结构化的 JSON 格式输出。整个过程高度自动化,适用于数据迁移、报表导出、系统对接等场景。
本文使用的方法需要用到 Free Spire.XLS for Java,可通过 Maven 安装:
<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.free</artifactId>
<version>16.3.1</version>
</dependency>1. 创建示例 Excel 文件
为了完整演示整个流程,我们先创建一个包含员工信息的 Excel 文件,模拟企业的人力资源数据表:
import com.spire.xls.*;
public class CreateSampleExcel {
public static void main(String[] args) {
// 1 创建工作簿并获取第一个工作表
Workbook workbook = new Workbook();
Worksheet sheet = workbook.getWorksheets().get(0);
sheet.setName("员工信息");
// 2 写入表头
sheet.get(1, 1).setText("员工编号");
sheet.get(1, 2).setText("姓名");
sheet.get(1, 3).setText("部门");
sheet.get(1, 4).setText("职位");
sheet.get(1, 5).setText("入职日期");
sheet.get(1, 6).setText("月薪(元)");
// 设置表头加粗
for (int col = 1; col <= 6; col++) {
sheet.get(1, col).getStyle().getFont().isBold(true);
}
// 3 写入员工数据
sheet.get(2, 1).setText("EMP001");
sheet.get(2, 2).setText("张三");
sheet.get(2, 3).setText("技术部");
sheet.get(2, 4).setText("高级工程师");
sheet.get(2, 5).setText("2019-03-15");
sheet.get(2, 6).setNumberValue(18000);
sheet.get(3, 1).setText("EMP002");
sheet.get(3, 2).setText("李四");
sheet.get(3, 3).setText("市场部");
sheet.get(3, 4).setText("市场经理");
sheet.get(3, 5).setText("2020-07-01");
sheet.get(3, 6).setNumberValue(15000);
sheet.get(4, 1).setText("EMP003");
sheet.get(4, 2).setText("王五");
sheet.get(4, 3).setText("财务部");
sheet.get(4, 4).setText("财务主管");
sheet.get(4, 5).setText("2018-11-20");
sheet.get(4, 6).setNumberValue(16500);
sheet.get(5, 1).setText("EMP004");
sheet.get(5, 2).setText("赵六");
sheet.get(5, 3).setText("人事部");
sheet.get(5, 4).setText("HR专员");
sheet.get(5, 5).setText("2021-05-10");
sheet.get(5, 6).setNumberValue(12000);
sheet.get(6, 1).setText("EMP005");
sheet.get(6, 2).setText("孙七");
sheet.get(6, 3).setText("技术部");
sheet.get(6, 4).setText("前端开发");
sheet.get(6, 5).setText("2022-01-08");
sheet.get(6, 6).setNumberValue(14000);
// 4 自动调整列宽
sheet.getAllocatedRange().autoFitColumns();
// 5 保存文件
String outputFile = "EmployeeData.xlsx";
workbook.saveToFile(outputFile, ExcelVersion.Version2013);
workbook.dispose();
System.out.println("Excel 文件已创建:" + outputFile);
}
}说明:
Workbook创建新的 Excel 工作簿对象,默认包含三个工作表getWorksheets().get(0)获取第一个工作表get(row, col)通过行列索引访问指定单元格setText()设置文本类型数据,setNumberValue()设置数值类型数据getStyle().getFont().isBold(true)设置单元格字体加粗getAllocatedRange().autoFitColumns()自动调整所有列宽以适应内容
此步骤创建了包含 5 名员工信息的 Excel 文件,为后续 JSON 转换提供源数据。
2. 将整个工作表转换为 JSON 数组
接下来加载刚才创建的 Excel 文件,将工作表中的每一行数据映射为一个 JSON 对象,以第一行作为字段名(键名),最终输出为 JSON 数组:
import com.spire.xls.*;
import com.spire.data.table.DataTable;
public class ExcelToJsonArray {
public static void main(String[] args) {
String inputFile = "EmployeeData.xlsx";
String outputFile = "EmployeeData.json";
// 1 加载 Excel 文件
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
// 2 获取第一个工作表
Worksheet sheet = workbook.getWorksheets().get(0);
// 3 将工作表数据导出为 DataTable
DataTable dataTable = sheet.exportDataTable();
int rowCount = dataTable.getRows().size();
int colCount = dataTable.getColumns().size();
// 4 构建 JSON 数组
StringBuilder jsonBuilder = new StringBuilder();
jsonBuilder.append("[\n");
for (int i = 0; i < rowCount; i++) {
jsonBuilder.append(" {\n");
for (int j = 0; j < colCount; j++) {
String columnName = dataTable.getColumns().get(j).getCaption();
String cellValue = dataTable.getRows().get(i).getString(j);
// 判断值是否为数值类型,决定是否加引号
jsonBuilder.append(" \"").append(escapeJson(columnName)).append("\": ");
if (isNumeric(cellValue)) {
jsonBuilder.append(cellValue);
} else {
jsonBuilder.append("\"").append(escapeJson(cellValue)).append("\"");
}
if (j < colCount - 1) {
jsonBuilder.append(",");
}
jsonBuilder.append("\n");
}
jsonBuilder.append(" }");
if (i < rowCount - 1) {
jsonBuilder.append(",");
}
jsonBuilder.append("\n");
}
jsonBuilder.append("]");
// 5 写入 JSON 文件
try (java.io.FileWriter writer = new java.io.FileWriter(outputFile)) {
writer.write(jsonBuilder.toString());
} catch (Exception e) {
e.printStackTrace();
}
workbook.dispose();
System.out.println("JSON 文件已生成:" + outputFile);
}
// 判断字符串是否为数值
private static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) return false;
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
// 转义 JSON 特殊字符
private static String escapeJson(String value) {
if (value == null) return "";
return value.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
}说明:
loadFromFile()从磁盘加载 Excel 文件exportDataTable()将整个工作表数据导出为DataTable对象,第一行自动作为列名getColumns().get(j).getCaption()获取列名,作为 JSON 的键名getRows().get(i).getString(j)获取指定行列的单元格值isNumeric()辅助方法用于判断值是否为数值,数值类型在 JSON 中不加引号escapeJson()处理 JSON 特殊字符的转义,确保输出格式正确
转换结果:
[
{
"员工编号": "EMP001",
"姓名": "张三",
"部门": "技术部",
"职位": "高级工程师",
"入职日期": "2019-03-15",
"月薪(元)": 18000.0
},
{
"员工编号": "EMP002",
"姓名": "李四",
"部门": "市场部",
"职位": "市场经理",
"入职日期": "2020-07-01",
"月薪(元)": 15000.0
}
]以上仅展示前两条记录,完整输出包含全部 5 名员工数据。每条记录以表头中文作为 JSON 键名,数值类型字段不加引号。
3. 将指定区域数据转换为 JSON 对象
在某些场景下,工作表中可能包含标题行或汇总行,我们只需要提取特定区域的数据。以下示例演示如何跳过表头并选择性地提取数据,同时添加文档级元信息,生成嵌套的 JSON 结构:
import com.spire.xls.*;
import com.spire.data.table.DataTable;
import com.spire.xls.ExportTableOptions;
public class ExcelToNestedJson {
public static void main(String[] args) {
String inputFile = "EmployeeData.xlsx";
String outputFile = "EmployeeReport.json";
// 1 加载 Excel 文件
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
// 2 获取第一个工作表
Worksheet sheet = workbook.getWorksheets().get(0);
// 3 使用 ExportTableOptions 配置导出选项
ExportTableOptions options = new ExportTableOptions();
options.setKeepDataFormat(true);
// 从第2行开始导出(跳过表头),导出到最后一个数据行和列
int startRow = 2;
int startCol = 1;
int endRow = sheet.getLastDataRow();
int endCol = sheet.getLastDataColumn();
DataTable dataTable = sheet.exportDataTable(startRow, startCol, endRow, endCol, options);
int rowCount = dataTable.getRows().size();
int colCount = dataTable.getColumns().size();
// 4 手动定义字段映射(列名 → JSON 键名)
String[] fieldNames = {"employeeId", "name", "department", "position", "hireDate", "salary"};
// 5 构建嵌套 JSON 结构
StringBuilder json = new StringBuilder();
json.append("{\n");
json.append(" \"report_name\": \"员工信息报表\",\n");
json.append(" \"sheet_name\": \"").append(sheet.getName()).append("\",\n");
json.append(" \"total_records\": ").append(rowCount).append(",\n");
json.append(" \"employees\": [\n");
for (int i = 0; i < rowCount; i++) {
json.append(" {\n");
for (int j = 0; j < colCount; j++) {
String key = (j < fieldNames.length) ? fieldNames[j] : "field_" + j;
String value = dataTable.getRows().get(i).getString(j);
json.append(" \"").append(key).append("\": ");
if (isNumeric(value)) {
json.append(value);
} else {
json.append("\"").append(escapeJson(value)).append("\"");
}
if (j < colCount - 1) {
json.append(",");
}
json.append("\n");
}
json.append(" }");
if (i < rowCount - 1) {
json.append(",");
}
json.append("\n");
}
json.append(" ]\n");
json.append("}");
// 6 写入 JSON 文件
try (java.io.FileWriter writer = new java.io.FileWriter(outputFile)) {
writer.write(json.toString());
} catch (Exception e) {
e.printStackTrace();
}
workbook.dispose();
System.out.println("嵌套 JSON 已生成:" + outputFile);
}
private static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) return false;
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
private static String escapeJson(String value) {
if (value == null) return "";
return value.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
}说明:
ExportTableOptions配置导出选项,setKeepDataFormat(true)保留原始数据格式getLastDataRow()和getLastDataColumn()自动获取数据的最后行列位置,避免手动计算范围exportDataTable(startRow, startCol, endRow, endCol, options)导出指定矩形区域的数据- 自定义
fieldNames数组将 Excel 列映射为英文 JSON 键名,更符合 API 接口规范 - 输出结构包含
report_name、sheet_name、total_records等元信息字段,形成嵌套结构
转换结果:
{
"report_name": "员工信息报表",
"sheet_name": "员工信息",
"total_records": 5,
"employees": [
{
"employeeId": "EMP001",
"name": "张三",
"department": "技术部",
"position": "高级工程师",
"hireDate": "2019-03-15",
"salary": 18000.0
},
{
"employeeId": "EMP002",
"name": "李四",
"department": "市场部",
"position": "市场经理",
"hireDate": "2020-07-01",
"salary": 15000.0
}
]
}以上仅展示前两条员工记录。输出结构包含文档级元信息字段,字段名采用英文驼峰命名,更适合直接作为 API 响应使用。
4. 批量转换多工作表为 JSON
当 Excel 文件包含多个工作表时,可以遍历所有工作表,将每个工作表的数据分别转换并合并到一个 JSON 文件中:
import com.spire.xls.*;
import com.spire.data.table.DataTable;
public class MultiSheetToJson {
public static void main(String[] args) {
String inputFile = "MultiSheetData.xlsx";
String outputFile = "AllSheetsData.json";
// 1 创建包含多个工作表的 Excel 文件
Workbook sourceWorkbook = new Workbook();
// 第一个工作表 - 销售数据
Worksheet sheet1 = sourceWorkbook.getWorksheets().get(0);
sheet1.setName("销售数据");
sheet1.get(1, 1).setText("产品");
sheet1.get(1, 2).setText("销量");
sheet1.get(1, 3).setText("销售额");
sheet1.get(2, 1).setText("笔记本电脑");
sheet1.get(2, 2).setNumberValue(1250);
sheet1.get(2, 3).setNumberValue(6250000);
sheet1.get(3, 1).setText("平板电脑");
sheet1.get(3, 2).setNumberValue(890);
sheet1.get(3, 3).setNumberValue(2670000);
// 第二个工作表 - 库存数据
Worksheet sheet2 = sourceWorkbook.getWorksheets().add("库存数据");
sheet2.get(1, 1).setText("产品");
sheet2.get(1, 2).setText("库存数量");
sheet2.get(1, 3).setText("仓库位置");
sheet2.get(2, 1).setText("笔记本电脑");
sheet2.get(2, 2).setNumberValue(350);
sheet2.get(2, 3).setText("A区-01");
sheet2.get(3, 1).setText("平板电脑");
sheet2.get(3, 2).setNumberValue(280);
sheet2.get(3, 3).setText("B区-03");
sourceWorkbook.saveToFile(inputFile, ExcelVersion.Version2013);
sourceWorkbook.dispose();
// 2 加载并遍历所有工作表
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
StringBuilder json = new StringBuilder();
json.append("{\n");
int sheetCount = workbook.getWorksheets().getCount();
for (int s = 0; s < sheetCount; s++) {
Worksheet sheet = workbook.getWorksheets().get(s);
String sheetName = sheet.getName();
DataTable dataTable = sheet.exportDataTable();
int rowCount = dataTable.getRows().size();
int colCount = dataTable.getColumns().size();
json.append(" \"").append(escapeJson(sheetName)).append("\": [\n");
for (int i = 0; i < rowCount; i++) {
json.append(" {\n");
for (int j = 0; j < colCount; j++) {
String key = dataTable.getColumns().get(j).getCaption();
String value = dataTable.getRows().get(i).getString(j);
json.append(" \"").append(escapeJson(key)).append("\": ");
if (isNumeric(value)) {
json.append(value);
} else {
json.append("\"").append(escapeJson(value)).append("\"");
}
if (j < colCount - 1) json.append(",");
json.append("\n");
}
json.append(" }");
if (i < rowCount - 1) json.append(",");
json.append("\n");
}
json.append(" ]");
if (s < sheetCount - 1) json.append(",");
json.append("\n");
}
json.append("}");
// 3 写入 JSON 文件
try (java.io.FileWriter writer = new java.io.FileWriter(outputFile)) {
writer.write(json.toString());
} catch (Exception e) {
e.printStackTrace();
}
workbook.dispose();
System.out.println("多工作表 JSON 已生成:" + outputFile);
}
private static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) return false;
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
private static String escapeJson(String value) {
if (value == null) return "";
return value.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
}说明:
getWorksheets().getCount()获取工作簿中的工作表总数getWorksheets().add("名称")添加新的工作表- 每个工作表的数据以工作表名称为键,组织为 JSON 对象的属性
- 该方案适用于多维度数据汇总,例如同时包含销售、库存、财务等不同工作表
输出结果示例:
{
"销售数据": [
{
"产品": "笔记本电脑",
"销量": 1250.0,
"销售额": 6250000.0
},
{
"产品": "平板电脑",
"销量": 890.0,
"销售额": 2670000.0
}
],
"库存数据": [
{
"产品": "笔记本电脑",
"库存数量": 350.0,
"仓库位置": "A区-01"
},
{
"产品": "平板电脑",
"库存数量": 280.0,
"仓库位置": "B区-03"
}
]
}每个工作表的数据以工作表名称为键,独立组织为 JSON 数组,便于按业务维度分别消费。
应用场景:
- 企业月度综合报表,将不同维度的数据统一输出为 JSON
- 项目管理系统中多工作表数据的统一接口响应
- 跨部门数据汇总,将各部门独立工作表合并为统一数据格式
5. 关键类与方法解析
核心类说明
Workbook 类
Workbook 是 Excel 操作的入口点,代表一个完整的 Excel 文件。
常用方法:
| 方法 | 说明 |
|---|---|
new Workbook() | 创建新的工作簿实例 |
loadFromFile(path) | 从指定路径加载 Excel 文件 |
saveToFile(path, version) | 将工作簿保存为 Excel 文件 |
getWorksheets() | 获取工作簿中的所有工作表集合 |
dispose() | 释放工作簿占用的资源 |
Worksheet 类
Worksheet 代表 Excel 中的单个工作表,是数据操作的主要对象。
常用方法与属性:
| 方法 / 属性 | 说明 |
|---|---|
get(row, col) | 通过行列索引获取指定单元格 |
getRange() | 获取工作表的单元格范围对象 |
getCellRange(row1, col1, row2, col2) | 获取指定矩形区域的单元格范围 |
getName() / setName(name) | 获取或设置工作表名称 |
exportDataTable() | 将整个工作表导出为 DataTable |
exportDataTable(startRow, startCol, endRow, endCol, options) | 导出指定区域为 DataTable |
getLastDataRow() | 获取最后一行数据的行号 |
getLastDataColumn() | 获取最后一列数据的列号 |
getAllocatedRange().autoFitColumns() | 自动调整所有列宽 |
DataTable 类
DataTable 用于存储从工作表导出的表格数据。
常用方法与属性:
| 方法 / 属性 | 说明 |
|---|---|
getRows() | 获取数据行集合 |
getRows().size() | 获取数据行数 |
getRows().get(i).getString(j) | 获取第 i 行第 j 列的值(字符串) |
getColumns() | 获取数据列集合 |
getColumns().size() | 获取数据列数 |
getColumns().get(j).getCaption() | 获取第 j 列的列名 |
ExportTableOptions 类
ExportTableOptions 用于配置数据导出选项。
常用属性:
| 属性 | 说明 |
|---|---|
setKeepDataFormat(boolean) | 是否保留原始数据格式 |
setRenameStrategy(strategy) | 设置列名重复时的重命名策略 |
使用建议:
- 如果原始 Excel 包含日期、百分比等特殊格式,建议启用
setKeepDataFormat(true) - 对于简单的文本和数值数据,可以直接使用无参
exportDataTable()方法
总结
通过本文示例,你已经了解如何使用 Java 将 Excel 文件转换为 JSON 格式。从创建示例数据、整体工作表转换,到指定区域的嵌套结构输出,再到多工作表的批量处理,整个过程高度自动化,特别适用于数据迁移、API 对接、报表导出等场景。
相比手动复制粘贴或依赖在线转换工具,基于 Java 代码的方式具有以下优势:
- 灵活性强:可以自定义 JSON 结构、字段映射和输出格式
- 批量处理高效:支持多工作表、多文件的自动化转换
- 数据可控:可以选择性提取指定区域的数据,过滤无关内容
- 易于集成:可嵌入到 Spring Boot 等 Java 框架中,作为数据接口的一部分
你可以在此基础上扩展更多能力,例如结合 Gson 或 Jackson 库生成更规范的 JSON、添加数据过滤与清洗逻辑、集成到 RESTful API 中实现实时数据查询等。
如果你正在处理 Excel 数据的结构化提取或系统对接需求,这种基于 Java 的方案将为你的工作带来显著提升。
以上就是使用Java将Excel文件转换为JSON的代码详解的详细内容,更多关于Java将Excel转换为JSON的资料请关注脚本之家其它相关文章!
相关文章
Netty中ChannelPoolHandler调用处理程序详解
这篇文章主要介绍了Netty中ChannelPoolHandler调用处理程序详解,Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程,但是你仍然可以使用底层的 API,需要的朋友可以参考下2023-11-11
在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码
在MyBatis的XML映射文件中,<trim>元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示例展示了如何在UPDATE、SELECT、INSERT和SQL片段中使用<trim>元素,以实现动态的SQL构建,感兴趣的朋友一起看看吧2025-01-01
Spring Cloud Eureka 服务上下线监控的实现
这篇文章主要介绍了Spring Cloud Eureka 服务上下线监控的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-09-09


最新评论