如何用JavaScript将JSON转CSV并把子项拆分为单独行?
解决方案
你的需求很明确:要把JSON中带数组的字段展开成单独的行,同时保持同一用户的Name和TotalCost仅在第一行显示,后续行留空。下面是修改后的convertToCSV函数,完全适配你想要的输出格式:
function convertToCSV(objArray) { const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray; let str = ''; // 自动提取表头(假设所有数据结构一致,取第一个对象的键) const headers = Object.keys(array[0]); // 写入表头行,用双引号包裹字段避免格式错乱 str += headers.map(header => `"${header.replace(/"/g, '""')}"`).join(',') + '\r\n'; array.forEach(item => { // 确定当前对象需要展开的行数:取数组字段的长度(假设所有数组长度一致) const rowCount = Object.values(item).find(val => Array.isArray(val))?.length || 1; for (let i = 0; i < rowCount; i++) { const line = []; headers.forEach(header => { const value = item[header]; if (Array.isArray(value)) { // 数组字段:取对应索引的元素,无元素时填充"None" const cellValue = value[i] ?? 'None'; line.push(`"${cellValue.toString().replace(/"/g, '""')}"`); } else { // 非数组字段:仅第一行显示值,后续行留空 const cellValue = i === 0 ? value : ''; line.push(`"${cellValue.toString().replace(/"/g, '""')}"`); } }); str += line.join(',') + '\r\n'; } }); return str; }
关键逻辑说明
- 表头与格式兼容:自动提取数据键作为表头,所有字段用双引号包裹,同时转义内容中的引号,避免CSV解析时因特殊字符出错。
- 行展开规则:通过检测数组字段的长度,确定当前对象需要生成多少行;如果没有数组字段则默认生成1行。
- 字段填充规则:
- 数组类型字段(如
SocialPackages、ProductTitle):每行对应数组的一个元素,空值用None填充(和你的示例一致)。 - 非数组类型字段(
Name、TotalCost):仅在当前对象的第一行显示值,后续同对象行留空。
- 数组类型字段(如
适配你的样本数据
用你提供的样本数据测试,生成的CSV内容会和你给出的格式示意图完全匹配,示例片段如下:
"Name","SocialPackages","ProductTitle","ProductCost","TotalCost" "Bruce Lee","None","Sample title","2500","17100" "","None","Another title","600","" "","None","Yet AnotherTitle","1400","" "Bruce Lee","None","Sample title","2500","4580"
额外修正提示
你的download函数里存在几处拼写错误,需要修正才能正确映射字段:
// 修正后的headers和数据映射逻辑 var headers = { Name: 'Name', SocialPackages: "Social Packages", ProductTitle : "Product Title", ProductCost: "Product Cost", TotalCost: "Total Cost" }; itemsFormatted = []; campaignData.forEach((item) => { itemsFormatted.push({ Name: item.Name, SocialPackages: item.SocialPackages || item["Social Packages"], // 兼容原数据的键名拼写差异 ProductTitle: item.ProductTitle, ProductCost: item.ProductCost, TotalCost: item.TotalCost }); });
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

