How to export nested json object to csv in javascript? [duplicate] - javascript

I have a link that opens up JSON data in the browser, but unfortunately I have no clue how to read it. Is there a way to convert this data using JavaScript in CSV format and save it in JavaScript file?
The data looks like:
{
"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"
}]
}
The closest I could find was: Convert JSON format to CSV format for MS Excel
But it downloads in a CSV file, I store it in a variable, the whole converted data.
Also would like to know how to change escape characters: '\u2019' back to normal.
I tried this code:
<!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>
But it doesn't seem to work. Can someone please help?

A more elegant way to convert json to csv is to use the map function without any framework:
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)
Output:
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"
Update ES6 (2016)
Use this less dense syntax and also JSON.stringify to add quotes to strings while keeping numbers unquoted:
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)

Ok I finally got this code working:
<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>
Thanks alot for all the support to all the contributors.
Praney

Very nice solution by praneybehl, but if someone wants to save the data as a csv file and using a blob method then they can refer this:
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);
}

If anyone wanted to download it as well.
Here is an awesome little function that will convert an array of JSON objects to csv, then download it.
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);
};
Then call it like this:
this.downloadCSVFromJson(`myCustomName.csv`, this.state.csvArrayOfJson)

I just wanted to add some code here for people in the future since I was trying to export JSON to a CSV document and download it.
I use $.getJSON to pull json data from an external page, but if you have a basic array, you can just use that.
This uses Christian Landgren's code to create the csv data.
$(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);
});
});
Edit: It's worth noting that JSON.stringify will escape quotes in quotes by adding \". If you view the CSV in excel, it doesn't like that as an escape character.
You can add .replace(/\\"/g, '""') to the end of JSON.stringify(row[fieldName], replacer) to display this properly in excel (this will replace \" with "" which is what excel prefers).
Full Line: let csv = items.map(row => header.map(fieldName => (JSON.stringify(row[fieldName], replacer).replace(/\\"/g, '""'))).join(','));

There are multiple options available to reuse the existing powerful libraries that are standards based.
If you happen to use D3 in your project, then you can simply invoke:
d3.csv.format or d3.csv.formatRows functions to convert an array of objects into csv string.
d3.csv.formatRows gives you greater control over which properties are converted to csv.
Please refer to d3.csv.format and d3.csv.formatRows wiki pages.
There are other libraries available too like jquery-csv, PapaParse. Papa Parse has no dependencies - not even jQuery.
For jquery based plugins, please check this.

Try these Examples
Example 1:
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;
}
Example2 :
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;
}
You can even download the csv file using the following code :
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();
}

<!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>

An elegant way to convert object array to 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');
};
To download it as file:
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);
};

I found the accepted answer extremely useful but needed my solution to work with unstructured json objects.
I have modified the accepted answer to work with an array of unstructured objects of varying size and schema.
Input:
[
{
"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"
]
}
]
Output:
"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>

Sometimes objects have different lengths. So I ran into the same problem as Kyle Pennell. But instead of sorting the array we simply traverse over it and pick the longest. Time complexity is reduced to O(n), compared to O(n log(n)) when sorting first.
I started with the code from Christian Landgren's updated ES6 (2016) version.
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');
}

An adaption from praneybehl answer to work with nested objects and tab separator
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
}

Here is the latest answer using a well optimized and nice csv plugin:
(The code may not work on stackoverflow here but will work in your project as i have tested it myself)
Using jquery and jquery.csv library (Very well optimized and perfectly escapes everything)
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>

Heres a way to do it for dynamically deep objects in a object oriented way for the newer js versions. you might have to change the seperatortype after region.
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;
}

Personally I would use d3-dsv library to do this. Why to 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);
}
With tree-shaking you can just import that particular function from d3-dsv library

