Implement save.As() dialog for csv in JavaScript - javascript

I am trying to write a code that will convert my php array into csv and then open a download dialog (save.As()) so that the website user can download the file after clicking on an html href link.
After searching a lot of posts, I could already come up with a solution in JavaScript that enables me to convert the php array to csv and display the result on the webpage to check if this is functioning and indeed it is.
I tried hard to also get the download dialog working, but had no success so far. I was trying FileSaver.js but this one just won't work for me. I would prefer a pure JavaScript solution that would work for IE, Safari and Firefox without additional libraries.
Here is my script so far to convert json object to csv and to display result on screen (this is mostly based on another script found at SO, but I cannot find the source again - if someone knows, I would be happy to include a link here):
<script type="text/javascript">
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;
}
function download_csv_function() {
// Read in JSON data and transform to CSV
$(document).ready(function () {
// Read in json data
var items = <?php echo $jsonout; ?>;
// Convert JSON object into JSON string
var jsonObject = JSON.stringify(items);
// Convert JSON to CSV
var csvstring = ConvertToCSV(jsonObject);
$('#csv').text(csvstring);
})
};
</script>
Include a link in html:
</form>
<!-- Define "Download .csv link here" -->
<a href="javascript:void(0)" onclick="download_csv_function();" >Get data as csv file</a>
</form>
<body>
<pre id="csv"></pre>
</body>
Thanks!

Thanks to the helpful comments, I could get this running and updated the code to the final version that uses FileSaver.js. The following syntax "saveTextAs(data, filename)" solved the problem. It works for both Firefox and Safari (IE I haven't checked yet). In addition to FileSaver.js, jQuery needs to be loaded for proper functioning of the href link.
First load js libraries:
</script>
<!-- Load jQuery and FileSaver.js here -->
<script src="/path-to-jquery.js"></script>
<script src="/path-to-FileSaver.js"></script>
<script>
Script to convert json object to csv and to open download dialog (this is mostly based on another script found at SO, but I cannot find the source again - if someone knows, I would be happy to include a link here):
<script type="text/javascript">
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;
}
function download_csv_function() {
// Read in JSON data and transform to CSV
$(document).ready(function () {
// Read in json data
var items = <?php echo $jsonout; ?>;
// Convert JSON object into JSON string
var jsonObject = JSON.stringify(items);
// Convert JSON to CSV
var csvstring = ConvertToCSV(jsonObject);
// FileSaver.js: open download dialog and save file as csv
saveTextAs(csvstring, "data.csv");
})
};
</script>
Include a link in html:
</form>
<!-- Define "Download .csv link here" -->
<a href="javascript:void(0)" onclick="download_csv_function();" >Get data as csv file</a>
</form>
Thanks everyone for the help!

Related

create a downloadable csv from a json string

Target: write&download a csv file starting with a json string, for example data.csv containing
col1,col2,col3
"324","19-08-2014","13000"
"325","19-08-2014","5010"
What I have done until now:
1) iframe and button to call my conversion function
<iframe id="frame" style="display:none"></iframe>
<form><input type="submit" value="Export CSV" onclick="javascript:Download();"></form>
2) my Download() function which would want to download my csv file
<script type="text/javascript">
function Download(){
var csv=ConvertToCSV(<?php echo $json_string ?>);
var url='data:application/csv,'+csv;
var _iframe_dl = $('<iframe />')
.attr('src', url)
.hide()
.appendTo('body');
};
</script>
3) my json to csv conversion function which tries to create a csv string
<script type="text/javascript">
function ConvertToCSV(json) {
var array = typeof json != 'object' ? JSON.parse(json) : json;
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;
}
</script>
Encountered problems :
i) it seems that it doesn't recognize \r\n, infact output is just one line
"324","19-08-2014","13000""325","19-08-2014","5010"
ii) I cannot set the filename and the extension, infact the downloaded file is "download" without extension containing the single line mentioned above
First of all, you will need to ensure your data is in this format, like the example below.
var array = [["col1","col2","col3"],["324","19-08-2014","13000"],["324","19-08-2014","13000"]]
then you need to create csv variable as shown below
var csv = "data:text/csv;charset=utf-8,";
after this you need to loop through your data array and append each line to the csv variable you just set.
array.forEach(function(arrayItem, index){
arrayAsString = arrayItem.join(",");
csv += index < array.length ? arrayAsString+ "\n" : arrayAsString;
});
now to give this file a name and create a download link you must create a hidden anchor node and set its download attribute.
var encUri = encodeURI(csv);
var link = document.createElement("a");
link.setAttribute("href", encUri);
link.setAttribute("download", "file_name.csv");
//add anchor element to body
document.body.appendChild(link);
link.click();
EDIT:
Tested on Chrome and is working, also on Safari. Does not work on Firefox for some reason which i will take a look at now
I found out that if you add the link into the body of the page only then will Firefox initiate the download, you can use a code like so. I have updated my code above
document.body.appendChild(link);

