如何将 JSON 转换为 CSV 格式并存储在一个变量中

我有一个在浏览器中打开 JSON 数据的链接,但不幸的是,我不知道如何读取它。有没有一种方法来转换这个数据使用 JavaScript 的 CSV 格式,并保存在 JavaScript 文件?

数据看起来是这样的:

{
"count": 2,
"items": [{
"title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
"description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China\u2019s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store\u2019s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone",
"link": "http:\/\/wik.io\/info\/US\/309201303",
"timestamp": 1326439500,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http:\/\/wikio.com\/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "2388575404943858468"
}, {
"title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
"description": "SHANGHAI \u2013 Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
"link": "http:\/\/wik.io\/info\/US\/309198933",
"timestamp": 1326439320,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http:\/\/wikio.com\/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "16209851193593872066"
}]
}

我能找到的最接近的是: 将 JSON 格式转换为 MSExcel 的 CSV 格式

但它下载在一个 CSV 文件,我存储在一个变量,整个转换的数据。

还想知道如何更改转义字符: '\u2019'恢复正常。


我试过这个代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">


<head>
<title>JSON to CSV</title>
<script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
<script type="text/javascript">
var json3 = {
"count": 2,
"items": [{
"title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
"description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store’s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone",
"link": "http://wik.io/info/US/309201303",
"timestamp": 1326439500,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http://wikio.com/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "2388575404943858468"
},
{
"title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
"description": "SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
"link": "http://wik.io/info/US/309198933",
"timestamp": 1326439320,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http://wikio.com/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "16209851193593872066"
}
]
}
//var objJson = JSON.parse(json3.items);


DownloadJSON2CSV(json3.items);


function DownloadJSON2CSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;


var str = '';


for (var i = 0; i < array.length; i++) {
var line = '';


for (var index in array[i]) {
line += array[i][index] + ',';
}


line.slice(0, line.Length - 1);


str += line + '\r\n';
}
$('div').html(str);
}
</script>


</head>


<body>
<div></div>
</body>


</html>

但好像不管用,有人能帮忙吗?

387308 次浏览

好吧,我终于让这个代码工作:

<html>
<head>
<title>Demo - Covnert JSON to CSV</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>


<script type="text/javascript">
// JSON to CSV Converter
function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';


for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (line != '') line += ','


line += array[i][index];
}


str += line + '\r\n';
}


return str;
}


// Example
$(document).ready(function () {


// Create Object
var items = [
{ name: "Item 1", color: "Green", size: "X-Large" },
{ name: "Item 2", color: "Green", size: "X-Large" },
{ name: "Item 3", color: "Green", size: "X-Large" }];


// Convert Object to JSON
var jsonObject = JSON.stringify(items);


// Display JSON
$('#json').text(jsonObject);


// Convert JSON to CSV & Display CSV
$('#csv').text(ConvertToCSV(jsonObject));
});
</script>
</head>
<body>
<h1>
JSON</h1>
<pre id="json"></pre>
<h1>
CSV</h1>
<pre id="csv"></pre>
</body>
</html>

非常感谢所有贡献者的支持。

Praney

Praneybehl 的解决方案非常好,但是如果有人想要将数据保存为 csv文件并使用 blob方法,那么他们可以参考以下内容:

function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {


//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
var CSV = '';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";


//This loop will extract the label from 1st index of on array
for (var index in arrData[0]) {
//Now convert each value to string and comma-seprated
row += index + ',';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}


//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData[i]) {
row += '"' + arrData[i][index] + '",';
}
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}


if (CSV == '') {
alert("Invalid data");
return;
}


//this trick will generate a temp "a" tag
var link = document.createElement("a");
link.id = "lnkDwnldLnk";


//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);


var csv = CSV;
blob = new Blob([csv], { type: 'text/csv' });
var csvUrl = window.webkitURL.createObjectURL(blob);
var filename =  (ReportTitle || 'UserExport') + '.csv';
$("#lnkDwnldLnk")
.attr({
'download': filename,
'href': csvUrl
});