I wanted to riff off #Christian Landgren's answer above. I was confused why my CSV file only had 3 columns/headers. This was because the first element in my json only had 3 keys. So you need to be careful with the const header = Object.keys(json[0]) line. It's assuming that the first element in the array is representative. I had messy JSON that with some objects having more or less.
So I added an array.sort to this which will order the JSON by number of keys. So that way your CSV file will have the max number of columns.
This is also a function that you can use in your code. Just feed it JSON!
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)
}

Here's my simple version of converting an array of objects ito CSV (assuming those objects all share the same attributes):
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')

Write 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;
}

Funny nothing complete nor working here (IE nor node.js). Answer on similar question, a bit structured JSON (suppose no need to copy it again), also demo snippet included.
JSON To CSV conversion (JavaScript) : How to properly format CSV conversion
Hope not only single type convertor, also on my Github (mentioned in profile) is similar used to analyze unknow JSON structure.
I am author of code in this answer and all code on my Github (except some projects started as fork/+translation).

A simple function to convert nested JS objects (without arrays) to csv format in an inline and formatted style ..
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))

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);
}
The following function has been written with help from the answers above.

Here is what I have done. I've used this function when I have an array of objects in JSON format. First of all, there are a lot of flavors of csv. So I've approached it this way, and my files seem to open up ok in spreadsheet editors. Adapted from RFC 4180 and MIME standards/wikipedia:
Each record should contain the same number of comma-separated fields.
Any field may be quoted (with double quotes).
If double-quotes are used to enclose fields, then a double-quote in a field must be represented by two double-quote characters. (internal " is escaped with "")
some type of carriage return/line feed
I know there are more complicated faster, and more elegant ways, but here is a readable and hopefully understandable function that will take in JSON and return a csv with those constraints.
Here is a rundown of the function, again not optimized for performance as it uses 2 passes.
Run through every array entry and get and collect all the key names on the first pass.
Make a header based on the key names
On a second pass, go through the entries and write the values using the keys.
If its undefined, don't write "undefined", instead write "".
If its not a string, stringify it. (After all its valid JSON, so just use JSON.stringify.) This will take care of objects, arrays, null, boolean, etc.
If it is a string do nothing of course.
Now replace any interior " with "".
Now wrap each entry in an outer pair of "" separated by commas with no spaces.
Don't forget the new line \n between lines.
The result is a string that should open in most spreadsheets easily.
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;
}

Here is my solution, as no other one here has support for dynamic columns (they use the first row to determine the columns):
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")
}
You can pass a replacer function if you need to convert certain column' value.

function jsonToCsv(data) {
return (
Object.keys(data[0]).join(",") +
"\n" +
data.map((d) => Object.values(d).join(",")).join("\n")
);
}
This is of course not for nested json array. But to map json into csv, I would recommend first to simplify nested json array.

