5

I have a CSV file in the same directory as an html page, and I'd like to use FileReader to read the file contents into a jquery-csv's To Arrays function, but I can't seem to get it to work properly. I think I understand the asynchrony of this task, but have i depicted it correctly? Here, I'm trying to output the 2nd cell in the 2nd column. Thanks for any help.

<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['timeline']}]}"></script>

<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="jquery.csv-0.71.js"></script>
<script type="text/javascript">

var reader = new FileReader();

reader.onload = function(e) {
  var text = e.target.result;
  var data = $.csv.toArrays(text);
  document.write(data[1][1]);

}

reader.readAsText('data.csv');




</script>
Evan Plaice
  • 13,944
  • 6
  • 76
  • 94
Terrarium
  • 74
  • 1
  • 1
  • 4
  • 1
    [FileReader operations take a file/blob object](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsText#Parameters), not a url path. You have to get the file from a server by using an ajax request – Patrick Evans May 13 '15 at 19:14

2 Answers2

12

Here's a working demo provided by jquery-csv

<html>
<head>
<meta charset="utf-8" />
<title>Demo - CSV-to-Table</title>
</head>

<body>
  <div id="inputs" class="clearfix">
    <input type="file" id="files" name="files[]" multiple />
  </div>
  <hr />
  <output id="list">
  </output>
  <hr />
  <table id="contents" style="width:100%; height:400px;" border>
  </table>

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
  <script src="http://evanplaice.github.io/jquery-csv/src/jquery.csv.min.js"></script>
  <script>
    $(document).ready(function() {
      if(isAPIAvailable()) {
        $('#files').bind('change', handleFileSelect);
      }
    });

    function isAPIAvailable() {
      // Check for the various File API support.
      if (window.File && window.FileReader && window.FileList && window.Blob) {
        // Great success! All the File APIs are supported.
        return true;
      } else {
        // source: File API availability - http://caniuse.com/#feat=fileapi
        // source: <output> availability - http://html5doctor.com/the-output-element/
        document.writeln('The HTML5 APIs used in this form are only available in the following browsers:<br />');
        // 6.0 File API & 13.0 <output>
        document.writeln(' - Google Chrome: 13.0 or later<br />');
        // 3.6 File API & 6.0 <output>
        document.writeln(' - Mozilla Firefox: 6.0 or later<br />');
        // 10.0 File API & 10.0 <output>
        document.writeln(' - Internet Explorer: Not supported (partial support expected in 10.0)<br />');
        // ? File API & 5.1 <output>
        document.writeln(' - Safari: Not supported<br />');
        // ? File API & 9.2 <output>
        document.writeln(' - Opera: Not supported');
        return false;
      }
    }

    function handleFileSelect(evt) {
      var files = evt.target.files; // FileList object
      var file = files[0];

      // read the file metadata
      var output = ''
          output += '<span style="font-weight:bold;">' + escape(file.name) + '</span><br />\n';
          output += ' - FileType: ' + (file.type || 'n/a') + '<br />\n';
          output += ' - FileSize: ' + file.size + ' bytes<br />\n';
          output += ' - LastModified: ' + (file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() : 'n/a') + '<br />\n';

      // read the file contents
      printTable(file);

      // post the results
      $('#list').append(output);
    }

    function printTable(file) {
      var reader = new FileReader();
      reader.readAsText(file);
      reader.onload = function(event){
        var csv = event.target.result;
        var data = $.csv.toArrays(csv);
        var html = '';
        for(var row in data) {
          html += '<tr>\r\n';
          for(var item in data[row]) {
            html += '<td>' + data[row][item] + '</td>\r\n';
          }
          html += '</tr>\r\n';
        }
        $('#contents').html(html);
      };
      reader.onerror = function(){ alert('Unable to read ' + file.fileName); };
    }
  </script>
</body>
</html>

Disclaimer: I'm the author of jquery-csv

Evan Plaice
  • 13,944
  • 6
  • 76
  • 94
  • 1
    @AuriellePerlmann You're welcome. Just a heads-up, browsers have an upper limit on how much data you can load into memory (ie 10MB) via the HTML5 File API. If you need to load raw CSV files larger than that, you'll need a parser capable of chunking the input. If that's the case, I highly recommend PapaParse. – Evan Plaice Dec 08 '17 at 06:41
  • Cool thanks, yeah I've seen the perils of csv size and every painful edge case but we deal with most of it server side, this is perfect for a project I'm helping someone with that's client side with a file picker. I'm so relieved I can stop searching and searching ha – Aurielle Perlmann Dec 08 '17 at 06:45
  • I know -- intimately -- the limits of CSV. It's pretty lousy for dealing with large quantities of data. For instance, to parse 1000 records you have to first parse them from start to finish to determine where the 1000th record ends. Even writing a simplified parser to speed up the process won't work unless you can guarantee that the values don't contain newline characters. Chunk parsers work around this limit by fetching an arbitrary amount of data and parsing until failure. I planned to add this capability but fortunately PapaParse saved me the time/effort by implementing it first. – Evan Plaice Dec 08 '17 at 06:57
  • Im pretty sure we use papaparse too at my company - similarly Im very passionate about how much I hate excel and that no program handles massive csv well for the end user - so one of our engineers built github.com/DataFoxCo/gocsv for us - saved the day(s) haha its great - but alas it is command line - hard to get everyone in the office to use it that have never used terminal :-P – Aurielle Perlmann Dec 08 '17 at 07:00
  • @AuriellePerlmann Cool, I'll have to give it a try if I happen to transition to Go at some point in the near future. – Evan Plaice Dec 08 '17 at 07:15
7

It's not going to work.You have no permissions to read files with javascript from the browser. The only way to deal with it is to create an input[type=file] tag and add onChange event to it. For example:

document.getElementById('fileupload').addEventListener('change', function (e) {
  var files = e.target.files;
  //proceed your files here
  reader.readAsText(files[0]);
}, false);
Anton Savchenko
  • 1,210
  • 1
  • 8
  • 11