$('#lnkDwnldLnk')[0].click();
document.body.removeChild(link);
}

将 json 转换为 csv 的一个更优雅的方法是不使用任何框架来使用 map 函数:

var json = json3.items
var fields = Object.keys(json[0])
var replacer = function(key, value) { return value === null ? '' : value }
var csv = json.map(function(row){
return fields.map(function(fieldName){
return JSON.stringify(row[fieldName], replacer)
}).join(',')
})
csv.unshift(fields.join(',')) // add header column
csv = csv.join('\r\n');
console.log(csv)

产出:

title,description,link,timestamp,image,embed,language,user,user_image,user_link,user_id,geo,source,favicon,type,domain,id
"Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)","Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store’s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone","http://wik.io/info/US/309201303","1326439500","","","","","","","","","wikio","http://wikio.com/favicon.ico","blogs","wik.io","2388575404943858468"
"Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)","SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone","http://wik.io/info/US/309198933","1326439320","","","","","","","","","wikio","http://wikio.com/favicon.ico","blogs","wik.io","16209851193593872066"

更新 ES6(2016)

使用这种不那么密集的语法,并使用 JSON.stringify 向字符串中添加引号,同时保持数字不带引号:

const items = json3.items
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(items[0])
const csv = [
header.join(','), // header row first
...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
].join('\r\n')


console.log(csv)

写简历。

function writeToCsv(dataToWrite, callback) {
var dataToWrite;
var fs = require('fs');
dataToWrite = convertToCSV(dataToWrite);
fs.writeFile('assets/distanceInfo.csv', dataToWrite, 'utf8', function (err) {
if (err) {
console.log('Some error occured - file either not saved or corrupted file saved.');
} else{
console.log('It\'s saved!');
}
callback("data_saved | assets/distanceInfo.csv")
});
}


function convertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (line != '') line += ','


line += array[i][index];
}
str += line + '\r\n';
}
return str;
}

有多种选择可以重用现有的基于标准的强大库。

如果您碰巧在项目中使用 D3,那么您可以简单地调用:

函数将对象数组转换为 csv 字符串。

d3.csv.formatRows使您能够更好地控制将哪些属性转换为 csv。

请参阅 D3.csv.format格式行维基页面。

还有其他可用的库,比如 Jquery-csv帕帕帕斯。 Papa Parse 没有依赖关系,甚至连 jQuery 都没有。

对于基于 jquery 的插件,请使用 看看这个

我只是想在这里为将来的人们添加一些代码,因为我试图将 JSON 导出到一个 CSV 文档并下载它。

我使用 $.getJSON从外部页面提取 json 数据,但是如果您有一个基本数组,那么可以直接使用它。

这使用 Christian Landgren 的代码来创建 csv 数据。

$(document).ready(function() {
var JSONData = $.getJSON("GetJsonData.php", function(data) {
var items = data;
const replacer = (key, value) => value === null ? '' : value; // specify how you want to handle null values here
const header = Object.keys(items[0]);
let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
csv.unshift(header.join(','));
csv = csv.join('\r\n');


//Download the file as CSV
var downloadLink = document.createElement("a");
var blob = new Blob(["\ufeff", csv]);
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = "DataDump.csv";  //Name the file here
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
});
});

编辑: 值得注意的是,JSON.stringify将通过添加 \"来转义引号。如果您在 excel 中查看 CSV,它不喜欢将其作为转义字符。

