React中导出嵌套JSON至Excel并实现指定格式需求
React中导出嵌套JSON为指定格式Excel
在React项目中,需要将嵌套结构的JSON数据导出为层级分明的Excel文件,使用XLSX库默认方案只能导出根节点数据,无法处理嵌套的Child、SubChild节点,以下是具体的解决方法。
原始嵌套JSON数据
[ { "Root":"00000", "RootId":"b597b7be58b0", "Index":0, "Child":[ { "ChildId":"48bb0b4be689", "Name":"Dimension", "Index":0, "SubChild0":[ { "SubChildId":"6b620696cf35", "Label":"Sample 2", "Index":1 }, { "SubChildId1":"f6b620696cf38", "Label":"Sample 2", "Index":2 } ] }, { "ChildId-01":"dcf70d3a-60b3-4b8c-8740-48bb0b4be689", "Name":"Weight", "Index":0, "SubChild1":[ { "SubChildId":"f42d99f5-37c5-4ea3-8425-6b620696cf35", "Label":"Sample 2", "Index":1 }, { "SubChildId1":"f42d99f5-37c5-4ea3-8425-6b620696cf35", "Label":"Sample 2", "Index":2 } ] } ] } ]
期望的Excel格式
导出的Excel需呈现层级合并结构:
- 根节点的
Root、RootId、Index字段合并单元格,覆盖其下所有子节点对应的行 - 每个
Child节点的ChildId/ChildId-01、Name、Index字段合并单元格,覆盖其下所有SubChild对应的行 SubChild节点的SubChildId/SubChildId1、Label、Index作为最明细行展示
实现步骤
1. 安装依赖
npm install xlsx
2. 编写数据扁平化与合并配置函数
先将嵌套JSON转换成扁平数组,同时记录需要合并的单元格范围:
import XLSX from 'xlsx'; // 扁平化嵌套数据并生成合并配置 const flattenData = (data) => { const flatRows = []; const merges = []; let startRow = 1; // Excel行号从1开始(表头占第1行) data.forEach(rootItem => { // 统计当前根节点下的总行数:每个Child下的SubChild数量之和 const totalRows = rootItem.Child.reduce((sum, child) => { const subChildKey = Object.keys(child).find(key => key.startsWith('SubChild')); return sum + (child[subChildKey]?.length || 0); }, 0); // 根节点合并配置:覆盖从startRow到startRow+totalRows-1的行 if (totalRows > 0) { merges.push({ s: { r: startRow, c: 0 }, e: { r: startRow + totalRows - 1, c: 0 } }); // Root列 merges.push({ s: { r: startRow, c: 1 }, e: { r: startRow + totalRows - 1, c: 1 } }); // RootId列 merges.push({ s: { r: startRow, c: 2 }, e: { r: startRow + totalRows - 1, c: 2 } }); // Index列 } let currentRow = startRow; rootItem.Child.forEach(child => { const subChildKey = Object.keys(child).find(key => key.startsWith('SubChild')); const subChildList = child[subChildKey] || []; const childRowCount = subChildList.length; // Child节点合并配置 if (childRowCount > 0) { merges.push({ s: { r: currentRow, c: 3 }, e: { r: currentRow + childRowCount - 1, c: 3 } }); // ChildId列 merges.push({ s: { r: currentRow, c: 4 }, e: { r: currentRow + childRowCount - 1, c: 4 } }); // Name列 merges.push({ s: { r: currentRow, c: 5 }, e: { r: currentRow + childRowCount - 1, c: 5 } }); // Index列 } // 生成SubChild行数据 subChildList.forEach(subChild => { flatRows.push({ Root: rootItem.Root, RootId: rootItem.RootId, RootIndex: rootItem.Index, ChildId: child.ChildId || child['ChildId-01'], Name: child.Name, ChildIndex: child.Index, SubChildId: subChild.SubChildId || subChild.SubChildId1, Label: subChild.Label, SubChildIndex: subChild.Index }); currentRow++; }); }); startRow = currentRow; }); return { flatRows, merges }; };
3. 编写导出Excel函数
使用XLSX库将处理后的数据生成Excel文件,并应用合并配置:
const exportToExcel = (data) => { const { flatRows, merges } = flattenData(data); // 创建工作簿和工作表 const worksheet = XLSX.utils.json_to_sheet(flatRows); // 应用合并单元格配置 worksheet['!merges'] = merges; // 创建工作簿并添加工作表 const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'NestedData'); // 导出文件 XLSX.writeFile(workbook, 'NestedData.xlsx'); }; // 使用示例:调用导出函数 const jsonData = [/* 你的嵌套JSON数据 */]; exportToExcel(jsonData);
代码说明
flattenData函数:遍历嵌套JSON,将所有SubChild转换为明细行,同时记录根节点、Child节点需要合并的单元格范围,确保父节点字段能覆盖所有子节点行。exportToExcel函数:利用XLSX的json_to_sheet生成工作表,通过!merges属性设置单元格合并,最终导出Excel文件。
内容的提问来源于stack exchange,提问作者user20240381
相关产品推荐
相关产品推荐