Typescript simple method taking into account:
✅ Keys/Values can have " inside it
✅ Keys/Values can have , inside it
✅ Values can have array or objects inside it
Playground Link
const arrayToCSV = (myJSON: any[]) => {
const escapeValue = (value: any) => {
const content = (() => {
if (!value) {
return "";
}
if (typeof value === "object") {
return JSON.stringify(value).replace(/"/g, '""')
}
return value.toString();
})()
return `"${content}"`
};
const fieldNamesArray: string[] = [...new Set(
myJSON.reduce((acc, arrayEntry) => {
return [...acc, ...Object.keys(arrayEntry)];
}, [])
)] as any[];
const header = fieldNamesArray.map(escapeValue).join(',');
const rows = myJSON.map(arrayEntry => {
return fieldNamesArray.map((field) => {
return escapeValue(arrayEntry[field]);
}).join(',');
}).join('\n');
return `${header}\n${rows}`;
};
Hope that helps :D

Related

Javascript CSV headers text formatting

Following with the help of various solutions around, I have a javascript CSV function that converts the JSON data into CSV format.
This is how the code goes:
function convertToCSV(headers, objArray) {
var header_line = "";
for (const [key, value] of Object.entries(headers)) {
header_line += [key, value] + "\n";
}
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";
}
var csv = header_line + "\n" + str;
return csv;
}
function exportCSVFile(headers, columns, items, fileTitle) {
if (columns) {
items.unshift(columns);
}
var jsonObject = JSON.stringify(items);
var csv = convertToCSV(headers, jsonObject);
var exportedFilenmae = fileTitle + ".csv" || "export.csv";
var blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, exportedFilenmae);
} else {
var link = document.createElement("a");
if (link.download !== undefined) {
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", exportedFilenmae);
link.style.visibility = "hidden";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
export default function generateCSV(dataarray, filename) {
var columns = {
"Count": "Count",
Coeff: "Coeff",
};
var headers = {
"# Some random long sheet title": "",
"# User Id": "37467yteyuw8473872938100j",
"# Created on": new Date() + "\t\t",
};
let json_data= [
{
"Count": "55",
Coeff: "56",
},
{
"Count": "55",
Coeff: "56",
},
{
"Count": "55",
Coeff: "56",
},
];
var formatItems = [];
json_data.forEach((item) => {
formatItems.push({
"Count": item["Count"],
Coeff: item["Coeff"]
});
});
var fileTitle = "my_data";
exportCSVFile(headers, columns, itemsFormatted, fileTitle);
}
The functions work completely fine. The problematic cases stuck are:
The header text, # Created On, is getting hidden as the file is downloaded and then opened. On downloading the file, this column needs to be manually dragged so that it's visible completely.
If a comma (,) is included in the title key like:
var headers = {
"# Some random long, sheet title": "",
"# User Id": "37467yteyuw8473872938100j",
"# Created on": new Date() + "\t\t",
};
It breaks the title into 2 cols even after is a single string.
Any help for the same is appreciated. Thanks in advance :)
Although you declare the header_line variable (string) with double quotes it is actually just a string. For csv to ignore a coma it must have double quotes around it (within the larger string).
If you console.log() the csv as its generated you should see it currently is something like....
...., # User Id:, 37467yteyuw8473872938100j,
you could try adding escaped quotes to the line
header_line += [key, value] + "\n"; so it becomes header_line += '\"' + [key, value] +'\"' + "\n";
This might not be exactly correct, but you should be able to see from the console and the raw csv file (open the csv file in text editor). In the csv file it should look like this (I think)
"# User Id:, 37467yteyuw8473872938100j",
Disclaimer: I couldn't get your code to run to test it properly.
Edit: The current csv output
# Some random long sheet title,
# User Id,37467yteyuw8473872938100j <--- the Comma is Separating the Values (CSV)
# Created on,Wed Jul 29 2020 00:16:41 GMT-0400 (Eastern Daylight Time)
Count,Coeff
55,56
55,56
55,56

Convert .xlsx file with merged cells to JSON with SheetJS

I'm trying to read a .xlsx file with SheetJS and convert it into JSON. I'm able to read and convert a simple (without merged cells) .xlsx file to JSON, but I'm not getting it right with merged cells.
The problem is that I have a .xlsx file with products in different languages.
I tried searching for a solution on different websites and the github repository of SheetJS https://github.com/sheetjs/js-xlsx/#json with mediocre success. Mostly addressing how to write merged cells.
function handleFile(e) {
var files = e.target.files, f = files[0];
var reader = new FileReader();
reader.onload = function(e) {
var data = new Uint8Array(e.target.result);
var workbook = XLSX.read(data, {type: 'array'});
let result = '';
let sheet_name_list = workbook.SheetNames;
// iterate through sheets
sheet_name_list.forEach(function (y) {
workbook.Sheets[y]['!merges'].map(r => {
let startChar = XLSX.utils.encode_range(r).split(':')[0].replace(/[^a-zA-Z]+/g, '');
let endChar = XLSX.utils.encode_range(r).split(':')[1].replace(/[^a-zA-Z]+/g, '');
let number = XLSX.utils.encode_range(r).split(':')[0].match(/[+-]?\d+(?:\.\d+)?/g)[0];
for (let i = numbersFromLetters(startChar); i < numbersFromLetters(endChar); i++) {
workbook.Sheets[y][numbersToLetters(i + 1) + number] = {t:'s'};
workbook.Sheets[y][numbersToLetters(i + 1) + number].v = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
workbook.Sheets[y][numbersToLetters(i + 1) + number].h = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
workbook.Sheets[y][numbersToLetters(i + 1) + number].w = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
workbook.Sheets[y][numbersToLetters(i + 1) + number].r = '<t>' + workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v + '</t>';
}
});
// Convert the cell value to JSON
//let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y]);
//let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {range: 1});
let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {header: 1});
//let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {skipHeader: true});
//let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {header: 1, range: 1});
if (roa.length > 0) result = roa;
});
console.log(result);
};
reader.readAsArrayBuffer(f);
}
For better perception this is an example excel file with merged language cell:
and I want this result:
[
{ "languages":
[
{
"language": "US",
"name": "blue pants"
},
{
"language": "DE",
"name": "blaue Hose"
},
{
"language": "ES",
"name": "pantalones azules"
}
],
"price": 29.9,
"category": "pants"
},
...
]
Depending on which part of the commented code I execute I get different results which look kind of similar to the code that I want to achieve or at least can further work with. But at each outcome I need to fiddle around further which appears to me that there might be a better solution.
const workbook = XLSX.readFile(fileName, readOptions);
const sheetNames = workbook.SheetNames;
for (let worksheet of sheetNames) {
if (workbook.Sheets[worksheet]['!merges'])
workbook.Sheets[worksheet]['!merges'].map((merge) => {
const value = XLSX.utils.encode_range(merge).split(':')[0];
for (let col = merge.s.c; col <= merge.e.c; col++)
for (let row = merge.s.r; row <= merge.e.r; row++)
workbook.Sheets[worksheet][String.fromCharCode(65 + col) + (row + 1)] = workbook.Sheets[worksheet][value];
});

Javascript: How to convert an JSON arrays in array into an CSV file?

I'm struggeling with my JSON file here...
This is what I get from my processing .php-file as a response:
{"1":{"Nachname":"Stromberg","Vorname":"Bernd",
"Benutzername":"strombergbernd12","Password":"Xrz5Bv6A"},
"2":{"Nachname":"Heisterkamp","Vorname":"Ernie",
"Benutzername":"heisterkampernie12","Password":"aOq24EpF"}}
Now, I want to build from this JSON array a csv file. In the first row the csv file should mention the headers Nachname, Vorname, Benutzername and Password and then list in the following rows the rest of the data.
I cant handle that, can you help me?
once you have your json as text you parse it:
var json = JSON.parse(jsonAsText);
transform it to an array:
json = Object.values(json);
init your result:
var csv = "";
keep header keys somewhere:
var keys = (json[0] && Object.keys(json[0])) || [];
write header row
csv += keys.join(',') + '\n';
iterate and put everything in csv
for (var line of json) {
csv += keys.map(key => line[key]).join(',') + '\n';
}
Your csv content should be ready
var json = {
"1": {
"Nachname": "Stromberg",
"Vorname": "Bernd",
"Benutzername": "strombergbernd12",
"Password": "Xrz5Bv6A"
},
"2": {
"Nachname": "Heisterkamp",
"Vorname": "Ernie",
"Benutzername": "heisterkampernie12",
"Password": "aOq24EpF"
}
}
function toCSV(json) {
json = Object.values(json);
var csv = "";
var keys = (json[0] && Object.keys(json[0])) || [];
csv += keys.join(',') + '\n';
for (var line of json) {
csv += keys.map(key => line[key]).join(',') + '\n';
}
return csv;
}
console.log(toCSV(json));
Note: If you can, switch your json to Array syntax:
[
{
"Nachname":"Stromberg",
"Vorname":"Bernd",
"Benutzername":"strombergbernd12",
"Password":"Xrz5Bv6A"
},
{
"Nachname":"Heisterkamp",
"Vorname":"Ernie",
"Benutzername":"heisterkampernie12",
"Password":"aOq24EpF"
}
]
and then remove this line:
json = Object.values(json);
You could use: Object.keys() and Object.values().
Something like this:
(function() {
var data = {
"1": {
"Nachname": "Stromberg",
"Vorname": "Bernd",
"Benutzername": "strombergbernd12",
"Password": "Xrz5Bv6A"
},
"2": {
"Nachname": "Heisterkamp",
"Vorname": "Ernie",
"Benutzername": "heisterkampernie12",
"Password": "aOq24EpF"
}
};
var csv = Object.keys(data[Object.keys(data)[0]]).join(","); // Header columns.
csv += "\n";
for (var item in data) {
csv += Object.values(data[item]).join(",");
csv += "\n";
}
console.log(csv);
}());
.as-console-wrapper {
position: relative;
top: 0;
}
The result will be:

Export Excel (.xlsx extension) file with includes responsive table data in SAPUI5

In my current job, i had a requirement in SAPUI5 to download Table/list/etc control's data into .xlsx excel file extension (not .csv extension).
Please guide me with some good examples or concept.
Thanking you in advance.
I have found one solution to download .xlsx file in sapui5. Please feel free to provide feedback on my work.
First get the data from table/list controls and use below code to generate .xlsx file in sapui5.
some_etc_controller.js
var aExcelData = [
{
"ProductId": "1239102",
"Name": "Power Projector 4713",
"Category": "Projector",
"SupplierName": "Titanium",
"Description": "A very powerful projector with special features for Internet usability, USB",
"WeightMeasure": 1467,
"WeightUnit": "g",
"Price": 856.49,
"CurrencyCode": "EUR",
"Status": "Available",
"Quantity": 3,
"UoM": "PC",
"Width": 51,
"Depth": 42,
"Height": 18,
"DimUnit": "cm"
},
{
"ProductId": "2212-121-828",
"Name": "Gladiator MX",
"Category": "Graphics Card",
"SupplierName": "Technocom",
"Description": "Gladiator MX: DDR2 RoHS 128MB Supporting 512MB Clock rate: 350 MHz Memory Clock: 533 MHz, Bus Type: PCI-Express, Memory Type: DDR2 Memory Bus: 32-bit Highlighted Features: DVI Out, TV Out , HDTV",
"WeightMeasure": 321,
"WeightUnit": "g",
"Price": 81.7,
"CurrencyCode": "EUR",
"Status": "Discontinued",
"Quantity": 10,
"UoM": "PC",
"Width": 34,
"Depth": 14,
"Height": 2,
"DimUnit": "cm",
}
];
// Consider above array of object as a dummy data
this.fnJSONToXLSXConvertor(aExcelData, <<put_here_xlsx_file_name>>);
}
fnJSONToXLSXConvertor : function(JSONData, ReportTitle) {
var aData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
if (aData.length) {
var aFinalXlsxData,
aXlsxHeaderData;
// Array variable to store header data in XLSX file
aXlsxHeaderData = [];
aFinalXlsxData = [];
// Below loop to extract header data
for ( var iIndex in aData[0]) {
switch (iIndex) {
case "ProductId":
aXlsxHeaderData.push(this.getText("ProductId"));
break;
case "Name":
aXlsxHeaderData.push(this.getText("Name"));
break;
...etc
<<specify/push your column header from i18n>>
}
// Adding column header data in final XLSX data
aFinalXlsxData.push(aXlsxHeaderData);
// Below loop to extract data
for (var i = 0; i < aData.length; i++) {
// Array variable to store content data in XLSX file
var aXlsxContentData = [];
for ( var iIndex in aData[i]) {
switch (iIndex) {
case "ProductId":
case "Name":
case "Status":
...
<<specify your column name, to extract only particular column data>>
aXlsxContentData.push(aData[i][iIndex]);
break;
}
}
// Adding content data in final XLSX data
aFinalXlsxData.push(aXlsxContentData);
}
var Workbook = function Workbook() {
if(!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
var wb = Workbook();
wb.SheetNames.push(ReportTitle);
var sheet_from_array_of_arrays = function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }};
for(var R = 0; R != data.length; ++R) {
for(var C = 0; C != data[R].length; ++C) {
if(range.s.r > R) range.s.r = R;
if(range.s.c > C) range.s.c = C;
if(range.e.r < R) range.e.r = R;
if(range.e.c < C) range.e.c = C;
var cell = {v: data[R][C] };
if(cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({c:C,r:R});
if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.t = 'n'; cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
}
else cell.t = 's';
ws[cell_ref] = cell;
}
}
if(range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
var ws = sheet_from_array_of_arrays(aFinalXlsxData);
// Setting up Excel column width
ws['!cols'] = [
{wch:14},
{wch:12}
...
<<specify no. of character in cell to set column width if any>>
];
wb.Sheets[ReportTitle] = ws; // wb.Sheets[ReportTitle] -> To set sheet name
var wbout = XLSX.write(wb, {bookType:'xlsx', bookSST:true, type: 'binary'});
var s2ab = function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
};
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), ReportTitle + ".xlsx");
} else {
MessageBox.error(
"No data..!",
{
styleClass: bCompact? "sapUiSizeCompact" : ""
}
);
}
}
Download and put below specified javascript library file into your sapui5 lib folder.
Blob.js: https://github.com/eligrey/Blob.js/blob/master/Blob.js
xlsx.js:https://github.com/SheetJS/js-xlsx/blob/master/xlsx.js
A better alternative is available now. I think this example can help you.
sap.ui.export.Spreadsheet creates a new spreadsheet export object. Use this object to build and download a spreadsheet file in Office Open XML Spreadsheet format from tabular data. This functionality is normally used together with UI5 tables.

