You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现从Excel提取数据生成动态嵌套JSON的技术需求

解决Java Excel转嵌套JSON的问题

核心问题诊断

你的现有代码是把Excel首行作为键、后续行直接转成扁平键值对,这种方式只会生成行级扁平JSON数组,完全没处理数据的层级关联,自然得不到嵌套结构。要生成动态计算的复杂嵌套JSON,必须先分析Excel数据的层级依赖关系,再按层级聚合数据。

分步解决方案

1. 先定义Excel数据的层级规则

假设你的Excel列结构是(请替换成你实际的列):
顶级分类, 二级分类, 项目名称, 项目值
层级逻辑为:顶级分类 -> 二级分类 -> 项目列表

2. 读取Excel并封装数据

用Apache POI读取Excel,把每行数据封装成实体类,方便后续处理:

import org.apache.poi.ss.usermodel.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ExcelRow {
    private String topCategory;
    private String subCategory;
    private String itemName;
    private String itemValue;

    // 构造器、getter、setter省略
}

// 读取Excel的方法
public List<ExcelRow> readExcel(String filePath) throws Exception {
    List<ExcelRow> rows = new ArrayList<>();
    Workbook workbook = WorkbookFactory.create(new java.io.File(filePath));
    Sheet sheet = workbook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    rowIterator.next(); // 跳过首行表头

    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        ExcelRow excelRow = new ExcelRow();
        excelRow.setTopCategory(row.getCell(0).getStringCellValue());
        excelRow.setSubCategory(row.getCell(1).getStringCellValue());
        excelRow.setItemName(row.getCell(2).getStringCellValue());
        excelRow.setItemValue(row.getCell(3).getStringCellValue());
        rows.add(excelRow);
    }
    workbook.close();
    return rows;
}

3. 按层级聚合生成嵌套结构

用HashMap分组,结合Jackson构建嵌套JSON:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
import java.util.stream.Collectors;

public class NestedJsonGenerator {
    public static void main(String[] args) throws Exception {
        List<ExcelRow> rows = readExcel("your-excel-file.xlsx");

        // 第一步:按顶级分类分组
        Map<String, List<ExcelRow>> topCategoryGroups = rows.stream()
                .collect(Collectors.groupingBy(ExcelRow::getTopCategory));

        // 第二步:构建嵌套结构
        List<Map<String, Object>> nestedResult = new ArrayList<>();
        for (Map.Entry<String, List<ExcelRow>> topEntry : topCategoryGroups.entrySet()) {
            Map<String, Object> topCategoryMap = new HashMap<>();
            topCategoryMap.put("topCategory", topEntry.getKey());

            // 按二级分类分组
            Map<String, List<ExcelRow>> subCategoryGroups = topEntry.getValue().stream()
                    .collect(Collectors.groupingBy(ExcelRow::getSubCategory));

            List<Map<String, Object>> subCategories = new ArrayList<>();
            for (Map.Entry<String, List<ExcelRow>> subEntry : subCategoryGroups.entrySet()) {
                Map<String, Object> subCategoryMap = new HashMap<>();
                subCategoryMap.put("subCategory", subEntry.getKey());

                // 生成项目列表
                List<Map<String, String>> items = subEntry.getValue().stream()
                        .map(row -> {
                            Map<String, String> item = new HashMap<>();
                            item.put("name", row.getItemName());
                            item.put("value", row.getItemValue());
                            return item;
                        })
                        .collect(Collectors.toList());
                subCategoryMap.put("items", items);
                subCategories.add(subCategoryMap);
            }
            topCategoryMap.put("subCategories", subCategories);
            nestedResult.add(topCategoryMap);
        }

        // 转成格式化后的JSON字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String nestedJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(nestedResult);
        System.out.println(nestedJson);
    }
}

4. 适配你的指定嵌套结构

如果你的目标JSON结构有特殊要求(比如某层级是对象而非数组、有动态计算字段),只需要调整分组逻辑和Map的构建即可:

  • 若某层级是唯一对象(而非多个子项),把List<Map>改成单个Map
  • 动态计算字段可以在构建Map时直接添加,比如subCategoryMap.put("totalValue", calculateTotal(subEntry.getValue()))

依赖说明

确保你的pom.xml(Maven)里引入以下依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
</dependencies>

内容的提问来源于stack exchange,提问作者Shyam Sundar V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:13:03