Another way to display JS on PHP page?

i am retrieving some information from Google's API and placing them in a single variable, and then inserting them to a div in the DOM like so:
$(function() {
// Load the info via Google's API
$.getJSON("https://www.googleapis.com/plus/v1/people/103039534797695934641/activities/public?maxResults=5&key=AIzaSyBaDZGM-uXuHc-VZZ2DINzVBcIDMN_54zg", function(data) {
// Variable to hold the HTML we'll generate
var html = '';
// how many posts we're displaying on the page
var numberOfPosts = 3;
// Loop over the results, generating the HTML for each <li> item
for (var i=0; i<numberOfPosts; i++) {
html += '<article>';
html += '<img src="'+data.items[i].actor.image.url+'">';
html += '<p>'+data.items[i].title+'</p>';
html += '<p>'+data.items[i].published+'</p>';
html += '</article>';
}
// Insert the generated HTML to the DOM
$('.google-posts-container').html(html);
});
});
My question is: is there a way to store every piece of information in each of its own variable, and then get the information individually by echoing the variable? So i dont have to hardcode all that HTML.
back in the days I would do:
<div id="google-posts-container">
<article>
<img src="{{image}}">
<p>{{title}}</p>
<p>{{published}}</p>
</article>
</div>
<script type="text/javascript">
// render a template (replace variables and return html)
function renderTemplate(tmpl, data){
for (k in data){
while(tmpl.indexOf('{{'+k+'}}') > -1){
tmpl = tmpl.replace('{{'+k+'}}', data[k]);
}
}
return tmpl;
}
$(function(){
// our template
var template = $('#google-posts-container').html();
$('#google-posts-container').html(''); // or clear()
$.getJSON("https://www.googleapis.com/plus/v1/people/103039534797695934641"
+"/activities/public"
+"?maxResults=5&key=AIzaSyBaDZGM-uXuHc-VZZ2DINzVBcIDMN_54zg", function(data) {
// Variable to hold the HTML we'll generate
var html = '';
// how many posts we're displaying on the page
var numberOfPosts = 3;
// Loop over the results, generating the HTML for each <li> item
for (var i=0; i<numberOfPosts; i++) {
html += renderTemplate(template, {
image : data.items[i].actor.image.url,
title : data.items[i].title,
publish : data.items[i].published
});
}
// Insert the generated HTML to the DOM
$('.google-posts-container').html(html);
});
});
</script>
nowadays I use angularjs
About comment by 'galchen' - don't use angular.js for serious &(or) big projects. Just look at source code.
(can't add sub comment, thats why i wrote to main branch)

How do I import, edit, and replace text in a txt file?

Using a client side script in a webpage (no server code), like javascript, how do I import, edit, and replace text in a txt file? I am simply trying to use two variables (Name and IP Address) and replace them in a text file. The existing text file is very long and I would like to automate this process. It would be nice for the script to also automatically create a new text file each time it is submitted. THANKS!
Here's my code:
<html>
<head>
<title>TExt File Changer v1</title>
<script type="text/javascript">
function findaNamendReplaceAll() {
var findaName = "Site_Name";
var findaCIP = "192.168.0.5";
var replaceaName = document.myInput.replaceWithName.value;
var replaceaCIP = document.myInput.replaceWithCIP.value;
var fulltexta = document.myInput.fulltext.value;
/*
var nr = new RegExp(findaName,"ig");
var tmp = fulltexta.replace(/Site_Name/gi, replaceaName).replace(/192.168.0.5 /gi,replaceaCIP);
document.myInput.fulltext.value = tmp;
*/
document.myInput.fulltext.value = fulltexta.replace(/Site_Name/gi, replaceaName).replace(/192.168.0.5/gi,replaceaCIP);
}
var str += ‘SECTION ethernet’/n;
str += ‘ETHERNET=UP’/n;
str += ‘BOOTP=server’/n;
str += ‘HOSTNAME=Site_Name’/n;
str += ‘IPADDR=192.168.0.4’/n;
str += ‘NETMASK=255.255.255.0’/n;
str += ‘DNS=‘/n;
str += ‘DHCP_RANGE_L=192.168.0.20’/n;
str += ‘DHCP_RANGE_U=192.168.0.100’/n;
str += ‘SEARCH=‘/n;
str += ‘ZEROCONF=YES’/n;
str += ‘ETH0_ADD_DEFAULT=on’/n;
str += ‘ENDSECTION ethernet’/n;
str += ‘‘;
</script>
</head>
<body>
<form name="myInput" onsubmit="return false">
<h1>Configuration Tool</h1>
New Site Name: <input type="text" id="replaceWithName" name="replaceWithName" value="">
<br><br>
New Camera IP: <input type="text" id="replaceWithCIP" name="replaceWithCIP" value="">
<br><br>
<button onclick="findaNamendReplaceAll()">Go</button>
<br><br>
<textarea id="fulltext" name="fulltext" rows="20" cols="100">
SECTION ethernet
ETHERNET=UP
BOOTP=no
HOSTNAME=Site_Name
IPADDR=192.168.0.4
NETMASK=255.255.255.0
DNS=
DHCP_RANGE_L=
DHCP_RANGE_U=
SEARCH=
ZEROCONF=YES
ETH0_ADD_DEFAULT=on
ENDSECTION ethernet
</textarea>
<br>
<button onclick="document.getElementById('fulltext').value = ''">Clear</button>
<button onclick="document.getElementById('fulltext').value = str">Restore</button>
</form>
</body>
</html></pre>
You can do it easily, provided you adhere to two limitations.
1) Internet Explorer on windows
2) Use of ActiveXObjects
I did a project that required assembling various data as found in excel spreadsheets. My input file was a hand-edited json file - specifying things like filenames and paths. Once the json was loaded, I used an ActiveXObject to open and control Excel in just the same manner as one would from within a VBA program.
As a result, I don't have any code to load arbitrary data from an arbitrary filename.
However, this snippet should give you enough to get started.
Note: The code assumes that IE still gives you a fully qualified path for any file selected with an <input type='file'/> Chrome, FF and Opera only give you the filename - they do not tell you which folder it resides in.
function byId(e){return document.getElementById(e);}
function writeDataToFile()
{
var mFSO = new ActiveXObject("Scripting.FileSystemObject");
var mFile = mFSO.createtextfile(outputFilename);
mFile.write( byId('outputTextArea').value );
mFile.close();
alert("text saved to '" + outputFilename + "'");
}

