Here is a simple way to convert your JSON to CSV, if your using FF or Chrome that supports data URI’s then this function convert your data and tell your browser to download the results as a text file. If you are using Internet Explorer (“IE”), a new window will popup so you can copy & paste or to use File -> Save As to download the results as text. The JSON parsing is done with json.org’s open source JSON parser, which you can download here.
Why can’t IE download the file to CSV like FireFox? The long answer is due to IE’s data URI support that was missing until IE8, and when implemented in IE8+, the security restrictions are set to prevent solutions like this from working! To force a download of your JSON data in CSV via IE, you’ll need to use an alternative technique like Server Side Parsing.
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]) {
if(line != '') line += ','
line += array[i][index];
}
str += line + '\r\n';
}
if (navigator.appName != 'Microsoft Internet Explorer')
{
window.open('data:text/csv;charset=utf-8,' + escape(str));
}
else
{
var popup = window.open('','csv','');
popup.document.body.innerHTML = '<pre>' + str + '</pre>';
}
}
#1 by Thilak on September 26, 2013 - 5:18 am
Am being tried to using this script…. it work fine in firefox where it convert 5 MB data to CSV but in chrome it not. If i have a data less 600KB it’s get’s converted or else it throws a error “Aw-Snap” error
#2 by Zach on September 26, 2013 - 10:08 am
This is a good read if you are having issues with large arrays in JavaScript on Chrome or Firefox: http://stackoverflow.com/questions/4833480/have-i-reached-the-limits-of-the-size-of-objects-javascript-in-my-browser-can-ha
#3 by test on August 13, 2013 - 8:42 am
I am trying with below in makeCSV() function by following http://jsfiddle.net/5KRf6/3/
$(‘#downloadbtn’).bind(‘click’, function(e){
var str = “Name, Price\nApple, 2\nOrange, 3″;
var uriContent = ‘data:text/csv;charset=utf-8,’ + str;
var myWindow = window.open(uriContent);
myWindow.focus();
});
Created a button in html.
All I get after clicking the btn is ” data:text/csv;charset=utf-8,Name, PriceApple, 2Orange, 3 ” in another URL. Its not even asking me to open or save .
#4 by Zach on August 13, 2013 - 9:00 am
This will not work in every browser, some browsers consider this code unsafe so it’s not a universal solution. What browser are you using?
#5 by rangareddy on October 26, 2012 - 12:11 pm
I have used this sample but not able to run IE9 please give me an alternative for a save prompt window. and the extension is not coming properly . how to give proper name Please let meknow.
#6 by Sam on June 29, 2012 - 1:47 am
my json is a little bit more complex one.. is it possible to convert this to csv ??
[
{
“_index”: “test”,
“_type”: “news”,
“_source”: {
“partnerName”: “propertyFile 9”,
“relatedSources”: “null”,
“entityCount”: “50”,
“Categories”: {
“Types”: {
“Events”:
[
{
“count”: 1,
“term”: “Time”,
“Time”:
[
{
“term”: “Dec 9”,
“Dec_9”:
[
{
“count”: 1,
“term”: “2012”
}
]
}
]
},
{
“count”: 4,
“term”: “News”,
“News”: [
{
“term”: “Germany”,
“Germany”: [
{
“count”: 1,
“term”: “Election”
}
],
“currency”: “Euro (EUR)”
},
{
“term”: “Egypt”,
“Egypt”: [
{
“count”: 1,
“term”: “Revolution”
}
]
},
{
“term”: “Japan”,
“Japan”: [
{
“count”: 1,
“term”: “Earthquake”
}
],
“currency”: “Yen (JPY)”
}
]
},
{“count”: 5,
“term”: “Persons”,
“Persons”: [
{
“count”: 2,
“term”: “Obama”
},
{
“count”: 1,
“term”: “David Beckham”
}
]
}
]}},
“Title”: “Pearce Snubs Beckham”,
“ParentUrl”: “http://feeds.nytimes.com/nyt/rss/Olympics”
},
“_index”: “test”,
“_type”: “news”,
“_source”: {
“partnerName”: “propertyFile 9”,
“relatedSources”: “null”,
“entityCount”: “50”,
“Categories”: {
“Types”: {
“Facets”:
[
{
“count”: 1,
“term”: “Time”,
“Time”:
[
{
“term”: “Dec 5”,
“Dec_5”:
[
{
“count”: 1,
“term”: “Birthday”
}
]
}
]
},
{
“count”: 4,
“term”: “news”,
“news”: [
{
“term”: “Italy”,
“Italy”: [
{
“count”: 1,
“term”: “Euro 2012 Final”
}
]
}
]
},
{“count”: 5,
“term”: “Persons”,
“Persons”: [
{
“count”: 2,
“term”: “Lebron James”
}
]
}
]}},
“Title”: “Heats National Champions”,
“ParentUrl”: “http://feeds.nytimes.com/nyt/rss/Americas”
}
}]
#7 by Venkat on February 20, 2012 - 1:44 pm
Hi Matthew,
Did you find a solution for chrome on windows ? I am facing the same issue Iits becoming hard to explain to client.
Thanks
#8 by matthew laver on February 16, 2012 - 4:04 am
Finding it really frustrating that Chrome on Mac nicely adds a ‘.csv’ extension whilst chrome on windows does not. It’s a pain having to tell client they have to add a file extension!
Any answers?
#9 by Justin Williams on January 18, 2012 - 10:07 pm
Works perfectly. Thanks very much for taking the time to share this.
#10 by Phil R on January 9, 2012 - 12:09 am
@Ryan Jacobs
I’m a while late but I figured out how to get this in working chrome.
window.open(‘data:text/csv;charset=utf-8;base64,’ + $.base64Encode(output));
e.g. base64 encode it.
#11 by Zach on January 11, 2012 - 4:30 pm
Thanks for the info Phil, this will probably help a few others out…
#12 by Hello on December 20, 2011 - 7:48 am
Hi Zach,
Thanks for this script. I’m having a hard time figuring out how to execute this on a file. I’m relatively new to coding and am not sure exactly what I’m supposed to do after opening up my json file in FireFox. Any help or guidance would be much appreciated.
Thanks,
Max
#13 by jermbo on July 25, 2011 - 10:43 am
Ok. Thank you. I will figure something out. This was still super helpful!
#14 by jermbo on July 25, 2011 - 10:08 am
Yeah I am pretty sure it is.. because when I open the file all the information that I put in there is there. So based of that, I think it is downloading all the way.
#15 by Zach on July 25, 2011 - 10:17 am
The file name is not set in the window.open, it’s set in the data uri scheme. I’ve checked the RFC and I can’t find any mention of being able to change/set the file name. I’ve tried some “suggested” hacks, but they don’t work because there is no way to change the header being returned to the browser when using a data uri. This means your going to keep getting random “something.part” file names. If you need something better, you’re going to have to return your data from the server so you can set a file name.
#16 by jermbo on July 25, 2011 - 9:12 am
Thanks for your example it was extremely helpful.
I have 2 questions. 1. Every time I download the file its always a .part file not a .csv file, what could be causing that and how do I fix it?
2. How do I name the file? Every time I down load the file it gives me a random alpha numeric string as a file name. Is there any way to place the name I want?
I did some research on window.open() and its saying you can have 4 parameters, URL, NAME, SPECS, REPLACE.
I have tried putting the name in the name parameter but with now luck. I have also tried adding to the end of escape(str) + ‘table.csv’. And I see that in the dialog box at the end of the str I am passing. But still downloads random alpha numeric number .part
Any help would be very much appreciated.
Thank you
Jermbo
#17 by Zach on July 25, 2011 - 9:22 am
The “.part” file extension is usually added to incomplete file downloads. Have you verified the file downloaded is complete ? As for the file name, I’d have to check the code since it’s been awhile since I’ve used this function…. I’ll check it in a bit and let you know about the naming, I do remember something about not being able to name the file due to the dynamic “generation” of the content, but I’ll verify.
#18 by Lisa on May 31, 2011 - 8:21 am
thanks for this.I’ve been pulling my hair out trying to find something to go from JSON to csv and this works great on FF. I’m coding for FF and IE. How do I get this to work on IE? The page is blank there but it is fine in ff.
#19 by Zach on May 31, 2011 - 4:12 pm
I just did a quick update to the function to give a “work-around” for IE. I also posted notes on why this won’t work in IE, if you must have it download the file without any user interaction (e.g. You click a link and it should prompt to download a CSV), you’ll need to use a server side solution for IE. This is pretty easy to do in PHP/ASP.NET/etc… but it’ll cost you a round-trip to the server.
#20 by pradeepkumar on April 12, 2011 - 2:23 am
zach this is the code snippet where i am using your function for downloading JSON to CSV but it was not working properly in firefox 4b11. I need your help though i am just a begineer please reply ASAP.
Object creation in JSON in JavaScript
var JSONObject = { “name” : “Amit”,
“address” : “B-123 Bangalow”,
“age” : 23,
“phone” : “011-4565763”,
“MobileNo” : 0981100092
};
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';
}
window.open("data:text/csv;charset=utf-8," + escape(str))
}
Example of object creation in JSON in JavaScript
#21 by Anthony on December 18, 2010 - 1:26 pm
The URL doesnt have the “@” character in the parameters, it has the “&” character – as it should.. I typed it in wrong.
#22 by Anthony on December 18, 2010 - 12:04 pm
Before the looping thing, I have to figure out how to get the URL’s JSON response into that function. I want to replace the ‘static’ json3.d variable with the JSON data that is retrieved by simply going that URL.
How can I pass that URL into your function: DownloadJSON2CSV(objArray) ? The URL will return well-formed JSON. I tried calling it like this:
DownloadJSON2CSV(http://myurl.com/webservice.svc/APIKEY?p=1@s=50) but nothing happens. No error displays either.
After that then I will figure out how to loop it and even create a file that I append each loop iteration to, to produce that one-time large file.
#23 by Zach on December 18, 2010 - 2:03 pm
In order to retrieve the data from a URL, you’ll need to make a AJAX JSON call. To call a site that is on a different domain, you’ll need to use AJAX JSONP call which is a bit more complicated. Once you have your data (all 156 requests), you can then export to CSV. I have a few posts on my site here about doing AJAX requests with .NET, look at the JS code in my example to see how this is done.
I really think doing this in .NET would be a lot easier, you can get Window Developer Express for FREE here http://www.microsoft.com/express/Windows/. I can probably get you 99% working solution in a few minutes, if you can give me a working URL where I can pull data…
If interested, email me directly your OS and the URL and I’ll play with it today/tomorrow when I get time… email to -> zachary dot hunter @ gmail dot com
just change dot to “.” to email me.
#24 by Ryan Jacobs on December 15, 2010 - 3:55 pm
Thanks for the response Zack. That got me one step closer but I still appear to be having some issues with Chrome. When I add the base64 it gets me past the default “about:blank” page to a page that says:
“This webpage is not available.
The webpage at data:text/csv;base64,charset=utf-8,data might be temporarily down or it may have moved permanently to a new web address.”
It shows the string of data but it won’t prompt with a download dialog like Firefox. If you have any ideas that would be much appreciated, otherwise I guess I’m relegated to Firefox for now.
Thanks.
#25 by Zach on December 17, 2010 - 2:14 am
You might try changing the file name to something with an unusual extension to see what it does (automatically opens in tab, or prompts for download) and you should also check Chrome’s settings (maybe setup to automatically open text files). If you see the data showing up in a tab, it sounds like a settings/configuration change is needed.
#26 by Anthony on December 15, 2010 - 7:43 am
RE: #2: Thanks for the reply Zach! Regarding the loop, I will give that a shot. Not being a programmer by trade I would be guessing that its a “for” loop? I have seen those in VBA. But then how to incorporate the number into the URL string… I enjoy learning this stuff so it should be fun. I assume that I will have to call “DownloadJSON2CSV(objArray)” 156 times from the for loop but where does the URL go? It would be nice if this could be done from right inside Access (or Excel).
As far as the API thing goes, my wife is the only other person who might go near my computer and if she knew what “view source” was then I’d be shocked. Also, no need to schedule this as I would create a large CSV from these 156 pages one-time. Then I would only call page 1 as the web service seems to sort the data by reverse entry date. So all of the newest entries are on the first page or 2. I am doing the data entry so I will know if I am going past 50 entries and need to run this again but I cant control the output. (i.e. I wish they’d just allow a CSV dump of the data). They add value to the data I am entering so I have to take what I get (JSON) and try to convert it to what I know (CSV).
#27 by Zach on December 17, 2010 - 2:08 am
Your right, a for loop is exactly what you want. Since you can only pull 50 records at a time you’ll need to loop the AJAX/JSON request to download the data (fyi: that’s 156 hits to their website). A great tool to use in testing is Firebug for FireFox, look at the XHR tab and you’ll see all the requests from your browser to the server including the JSON calls. Personally, I would create a new function to do the downloading and appending, to keep things simple. Once you have all 156 requests combined, then download the file.
#28 by Ryan Jacobs on December 14, 2010 - 2:45 pm
Zack,
Any idea how to make this work for Chrome also? It works for me on Firefox (3.6) but not Chrome (8.0).
Thanks
#29 by Zach on December 15, 2010 - 12:58 am
To make it work in Chrome, you will need to change the URI format to “data:text/html;base64;charset=utf-8” (notice base64; is before charset). This is non-standard and only implemented by chrome, so if you want the best of both you’ll have to test for Chrome before building your URI.
#30 by Anthony on December 14, 2010 - 10:08 am
Hi, I am trying your solution to convert JSON to CSV and have one question with 2 parts..
1) How could I change the code in your example to retrieve the JSON from a URL, whose output is JSON. Its actually nearly 156 URLS because I have to change the page number argument (?p=1, ?p=2, … , ?p=156) since the creator of that web service only outputs 50 records from their server per page.. I’d like to get that automatically and create one large array to be converted to CSV.
2) The URL contains my “API key” so I must keep this on a local machine – does that hinder its operation? Does it have to be hosted out there somewhere?
This is ultimately going to populate a database the first time and then refresh the database each day after the initial creation by way of an update routine that checks for changes. So its going from JSON out on the web to CSV on my machine and eventually to a MS Access DB on my network.
Sorry for the long question but JSON is foreign to me like XML is. I can deal with CSV and have been importing CSV without issue for a long time. I just got to get the JSON to CSV and I am cool.
#31 by Zach on December 15, 2010 - 1:13 am
1. To change the page URLS, you’ll need to create an outer loop to iterate each page (e.g. 1, 2, 3 ,4, etc…). You’ll need to get the MAX page from somewhere so you know when to stop, I assume this will be changing.
2. Normally, if your using an API key your going to put your logic in some type of protected server code (not published and accessible to visitors). If your willing/able to post your API key into JS, remember that anybody can see it if they “view source” on your code. In general, it’s bad practice.
If your goal is to pull data from the site into CSV, you should looking into site scraping. I’ve written lots of .NET console apps to this this, they are simple to write and can easily be scheduled using Task Scheduler on your desktop/server. If you need something else, you can use PHP and a CRON job which is also very simple. You’ll find lots of articles on the web about these topics, which are both more suited to automatically pulling (scraping) data from the web into any format of your choosing.