I need to be able to take data from a CSV file (which has been chosen by the user via <input type="file" id="fileInput">) and put it into an array. Id rather avoid using jquery as I haven't used it before but any help would be appreciated. Here's my code:
<div id="page-wrapper">
<div>
Select a text file:
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"><pre>
</div>
<p id="csvData"></p>
<button onClick="test()">Show Text</button>
<script>
function test (){
var file = fileInput.files[0];
var textType = /text.*/;
var csvType = 'application/vnd.ms-excel';
if (file.type.match(csvType)) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById("csvData").innerHTML=reader.result;
}
reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!";
}
}
</script>
1 Answer 1
To process a csv type file, there's two things you need to do:
- Split in to lines
- Split in to columns
You can do both by using String.prototype.split. This method splits a string into an array. To split on each new line, use the regex /\n/. To split each column, use the character that is used in your data (probably , or ;).
Here's an example:
// Create an array of arrays
// Remove first line
// Split by ","
function process(dataString) {
var lines = dataString
.split(/\n/) // Convert to one string per line
.map(function(lineStr) {
return lineStr.split(","); // Convert each line to array (,)
})
.slice(1); // Discard header line
return JSON.stringify(lines, null, 2);
}
function test() {
var file = fileInput.files[0];
var textType = /text.*/;
var csvType = 'text/csv';
if (file.type.match(csvType)) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById("csvData").innerHTML = process(reader.result);
}
reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!";
}
}
<div id="page-wrapper">
<div>
Select a text file:
<input type="file" id="fileInput" />
</div>
<pre id="fileDisplayArea"></pre>
<pre id="csvData"></pre>
<button onClick="test()">Show Text</button>
</div>
Store this data snippet as a .csv file to test:
ONE,TWO,THREE
1,2,3
2,4,6
3,6,9
An additional note: if there is a header row in your data, like in the example above, I'd strongly suggest to not map to arrays, but to objects. This makes your code easier to read and use:
// Create an array of objects
// Use the first line as keys
// Split by ","
function process(dataString) {
var lines = dataString
.split(/\n/)
.map(function(lineStr) {
return lineStr.split(",");
});
var keys = lines[0];
var objects = lines
.slice(1)
.map(function(arr) {
return arr.reduce(function(obj, val, i) {
obj[keys[i]] = val;
return obj;
}, {});
});
return JSON.stringify(objects, null, 2);
}
function test() {
var file = fileInput.files[0];
var textType = /text.*/;
var csvType = 'text/csv';
if (file.type.match(csvType)) {
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById("csvData").innerHTML = process(reader.result);
}
reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!";
}
}
<div id="page-wrapper">
<div>
Select a text file:
<input type="file" id="fileInput" />
</div>
<pre id="fileDisplayArea"></pre>
<pre id="csvData"></pre>
<button onClick="test()">Show Text</button>
</div>
8 Comments
csvType to text/csv in my snippet for testing. Change it back to whatever type you're using before trying it out. I don't know what you'll get when you try to parse an excel file though. Have you exported to .csv or are you trying to load a .xls?process method that makes an array of each line. In the future, when somebody takes the time to help you out, try to invest some time as well in to trying to understand the suggestion, and don't just say "Doesn't work"process method, remove the JSON.stringify from its return statement, and you're ready to go.
csvTypeis wrong... a csv usetext/csvas a mimetype