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

使用xlsx-js的json_to_sheet生成Excel时多余空单元格问题求助

解决xlsx-js中json_to_sheet生成Excel空行/空单元格问题

问题场景

在Vue3应用中使用xlsx-js库的json_to_sheet方法从JSON列表生成Excel时,若JSON对象是按字段拆分的同键条目(比如单独的name对象和age对象),会导致生成的表格出现多余空单元格,行被"占用"后后续字段会自动换行。

示例代码:

import * as XLSX from 'xlsx'; 

var wb = XLSX.utils.book_new();

var myws = XLSX.utils.json_to_sheet([
{"name": "Peter"},
{"name": "Adam"},
{"age": "13"},
{"age": "25"}
]);
 
XLSX.utils.book_append_sheet(wb, myws, 'my_sheet1' );

当前生成的Excel输出:

|name  |age |
|Peter |    |
|Adam  |    |
|      | 13 |
|      | 25 |

期望输出:

|name  |age |
|Peter | 13 |
|Adam  | 25 |

补充场景:当输入为带分号分隔多值的人员对象(如爱好、好友),因Excel单单元格字符数限制拆分多值为同键的多个JSON对象时,同样会出现空行问题。

解决方案

1. 预处理JSON数据(最优方案)

核心思路是将分散的同索引字段合并为完整的对象,确保每个对象包含所有需要的列字段,这样json_to_sheet就能按行正常映射。

针对基础场景的处理代码:

import * as XLSX from 'xlsx'; 

// 原始拆分的JSON数组
const rawData = [
  {"name": "Peter"},
  {"name": "Adam"},
  {"age": "13"},
  {"age": "25"}
];

// 按字段分组,提取各字段的数组
const grouped = {};
rawData.forEach(item => {
  const key = Object.keys(item)[0];
  if (!grouped[key]) grouped[key] = [];
  grouped[key].push(item[key]);
});

// 合并为完整对象数组
const mergedData = [];
const maxLength = Math.max(...Object.values(grouped).map(arr => arr.length));
for (let i = 0; i < maxLength; i++) {
  const obj = {};
  Object.keys(grouped).forEach(key => {
    obj[key] = grouped[key][i] || ''; // 空值填充空字符串
  });
  mergedData.push(obj);
}

// 生成工作表
var wb = XLSX.utils.book_new();
var myws = XLSX.utils.json_to_sheet(mergedData);
XLSX.utils.book_append_sheet(wb, myws, 'my_sheet1' );

针对补充场景(多值拆分)的处理:
拆分多值时,确保每个拆分后的对象保留所有字段,而非仅保留拆分的字段。比如原对象{"name":"Peter","hobbies":"reading;hiking","age":"25"},拆分爱好时生成:

// 正确的拆分方式
const processedData = [
  {"name":"Peter","hobbies":"reading","age":"25"},
  {"name":"Peter","hobbies":"hiking","age":"25"}
];

这样json_to_sheet生成的表格不会出现空行,同一行的其他字段会自动重复填充,符合Excel展示需求。

2. 生成工作表后手动清理空行

若无法预处理数据,可在生成工作表后遍历单元格,删除全空的行:

import * as XLSX from 'xlsx'; 

// 生成原始工作表
var wb = XLSX.utils.book_new();
var myws = XLSX.utils.json_to_sheet(rawData);
XLSX.utils.book_append_sheet(wb, myws, 'my_sheet1' );

// 获取工作表范围
const range = XLSX.utils.decode_range(myws['!ref']);
const rowsToKeep = [];

// 遍历每一行,检查是否全空
for (let r = range.s.r; r <= range.e.r; r++) {
  let hasData = false;
  for (let c = range.s.c; c <= range.e.c; c++) {
    const cellAddress = XLSX.utils.encode_cell({r, c});
    if (myws[cellAddress]) {
      hasData = true;
      break;
    }
  }
  if (hasData) rowsToKeep.push(r);
}

// 重新构建工作表数据
const newData = [];
rowsToKeep.forEach(r => {
  const row = [];
  for (let c = range.s.c; c <= range.e.c; c++) {
    const cellAddress = XLSX.utils.encode_cell({r, c});
    row.push(myws[cellAddress] ? myws[cellAddress].v : '');
  }
  newData.push(row);
});

// 生成新的工作表并替换原表
const newWs = XLSX.utils.aoa_to_sheet(newData);
wb.Sheets['my_sheet1'] = newWs;

注意事项

  • json_to_sheet的默认行为是按对象出现的顺序依次填充行,若对象缺少之前出现过的键,会自动跳过已占用的行,这是导致空单元格的根本原因。
  • 预处理数据是最高效的解决方案,避免后续额外的工作表操作。

内容的提问来源于stack exchange,提问作者Dielna Reboot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 09:54:22