Generate CSV and Download it Client Side from the Browser

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Eh, I'd much rather make the round trip.

👍︎︎ 3 👤︎︎ u/filleduchaos 📅︎︎ Jun 01 2018 🗫︎ replies
const RE_SHOULD_QUOTE = /[",\n\r]/
const RE_ALL_QUOTES = /"/g
function quoteCSV (value, force) {
    value = String(value)

    if (!force && !RE_SHOULD_QUOTE.test(value)) return value;

    value = value.replace(RE_ALL_QUOTES, '""');
    return `"${value}"`;
}

function gimmeCSV (data) {
    // Data is an array of lines, i.e. Array<Array<string>>
    return data.map(row => row.map(val => quoteCSV(val)).join(',')).join('\r\n');
}
👍︎︎ 1 👤︎︎ u/svvac 📅︎︎ Jun 01 2018 🗫︎ replies
Captions
all right so today we're gonna be doing a interesting technique which is going to allow us to generate a CSV from an object and then actually download it on the client browser without ever going to a server normally for this kind of thing you would send data or pool data from a server and the server would would serve a file to you and the browser would download it but here we're gonna generate the CSV client-side and download it okay so I've just got a page set up here it's got a button on it when you click the business a function when you click the button it fires this method called get report and it's just as button clicked so if I just run this real quick and I just go to download innovation and just open it in chrome real quick if I click the button alert button clicked ok nothing fancy here just starting up the execution of the browser so the first thing we want to do is we're going to get some data and then we want to generate a CSV that's the first thing so I had this is an async function error while computing document highlights whatever okay this is an async function because we are going to do some async await stuff in here so I have previously used JSON generator to generate a bunch of JSON so console or Const JSON URL equals this link and I've use JSON generator just generate this so we're gonna use fetch which is the browser way to get data a newer way so we're just going to do Const res equals a weight fetch fetch returns of promise I'm just gonna stretch the JSON URL now the result of fetch is not actually the data so if we were to console dot log res for example and if we go back to here and we inspect and view the console and hit refresh and then hit download you can see that the response doesn't actually give us the data we're looking for it's a stream so to get the actual data we actually have to say constant a Sun equals a weight JSON now I think that as I read that Jason I think this is stupid but whatever it's how it is so console dot log Jason go back to the browser refresh and hit download and there's our object with our bunch of entries from Jason's this is all good this is all just random data that's whatever okay cool so let's form a CSV out of this so I want to make this a nice function that you can reuse over and over again so I want to make a function that's like constant CSV data equals object to CSV CSV and we're going to pass it the JSON okay that's sort of what we're looking for now I don't actually want to see everything I just want to CSV some stuff so let's actually map this to just some data that we want so let's just say Const data equals JSON map and let's just say row and then we'll return and actually we're going to do an implicit return so I'm going to wrap this in parentheses and we're going to return this object now instead of having to write return so age is Rho dot age and then email is Rho dot email and then first name Rho dot name dot first and last name row name dot last okay and so we're gonna say Const console dot log data and let's pass that into this function I'm also going to comment this out because we're gonna give this a test to make sure our map is correct I'm gonna get rid of that because we're not really gonna use this okay cool so let's refresh the browser here and hit the button and there we go we have a nice simplified object so this is this is the array that we want to turn into a CSV okay so let's run this function which we haven't written yet so let's go write that function really come in it doesn't do that whatever still getting used to vs code I just switched like two days ago all right so let's write this function object to CSV here const object csv equals a function and it's gonna take data so let's talk about what we want this function to do so we need to get the headers for a csv then we need to loop over the rows and then we need to form escaped comma separated separated values that's sort of what we need to do here so let's start with getting the headers so let's just so the headers of a json object will be the keys of one of them so let's use the keys from the very first object as the headers we could optionally pass in headers if we wanted to but i'm not programming that now so we're gonna say whatever the headers are of the very first object those are the headers that we're gonna need to that we're gonna want so i'm just like comes headers equals object keys that's how you get the keys of the object and data 0 so the first element in the data okay and we're also assuming here that this is an array that's being passed in because in a csv it's all about the rows okay now i want to before we sort of move on past this what's our final output going to be it needs to be a bunch of CSV rows okay and a bunch of a bunch of new line separated rows so I'm gonna start off an object that we're going to trying to form and I call this Const CSV rows and that's an empty array and we're going to be pushing things to this that we will eventually turn into the file so headers is the first row so I will say CSV res dot push and we're going to push the headers now again it's a CSV and so things need to be comma separated so it's headers not join by a comma okay that's the first thing so then let's stop here and take a look at what this is before we move too much further so I'm just gonna say console dot log headers just let's just take a look at this let's go to the browser refresh and hit download and there you go this is an object I know I don't want to look at headers I want to look at CSV rose again CSV Rose is actually actually the thing we want to be looking at so there we go CSV Rose is an array of rows right now which is fine but the first row is correctly comma separated okay so that's the right start that's what a CSV looks like to start alright so now we've got our headers so the next thing we do is loop over the rows and add those in to okay so I can say data about for each row I'm actually gonna I'm going to use a for of loop instead because there's no reason there's not a good reason to use for each much at all anymore actually I know it for of is widely available so we're gonna say for Const row of data so now we're going to loop over because if what you can see here is that this is not creating an anonymous function which takes a little bit of effort on the browser's part we no longer need to do that for each does create a new function this doesn't and we get the same result okay so let's go ahead and let's see what are we gonna do here so we need to add the data to our object now it is very important for a CSV that the that the order of our keys in each row is the same so we need absolutely four items every time and they match exactly age email first name last name in order for this CSV to work it has to match this on every row okay so what we need to do then is we need to map over the headers because we need to make sure that we're in the same order with those four things every single time okay so we're going to say headers that map so we're gonna map over the headers now and given the header we're gonna do a bunch of stuff so now we're mapping over the headers and so we're at the first header which in this case is age and so what we need to do is add that to our what we would want to return Rouen it's in this case it's rohwedder okay so rohwedder is our first row header is aged so it's gonna say row age for the first one okay and then that's going to return that back and so for our map here try to figure how to best explain this let's let's take a look at what this looks like so I'm just gonna say Const values equals this map and then when it's just console dot log values and so this should be the four values for each row so let's just take a look at that for a second okay so for each row you can see that we have these values and that's great and that's what we need and so we need to join them by comma just like we did with the headers okay so do we have values so if we do values dot join by comma three fresh then take a look that's what we're looking for that's the rest of the rows now we have to be a little careful here because it's possible that these names or something else of this text could potentially have a comma in it and if it does we've screwed up our CSV so we need to protect that from happening so we really need to escape any quotes well in a CSV you're allowed to quote each of the sections so we need to wrap each of the values in a in a quote situation first so instead of returning row header we're gonna return a template literal and we're gonna wrap this in like that and then we're just going to wrap this whole thing in quotes so that it's it's wrapped and so if we take a look at that again you can see now everything is wrapped but if we have a quote inside of here which is possible that also screws it up so before we actually wrap it in quotes we actually need this to escape quotes so I'm actually gonna say like Khan's escaped equals and we'll just we're going to use regex here so we're gonna say that dot replace now the regex that we're going to use here we're gonna replace quote with mu G so many quotes with backslash backslash quote so this is gonna so this is the escape value now we want to replace quote with if we ever find any but this allows us to use the slash so that's our regex to replace this value and I didn't mean to get rid of that so rohwedder dot replace this so this is an escaped value and then we're gonna have our escaped value wrapped in quotes okay I'm gonna take a look at that row header that replace is not a function row header should be row header row header is not always a string because the first one that we find is a number and you cannot use that replace on a number okay so what we need to do is we need to first coerce this value to a string so that we can use it on dot replace so the easiest way to coerce something to a string is to wrap it in parenthesis and add a single quote plus plus or sorry single quote plus in front so this coerces it to a string that allows us to always use the replace function which replaces quotes with backslash quote okay and then we pass that in that way so let's refresh and hit download and there you go the same result but if any of these had a quote it would be escaped and it's all wrapped in in quotations now so all the commas are safe okay and so we would just want to we actually want to push each of these each of these things onto it well yeah this is what we want to put it onto cs0 so CSV rows that push each of each of these things and so now after that we can sort of say console that log CSV rows refresh that okay so here's each of our rows our first one is our our headers and then our next ones are all quote and properly quoted and escaped values so these are the right array but we can't have an array when we print a CSV so what we need to do now is actually join everything by a newline so we want to return CSV rows dot join by backslash n and now if we look at the return of CSV data down here CSV data you'll find that we've got a really nice there we go this is a proper CSV it's a new line separated it's got escaped it's got escaped quotations if it's needed it's got escaped commas because it's separated so there we go we got a good CSV we have a nice object of CSV function to use now we've got our CSV so the next step is we need to download it so we're gonna make a function that doesn't exist yet called download and we're gonna pass it the CSV data okay so let's make the download function so const download equals a function now what's this download function gonna do so in order to do this trick we need to make a blob it's called so new blob is how you download stuff and that's gonna take so we pass this data right so we pass this data and it's a new blob the first parameter their blob takes is the data the second parameter is the type of thing it is and that's in an object so type is text slash CSV okay so we made it blob so just say constant blob equals now that we have a blob we actually need to send that blob to the browser okay now the browser has a way to create an object from URL and so we're going to say Const URL equals window dot URL that create object URL and that takes the blob so this is the this is sort of the crux of the trick here is that this window dot URL function in browsers allows you to create a URL version of an object it's a URL version of our CSV and so then we're just going to create an a tag and click it so Const a equals document dot create element a and then we're going to say a dot set attribute hidden we don't want to show up anywhere so we're just gonna set the attribute hidden then a that set attribute href to that URL that we just made and then a dot set attribute download so setting the attribute download allows it to be downloaded to a file name we're just going to call it download that CSV and then we're gonna append it to the document so document body dot append append child and the a tag and then we're gonna click it and then after we're done to click we're gonna remove it so document that body don't remove child a and that will now download it so let's take a look up over here refresh and hit download and there we go there's our CSV that downloaded let's open it up in Excel and there you go we've opened it in Excel and there we go there's our CSV and as you can see I was able to download a file directly from the browser using this method after creating it from the CSV so there you go that's how you generate a CSV on the client side from an object in this cancer array and cause it download on the client
Info
Channel: optikalefx
Views: 40,586
Rating: 4.9832168 out of 5
Keywords: csv, json, generate, browser, chrome, firefox, blob, file, object, javascript, js, coding, programming, learn, client
Id: eicLNabvZN8
Channel Id: undefined
Length: 17min 13sec (1033 seconds)
Published: Thu May 31 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.