您可以将 .replace(/\\"/g, '""')添加到 JSON.stringify(row[fieldName], replacer)的末尾,以便在 excel 中正确地显示它(这将用 Excel 喜欢的 ""替换 \")。

全线: let csv = items.map(row => header.map(fieldName => (JSON.stringify(row[fieldName], replacer).replace(/\\"/g, '""'))).join(','));

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JSON to CSV</title>
<script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
</head>
<body>
<h1>This page does nothing....</h1>


<script type="text/javascript">
var json3 = {
"count": 2,
"items": [{
"title": "Apple iPhone 4S Sale Cancelled in Beijing Amid Chaos (Design You Trust)",
"description": "Advertise here with BSA Apple cancelled its scheduled sale of iPhone 4S in one of its stores in China’s capital Beijing on January 13. Crowds outside the store in the Sanlitun district were waiting on queues overnight. There were incidents of scuffle between shoppers and the store’s security staff when shoppers, hundreds of them, were told that the sales [...]Source : Design You TrustExplore : iPhone, iPhone 4, Phone",
"link": "http://wik.io/info/US/309201303",
"timestamp": 1326439500,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http://wikio.com/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "2388575404943858468"
},
{
"title": "Apple to halt sales of iPhone 4S in China (Fame Dubai Blog)",
"description": "SHANGHAI – Apple Inc said on Friday it will stop selling its latest iPhone in its retail stores in Beijing and Shanghai to ensure the safety of its customers and employees. Go to SourceSource : Fame Dubai BlogExplore : iPhone, iPhone 4, Phone",
"link": "http://wik.io/info/US/309198933",
"timestamp": 1326439320,
"image": null,
"embed": null,
"language": null,
"user": null,
"user_image": null,
"user_link": null,
"user_id": null,
"geo": null,
"source": "wikio",
"favicon": "http://wikio.com/favicon.ico",
"type": "blogs",
"domain": "wik.io",
"id": "16209851193593872066"
}
]
};


const items = json3.items
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(items[0])
let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
csv.unshift(header.join(','))
csv = csv.join('\r\n')


var link = document.createElement("a");
link.id="lnkDwnldLnk";
document.body.appendChild(link);
blob = new Blob([csv], { type: 'text/csv' });
var csvUrl = window.webkitURL.createObjectURL(blob);
var filename = 'UserExport.csv';
jQuery("#lnkDwnldLnk")
.attr({
'download': filename,
'href': csvUrl
});
jQuery('#lnkDwnldLnk')[0].click();
document.body.removeChild(link);
</script>
</body>
</html>

这里有一种方法,可以用面向对象的方式为较新的 js 版本的动态深度对象做到这一点。你可能需要一个区域一个区域地更改分离器类型。

private ConvertToCSV(objArray) {
let rows = typeof objArray !== "object" ? JSON.parse(objArray) : objArray;
let  header = "";
Object.keys(rows[0]).map(pr => (header += pr + ";"));


let str = "";
rows.forEach(row => {
let line = "";
let columns =
typeof row !== "object" ? JSON.parse(row) : Object.values(row);
columns.forEach(column => {
if (line !== "") {
line += ";";
}
if (typeof column === "object") {
line += JSON.stringify(column);
}  else {
line += column;
}
});
str += line + "\r\n";
});
return header + "\r\n" + str;
}

如果有人也想下载的话。
下面是一个非常棒的小函数,它将把一个 JSON 对象数组转换成 csv,然后下载它。

downloadCSVFromJson = (filename, arrayOfJson) => {
// convert JSON to CSV
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(arrayOfJson[0])
let csv = arrayOfJson.map(row => header.map(fieldName =>
JSON.stringify(row[fieldName], replacer)).join(','))
csv.unshift(header.join(','))
csv = csv.join('\r\n')


// Create link and download
var link = document.createElement('a');
link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(csv));
link.setAttribute('download', filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};

那就这么说吧:

this.downloadCSVFromJson(`myCustomName.csv`, this.state.csvArrayOfJson)

有趣的是没有什么是完整的,也不能在这里工作(IE 或 node.js)。回答类似的问题,一个有点结构化的 JSON (假设不需要再次复制它) ,也包括演示片段。 JSON 到 CSV 转换(JavaScript) : 如何正确格式化 CSV 转换 希望不仅单一的类型转换器,还可以对我的 Github (在概要中提到)类似的未知 JSON 结构进行分析。 我是这个答案中的代码的作者,也是 Github 上所有代码的作者(除了一些以 fork/+ 翻译开始的项目)。

我个人会使用 D3-dsv库来做这个。为什么到 reinvent the wheel


import { csvFormat } from 'd3-dsv';
/**
* Based on input data convert it to csv formatted string
* @param (Array) columnsToBeIncluded array of column names (strings)
*                which needs to be included in the formated csv
* @param {Array} input array of object which need to be transformed to string
*/
export function convertDataToCSVFormatString(input, columnsToBeIncluded = []) {
if (columnsToBeIncluded.length === 0) {
return csvFormat(input);
}
return csvFormat(input, columnsToBeIncluded);
}

使用 摇树,您只需从 d3-dsv库中导入该特定函数即可

试试这些例子

例子一:

JsonArray = [{
"AccountNumber": "123",
"AccountName": "abc",
"port": "All",
"source": "sg-a78c04f8"


}, {
"Account Number": "123",
"Account Name": "abc",
"port": 22,
"source": "0.0.0.0/0",
}]


JsonFields = ["Account Number","Account Name","port","source"]


function JsonToCSV(){
var csvStr = JsonFields.join(",") + "\n";


JsonArray.forEach(element => {
AccountNumber = element.AccountNumber;
AccountName   = element.AccountName;
port          = element.port
source        = element.source


csvStr += AccountNumber + ',' + AccountName + ','  + port + ',' + source + "\n";
})
return csvStr;
}

例子二:

JsonArray = [{
"AccountNumber": "1234",
"AccountName": "abc",
"inbound": [{
"port": "All",
"source": "sg-a78c04f8"
},
{
"port": 22,
"source": "0.0.0.0/0",
}]
}]


JsonFields = ["Account Number", "Account Name", "port", "source"]


function JsonToCSV() {
var csvStr = JsonFields.join(",") + "\n";


JsonArray.forEach(element => {
AccountNumber = element.AccountNumber;
AccountName = element.AccountName;
        

element.inbound.forEach(inboundELe => {
port = inboundELe.port
source = inboundELe.source
csvStr += AccountNumber + ',' + AccountName + ',' + port + ',' + source + "\n";
})
})
return csvStr;
}

您甚至可以使用以下代码下载 csv 文件:

function downloadCSV(csvStr) {


var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvStr);
hiddenElement.target = '_blank';
hiddenElement.download = 'output.csv';
hiddenElement.click();
}

我想即兴复述“克里斯蒂安 · 兰德格伦上面的回答。我很困惑为什么我的 CSV 文件只有3列/标题。这是因为 json 中的第一个元素只有3个键。所以你需要小心使用 const header = Object.keys(json[0])线。它假设数组中的第一个元素是有代表性的。我有一个混乱的 JSON,其中一些对象或多或少拥有。

因此,我添加了一个 array.sort,它将按键数对 JSON 进行排序。这样你的 CSV 文件就有了最大的列数。

这也是一个可以在代码中使用的函数!

function convertJSONtocsv(json) {
if (json.length === 0) {
return;
}


json.sort(function(a,b){
return Object.keys(b).length - Object.keys(a).length;
});


const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(json[0])
let csv = json.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
csv.unshift(header.join(','))
csv = csv.join('\r\n')


fs.writeFileSync('awesome.csv', csv)
}

有时候物体有不同的长度。所以我和 Kyle Pennell 遇到了同样的问题。但是我们不对数组进行排序,而是遍历它并选择最长的。与第一次排序时的 O (n log (n))相比,时间复杂度降低到 O (n)。

我从 Christian Landgren 更新的 ES6(2016)版本的代码开始。

json2csv(json) {
// you can skip this step if your input is a proper array anyways:
const simpleArray = JSON.parse(json)
// in array look for the object with most keys to use as header
const header = simpleArray.map((x) => Object.keys(x))
.reduce((acc, cur) => (acc.length > cur.length ? acc : cur), []);


// specify how you want to handle null values here
const replacer = (key, value) => (
value === undefined || value === null ? '' : value);
let csv = simpleArray.map((row) => header.map(
(fieldName) => JSON.stringify(row[fieldName], replacer)).join(','));
csv = [header.join(','), ...csv];
return csv.join('\r\n');
}

普拉尼贝尔 回答的适应工作与嵌套对象和制表符分隔符

function ConvertToCSV(objArray) {
let array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
if(!Array.isArray(array))
array = [array];


let str = '';


for (let i = 0; i < array.length; i++) {
let line = '';
for (let index in array[i]) {
if (line != '') line += ','


const item = array[i][index];
line += (typeof item === 'object' && item !== null ? ConvertToCSV(item) : item);
}
str += line + '\r\n';
}


do{
str = str.replace(',','\t').replace('\t\t', '\t');
}while(str.includes(',') || str.includes('\t\t'));


return str.replace(/(\r\n|\n|\r)/gm, ""); //removing line breaks: https://stackoverflow.com/a/10805198/4508758
}

下面是我将一个对象数组转换为 CSV 的简单版本(假设这些对象共享相同的属性) :

var csv = []
if (items.length) {
var keys = Object.keys(items[0])
csv.push(keys.join(','))
items.forEach(item => {
let vals = keys.map(key => item[key] || '')
csv.push(vals.join(','))
})
}


csv = csv.join('\n')

下面是使用优化良好的 csv 插件得到的最新答案: (这里的代码可能不能在 stackoverflow 上工作,但是可以在你的项目中工作,因为我已经亲自测试过了)

使用 JqueryJquery.csv库(非常好的优化和完美的转义) Https://github.com/typeiii/jquery-csv

// Create an array of objects
const data = [
{ name: "Item 1", color: "Green", size: "X-Large" },
{ name: "Item 2", color: "Green", size: "X-Large" },
{ name: "Item 3", color: "Green", size: "X-Large" }
];


// Convert to csv
const csv = $.csv.fromObjects(data);


// Download file as csv function
const downloadBlobAsFile = function(csv, filename){
var downloadLink = document.createElement("a");
var blob = new Blob([csv], { type: 'text/csv' });
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = filename;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}


// Download csv file
downloadBlobAsFile(csv, 'filename.csv');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.tutorialjinni.com/jquery-csv/1.0.11/jquery.csv.min.js"></script>

一个简单的函数,将嵌套的 JS 对象(不带数组)转换为内联格式的 csv 格式。

const Obj2Csv = (data, level = 0) => (
Object.keys(data).reduce((prevValue, currValue) => {
if (typeof data[currValue] === 'object' && !Array.isArray(data[currValue])) {
// format a deeper object
const formattedObjProp = `${prevValue}${','.repeat(level)}${currValue}\r\n`;
level++;
const formattedObj = `${formattedObjProp}${Obj2Csv(data[currValue], level)}`;
level--;
return formattedObj;
}
return `${prevValue}${','.repeat(level)}${currValue},${data[currValue]}\r\n`
}, '')
)


const obj = {
baz: {
foo: {
bar: 5
}
}
};


console.log(Obj2Csv(obj))

这是我的解决方案,因为这里没有其他人支持动态列(他们使用第一行来确定列) :

function toCsv(summary, replacer = (_, v) => v) {
let csv = [[]]


for (const data of summary) {
let row = []
for (const column in data) {
let columnIndex = csv[0].indexOf(column)


if (columnIndex === -1) {
columnIndex = csv[0].length
csv[0].push(column)
}


row[columnIndex] = replacer(column, data[column])
}
csv.push(row.join(","))
}


csv[0] = csv[0].join(",")


return csv.join("\r\n")
}

如果需要转换某列的值,可以传递 replacer函数。

一种将对象数组转换为 CSV 的优雅方法:

const convertToCsv = (arr) => {
const keys = Object.keys(arr[0]);
const replacer = (_key, value) => value === null ? '' : value;
const processRow = row => keys.map(key => JSON.stringify(row[key], replacer)).join(',');
return [ keys.join(','), ...arr.map(processRow) ].join('\r\n');
};

以文件形式下载:

const downloadFile = (fileName, data) => {
var link = document.createElement('a');
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
link.setAttribute('download', fileName);
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};

我发现公认的答案非常有用,但是需要我的解决方案来处理非结构化的 json 对象。

我已经修改了可接受的答案,使其适用于大小和模式不同的非结构化对象数组。

输入:

[
{
"name": "Item 1",
"color": "Green",
"sizerange": {
"max": "X-Large",
"min": "X-Small"
}
},
{
"name": "Item 2",
"color": "Green",
"size": "X-Large",
"owner": {
"name": "Bill",
"address": {
"line1": "1 test st",
"suburb": "testville"
}
}
},
{
"name": "Item 3",
"color": "Green",
"sizes": [
"X-Large",
"Large",
"Small"
]
}
]

产出:

"name","color","sizerange.max","sizerange.min","size","owner.name","owner.address.line1","owner.address.suburb","sizes.0","sizes.1","sizes.2"
"Item 1","Green","X-Large","X-Small","","","","","","",""
"Item 2","Green","","","X-Large","Bill","1 test st","testville","","",""
"Item 3","Green","","","","","","","X-Large","Large","Small"

// JSON to CSV Converter


//https://www.codegrepper.com/code-examples/javascript/javascript+array+to+csv+string
function objectToCSVRow(dataObject) {
var dataArray = [];
for (var o in dataObject) {
var innerValue = typeof dataObject[o] == 'undefined' ? '' : dataObject[o].toString();
var result = innerValue.replace(/"/g, '""');
result = '"' + result + '"';
dataArray.push(result);
}
return dataArray.join(',') + '\r\n';
}


//https://stackoverflow.com/a/6491621
function findbystring(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}




function pushUnique(arr, item) {
if (item != "" && !arr.includes(item))
arr.push(item);
}




function getLabels(name, item, labels) {
if (typeof item == 'object') {
for (var index in item) {
thisname = ""
if (name != "") thisname = name + ".";
thisname += index;
getLabels(thisname, item[index], labels);
}
} else {
pushUnique(labels, name);
}
}


function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';


var labels = [];


for (var i = 0; i < array.length; i++) {
getLabels("", array[i], labels);


}


str += objectToCSVRow(labels);
  

for (var i = 0; i < array.length; i++) {


var line = [];
for (var label in labels) {


line.push(findbystring(array[i], labels[label]));


}


str += objectToCSVRow(line);
}


return str;
}


// Example
$(document).ready(function() {


// Create Object
var items = [{
name: "Item 1",
color: "Green",
sizerange: {
max: "X-Large",
min: "X-Small"
}
},
{
name: "Item 2",
color: "Green",
size: "X-Large",
owner: {
name: "Bill",
address: {
line1: "1 test st",
suburb: "testville"
}
}
},
{
name: "Item 3",
color: "Green",
sizes: ["X-Large", "Large", "Small"]
}
];


// Convert Object to JSON
var jsonObject = JSON.stringify(items, null, 2);


// Display JSON
$('#json').text(jsonObject);


// Convert JSON to CSV & Display CSV
$('#csv').text(ConvertToCSV(jsonObject));
});
<html>


<head>
<title>Demo - Covnert JSON to CSV</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>


<script type="text/javascript">
</script>
</head>


<body>
<h1>
JSON</h1>
<pre id="json"></pre>
<h1>
CSV</h1>
<pre id="csv"></pre>
</body>


</html>

export function convertJsontoCSV(jsonData, fileName = "sheet.csv") {
/*  *This function converts the jsonData into CSV and then downloads it
*the jsonData is supposed to be array of Objects with similar structure
*the fileName should be provided otherwise it will set the default name as below.
*/


/* The code that converts the jsonData into CSV data*/
let json = jsonData
let fields = Object.keys(json[0])
let replacer = function (key, value) { return value === null ? '' : value }
let csv = json.map(function (row) {
return fields.map(function (fieldName) {
return JSON.stringify(row[fieldName], replacer)
}).join(',')
})
csv.unshift(fields.join(','))
csv = csv.join('\r\n');


/* The code that downloads the CSD data as a .csv file*/
let downloadLink = document.createElement("a");
let blob = new Blob(["\ufeff", csv]);
let url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = fileName;  //Name the file here
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}

下面的函数是在上述答案的帮助下编写的。

这就是我所做的。当我有一个 JSON 格式的对象数组时,我使用了这个函数。首先,CSV 有很多种口味。所以我用这种方法处理它,我的文件似乎在电子表格编辑器中可以打开。改编自 RFC4180和 MIME 标准/维基百科:

  1. 每条记录应该包含相同数量的逗号分隔的字段。
  2. 任何字段都可以引用(带双引号)。
  3. 如果使用双引号来包围字段,则字段中的双引号必须由两个双引号字符表示。(内部“用”转义)
  4. 某种回车/行进给

我知道还有更复杂、更快、更优雅的方法,但这里有一个可读的、希望可以理解的函数,它将接受 JSON 并返回带有这些约束的 csv。

下面是该函数的概要,同样没有针对性能进行优化,因为它使用了2次传递。

  1. 遍历每个数组条目,并在第一次通过时获取和收集所有密钥名称。
  2. 根据键名制作标题
  3. 在第二次传递时,遍历条目并使用键写入值。

如果它未定义,不要写“未定义”,而是写“”。 如果它不是一个字符串,则将其字符串化。(毕竟它是有效的 JSON,所以只需要使用 JSON.stringify。)这将处理对象、数组、 null、 boolean 等。 如果它是一个字符串做什么当然。

现在用“”代替任何内饰。

现在,将每个条目包装成一个由逗号分隔、没有空格的“”外对。

不要忘记行与行之间的新行 n。

结果是一个字符串,可以在大多数电子表格中轻松打开。

function makeCSVFromJSON(myJSON) {


//FIRST PASS// -- collect field names for csv table
let fieldNamesArray = [];
for (arrayEntry of myJSON) {
for (const field in arrayEntry) {
if (!fieldNamesArray.includes(field)) {
fieldNamesArray.push(field)
};
}
}


//make header with field names
let csvString = "";
for (field of fieldNamesArray) {
field = field.replaceAll('"', '""'); //any interior " needs to be replaced with ""
csvString += "\"" + field + "\","; //surround each field with quotes
}
csvString = csvString.slice(0, -1) + "\n"; //remove last comma and add new line


//SECOND PASS -- fill in table using field names/keys
for (arrayEntry of myJSON) {
for (field of fieldNamesArray) {
let csvEntry = arrayEntry[field];
if (csvEntry === undefined) { //if undefined set to empty string ""
csvEntry = "";
} else if (typeof(csvEntry) != "string") { //if its not a string make it a string
csvEntry = JSON.stringify(csvEntry);
}
csvEntry = csvEntry.replaceAll('"', '""');
csvString += "\"" + csvEntry + "\"" + ","
}
csvString = csvString.slice(0, -1) + "\n";
}


return csvString;
}
function jsonToCsv(data) {
return (
Object.keys(data[0]).join(",") +
"\n" +
data.map((d) => Object.values(d).join(",")).join("\n")
);
}

这当然不适用于嵌套的 json 数组。但是要将 json 映射到 csv,我建议首先简化嵌套的 json 数组。