微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 JavaScript 中将数据导出为 CSV

如何解决在 JavaScript 中将数据导出为 CSV

我有以下格式的数据,

const data = {
    "Class-1": [{
        "section": "A","total": "45","boys": "31","girls": "14","subjects": 3,"class-teacher": "ABC"
    },{
        "section": "B","total": "30","boys": "20","girls": "10","class-teacher": "XYZ"
    }],"Class-2": [{
        "section": "A","total": "40","boys": "25","girls": "15","subjects": 4,"class-teacher": "ABC2"
    }],"Class-3": [{
        "section": "A","total": "44","boys": "29","class-teacher": "ABC3"
    },"girls": "11","class-teacher": "XYZ1"
    }],"Class-4": [{
        "section": "A","total": "50","boys": "30","girls": "20","subjects": 5,"class-teacher": "ABC4"
    }]
}

我想用 JavaScript 将上述数据导出到 CSV 文件中,如下所示,

Expected

我尝试使用 d3-dsv (this),但无法达到预期的效果。使用 d3-dsv,如果我将数据展平为对象的直接数组,我将无法获得类 - Class-1、Class-2、Class-3 和 Class-4。

使用 d3-dsv,如果我以以下格式提供数据,我会得到如下附加的输出数据格式-

[{
    "section": "A","class-teacher": "ABC"
},{
    "section": "B","class-teacher": "XYZ"
},{
    "section": "A","class-teacher": "ABC2"
},"class-teacher": "ABC3"
},"class-teacher": "XYZ1"
},"class-teacher": "ABC4"
}]

CSV 格式输出-

Output

解决方法

迭代Object.entries(),每次迭代创建子标题行并迭代它的数组以推送数据行

const headings = ['section','total','boys','girls','subjects','class-teacher'];

const rows = [headings];

Object.entries(data).forEach(([k,arr])=>{
    const subHeadRow = Array.from(headings,(el,i) => i ? '' : k); 
    rows.push(subHeadRow)
    arr.forEach(o => rows.push(Object.values(o)));
});

const csv = rows.map(row => row.map(JSON.stringify)).join('\r\n')

console.log(csv)
<script>
const data={"Class-1":[{section:"A",total:"45",boys:"31",girls:"14",subjects:3,"class-teacher":"ABC"},{section:"B",total:"30",boys:"20",girls:"10","class-teacher":"XYZ"}],"Class-2":[{section:"A",total:"40",boys:"25",girls:"15",subjects:4,"class-teacher":"ABC2"}],"Class-3":[{section:"A",total:"44",boys:"29","class-teacher":"ABC3"},girls:"11","class-teacher":"XYZ1"}],"Class-4":[{section:"A",total:"50",boys:"30",girls:"20",subjects:5,"class-teacher":"ABC4"}]};
</script>

,

根据@charlieftl,您不需要 D3 来执行此操作。但是,如果您想使用 d3-dsv 库,请查看 d3.csvFormatBody,它将采用一组对象并只提供 csv 格式的行数据,即没有标题。

在下面的示例中,对于第一行,标题来自第一个键的第一个数组项。

然后迭代数据的键,并为每个键在一行上输出它(例如Class-1),然后下面的行来自数组属性。

// linefeed
const lf = `\r\n`;
// keys of object are Class-1,Class-2 etc
const keys = Object.keys(data);
// get headers from 1st array item of 1st key
const headers = Object.keys(data[keys[0]][0]);
// initialise the csv output with the headers
let csv = `${headers}${lf}`;
// for each key,add the Class-N then the rows (with no headers)
keys.forEach(key => csv += `${key}${lf}${d3.csvFormatBody(data[key])}${lf}`);
// output
console.log(csv);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
<script>
const data={"Class-1":[{section:"A","class-teacher":"ABC4"}]};
</script>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。