easiest way to read data from excel spreadsheet with javascript?

I have a list of airport codes, names, and locations in an Excel Spreadsheet like the below:
+-------+----------------------------------------+-------------------+
| Code | Airport Name | Location |
+-------+----------------------------------------+-------------------+
| AUA | Queen Beatrix International Airport | Oranjestad, Aruba|
+-------+----------------------------------------+-------------------+
My Javascript is passed a 3 character string that should be an airline code. When that happens I need to find the code on the spreadsheet and return the Airport Name and Location.
Im thinking something like:
var code = "AUA";
console.log(getAirportInfo(code));
function getAirportInfo(code) {
// get information from spreadsheet
//format info (no help needed there)
return airportInfo;
}
Where the log would write out:
Oranjestad, Aruba (AUA): Queen Beatrix International Airport
What is the easiest method to get the data I need from the spreadsheet?
Extra Info:
The spreadsheet has over 17,000 entries
The function alluded to above may be called up to 8 times in row
I don't have to use an Excel Spreadsheet thats just what I have now
I will never need to edit the spreadsheet with my code
I did search around the web but everything I could find was much more complicated than what Im trying to do so it made it hard to understand what Im looking for.
Thank you for any help pointing me in the right direction.
I ended up using a tool at shancarter.com/data_converter to convert my flie to a JSON file and linked that to my page. Now I just loop through that JSON object to get what I need. This seemed like the simplest way for my particular needs.
I've used a plain text file(csv, or tsv both of which can be exported directly from Excel)
Loaded that into a string var via xmlhttprequest. Usually the browsers cache will stop having to download the file on each page load.
Then have a Regex parse out the values as needed.
All without using any third party....I can dig the code out if you wish.
Example:
you will need to have the data.txt file in the same web folder as this page, or update the paths...
<html>
<head>
<script>
var fileName = "data.txt";
var data = "";
req = new XMLHttpRequest();
req.open("GET", fileName, false);
req.addEventListener("readystatechange", function (e) {
data = req.responseText ;
});
req.send();
function getInfoByCode(c){
if( data == "" ){
return 'DataNotReady' ;
} else {
var rx = new RegExp( "^(" + c + ")\\s+\\|\\s+(.+)\\s+\\|\\s+\\s+(.+)\\|", 'm' ) ;
var values = data.match(rx,'m');
return { airport:values[2] , city:values[3] };
}
}
function clickButton(){
var e = document.getElementById("code");
var ret = getInfoByCode(e.value);
var res = document.getElementById("res");
res.innerText = "Airport:" + ret.airport + " in " + ret.city;
}
</script>
</head>
<body>
<input id="code" value="AUA">
<button onclick="clickButton();">Find</button>
<div id="res">
</div>
</body>
</html>