Export JSON to Excel using EmberJS

I have a JSON object being returned by the service. I want to export that to a xls or excel file on the click of a button.
When I make a get service call the server return with this:
"objects": [
{
"amount": 1000,
"date": "2015-12-08",
"description": "sdadas",
"from_id": "Prateek",
"id": 1,
"to_id": "Prateek,Srabani,Jimmy"
},
{
"amount": 132,
"date": "2015-12-08",
"description": "sdadas",
"from_id": "Prateek",
"id": 3,
"to_id": "Jimmy"
},
{
"amount": 3000,
"date": "2015-12-08",
"description": "asdsasa",
"from_id": "Srabani",
"id": 4,
"to_id": "Prateek,Srabani,Jimmy"
},
{
"amount": 2000,
"date": "2015-12-08",
"description": "asdsasa",
"from_id": "Jimmy",
"id": 5,
"to_id": "Prateek,Srabani,Jimmy"
},
{
"amount": 100,
"date": "2015-12-08",
"description": "adas",
"from_id": "Srabani",
"id": 6,
"to_id": "Prateek"
}
]
Apart from this there is no filtering done whatsoever in the front end. I have to export this array of objects to excel with the keys being label of the columns and the values being corresponding rows.
Can someone help me with the handlebars as well as controller code ?
This is the code to export a JSON object to a Excel supported format. Works well.
$(document).ready(function(){
$('button').click(function(){
var data = $('#txt').val();
if(data == '')
return;
JSONToCSVConvertor(data, "Vehicle Report", true);
});
});
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 = '';
//Set Report title in first row or line
CSV += ReportTitle + '\r\n\n';
//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;
}
//Generate a file name
var fileName = "MyReport_";
//this will remove the blank-spaces from the title and replace it with an underscore
fileName += ReportTitle.replace(/ /g,"_");
//Initialize file format you want csv or xls
var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
// Now the little tricky part.
// you can use either>> window.open(uri);
// but this will not work in some browsers
// or you will not get the correct file extension
//this trick will generate a temp <a /> tag
var link = document.createElement("a");
link.href = uri;
//set the visibility hidden so it will not effect on your web-layout
link.style = "visibility:hidden";
link.download = fileName + ".csv";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

Categories