Use jQuery to get the file input's selected filename without the path

I used this:
$('input[type=file]').val()
to get the file name selected, but it returned the full path, as in "C:\fakepath\filename.doc". The "fakepath" part was actually there - not sure if it's supposed to be, but this is my first time working with the filename of file uploads.
How can I just get the file name (filename.doc)?
var filename = $('input[type=file]').val().split('\\').pop();
or you could just do (because it's always C:\fakepath that is added for security reasons):
var filename = $('input[type=file]').val().replace(/C:\\fakepath\\/i, '')
You just need to do the code below. The first [0] is to access the HTML element and second [0] is to access the first file of the file upload (I included a validation in case that there is no file):
var filename = $('input[type=file]')[0].files.length ? ('input[type=file]')[0].files[0].name : "";
Get path work with all OS
var filename = $('input[type=file]').val().replace(/.*(\/|\\)/, '');
Example
C:\fakepath\filename.doc
/var/fakepath/filename.doc
Both return
filename.doc
filename.doc
Chrome returns C:\fakepath\... for security reasons - a website should not be able to obtain information about your computer such as the path to a file on your computer.
To get just the filename portion of a string, you can use split()...
var file = path.split('\\').pop();
jsFiddle.
...or a regular expression...
var file = path.match(/\\([^\\]+)$/)[1];
jsFiddle.
...or lastIndexOf()...
var file = path.substr(path.lastIndexOf('\\') + 1);
jsFiddle.
Here is how I do it, it works pretty well.
In your HTML do:
<input type="file" name="Att_AttributeID" onchange="fileSelect(event)" class="inputField" />
Then in your js file create a simple function:
function fileSelect(id, e){
console.log(e.target.files[0].name);
}
If you're doing multiple files, you should also be able to get the list by looping over this:
e.target.files[0].name
maybe some addition for avoid fakepath:
var fileName = $('input[type=file]').val();
var clean=fileName.split('\\').pop(); // clean from C:\fakepath OR C:\fake_path
alert('clean file name : '+ fileName);
How about something like this?
var pathArray = $('input[type=file]').val().split('\\');
alert(pathArray[pathArray.length - 1]);
This alternative seems the most appropriate.
$('input[type="file"]').change(function(e){
var fileName = e.target.files[0].name;
alert('The file "' + fileName + '" has been selected.');
});
Does it have to be jquery? Or can you just use JavaScript's native yourpath.split("\\") to split the string to an array?
<script type="text/javascript">
$('#upload').on('change',function(){
// output raw value of file input
$('#filename').html($(this).val().replace(/.*(\/|\\)/, ''));
// or, manipulate it further with regex etc.
var filename = $(this).val().replace(/.*(\/|\\)/, '');
// .. do your magic
$('#filename').html(filename);
});
</script>
Get the first file from the control and then get the name of the file, it will ignore the file path on Chrome, and also will make correction of path for IE browsers. On saving the file, you have to use System.io.Path.GetFileName method to get the file name only for IE browsers
var fileUpload = $("#ContentPlaceHolder1_FileUpload_mediaFile").get(0);
var files = fileUpload.files;
var mediafilename = "";
for (var i = 0; i < files.length; i++) {
mediafilename = files[i].name;
}
Here you can call like this
Let this is my Input File control
<input type="file" title="search image" id="file" name="file" onchange="show(this)" />
Now here is my Jquery which get called once you select the file
<script type="text/javascript">
function show(input) {
var fileName = input.files[0].name;
alert('The file "' + fileName + '" has been selected.');
}
</script>
var filename=location.href.substr(location.href.lastIndexOf("/")+1);
alert(filename);
We can also remove it using match
var fileName = $('input:file').val().match(/[^\\/]*$/)[0];
$('#file-name').val(fileName);

Categories