0

I'm working on a project where I need to be able to update an HTML table, and I would do it through javascript. I have not yet made an HTML site for this project, for I would try to convert a CSV file to a Java array, which would update the HTML table.

I have been trying with papa parse, but it would not work for me. I have no experience with npm and installing and getting stuff to work like Papa parsa. I have found this website, which has a great function to convert CSV to an array. One problem with this function is, that I can't take a local file on the server, and put it into the function as I do with a string. Maybe I have overlooked something?

  • I have got Papa Parse to work somehow, but I can't figure out how I use it on a local file, so I have two codes for the job, but I don't know how to get them to do it or how good the outcome is.

  • I just got a random CSV file as a test file. Normal.csv came from papa parse website.

-- to sum up -- I want to take a CSV file, turn it into a Java array, and then make that into an HTML table

Here is my long HTML file, with all scripts - no CSS at this point.

File(s) is being hosted on local Apache/XAMPP server.

<head>
    <title>Test af Papa Parse</title>
</head>
<body>
    <p>Hey - Test paraghaph</p>
    <script src="node_modules/papaparse/papaparse.min.js"></script> 
    <script src="node_modules/jquery/dist/jquery.min.js"></script> 
/*edit: src="http://localhost/test/node_modules/papaparse/papaparse.min.js"*/
/*edit: src="http://localhost/test/node_modules/jquery/dist/jquery.min.js"*/
    <script>    

      var config = {
        download: true,
        // rest of config ...
        delimiter: "",  // auto-detect
        newline: "",  // auto-detect
        quoteChar: '"',
        escapeChar: '"',
        header: false,
        trimHeaders: false,
        dynamicTyping: false,
        preview: 0,
        encoding: "",
        worker: false,
        comments: false,
        step: undefined,
        complete: undefined,
        error: undefined,
        download: false,
        skipEmptyLines: false,
        chunk: undefined,
        fastMode: undefined,
        beforeFirstChunk: undefined,
        withCredentials: undefined,
        transform: undefined
      }

      var data = csv2array("http://localhost/test/normal.csv")

      var data2 = Papa.parse("http://localhost/test/normal.csv", config)
      console.log("papa parsa - direktly: "+ Papa.parse("http://localhost/test/normal.csv", config))
      console.log(data)
      console.log("data2 = "+data2)
      console.log(data2);

      /**
      * Convert data in CSV (comma separated value) format to a javascript array.
       *
       * Values are separated by a comma, or by a custom one character delimeter.
       * Rows are separated by a new-line character.
       *
       * Leading and trailing spaces and tabs are ignored.
       * Values may optionally be enclosed by double quotes.
       * Values containing a special character (comma's, double-quotes, or new-lines)
       *   must be enclosed by double-quotes.
       * Embedded double-quotes must be represented by a pair of consecutive 
       * double-quotes.
       *
       * Example usage:
       *   var csv = '"x", "y", "z"\n12.3, 2.3, 8.7\n4.5, 1.2, -5.6\n';
       *   var array = csv2array(csv);
       *  
       * Author: Jos de Jong, 2010
       * 
       * @param {string} data      The data in CSV format.
       * @param {string} delimeter [optional] a custom delimeter. Comma ',' by default
       *                           The Delimeter must be a single character.
       * @return {Array} array     A two dimensional array containing the data
       * @throw {String} error     The method throws an error when there is an
       *                           error in the provided data.
       */ 
      function csv2array(data, delimeter) {
        // Retrieve the delimeter
        if (delimeter == undefined) 
          delimeter = ',';
        if (delimeter && delimeter.length > 1)
          delimeter = ',';

        // initialize variables
        var newline = '\n';
        var eof = '';
        var i = 0;
        var c = data.charAt(i);
        var row = 0;
        var col = 0;
        var array = new Array();

        while (c != eof) {
          // skip whitespaces
          while (c == ' ' || c == '\t' || c == '\r') {
            c = data.charAt(++i); // read next char
          }
          // get value
          var value = "";
          if (c == '\"') {
            // value enclosed by double-quotes
            c = data.charAt(++i);

            do {
              if (c != '\"') {
                // read a regular character and go to the next character
                value += c;
                c = data.charAt(++i);
              }
              if (c == '\"') {
                // check for escaped double-quote
                var cnext = data.charAt(i+1);
                if (cnext == '\"') {
                  // this is an escaped double-quote. 
                  // Add a double-quote to the value, and move two characters ahead.
                  value += '\"';
                  i += 2;
                  c = data.charAt(i);
                }
              }
            }
            while (c != eof && c != '\"');
            if (c == eof) {
              throw "Unexpected end of data, double-quote expected";
            }

            c = data.charAt(++i);
          }
          else {
            // value without quotes
            while (c != eof && c != delimeter && c!= newline && c != ' ' && c != '\t' && c != '\r') {
              value += c;
              c = data.charAt(++i);
            }
          }

          // add the value to the array
          if (array.length <= row) 
            array.push(new Array());
          array[row].push(value);
          // skip whitespaces
          while (c == ' ' || c == '\t' || c == '\r') {
            c = data.charAt(++i);
          }

          // go to the next row or column
          if (c == delimeter) {
            // to the next column
            col++;
          }
          else if (c == newline) {
            // to the next row
            col = 0;
            row++;
          }
          else if (c != eof) {
            // unexpected character
            throw "Delimiter expected after character " + i;
          }
          // go to the next character
          c = data.charAt(++i);
        }  
        return array;
      }
    </script>
</body>
The_Mikkel
  • 13
  • 5
  • When you say Papa Parse wouldn't work, was there an error? Saying some 'wouldn't work' doesn't make it easy to debug. – Andrew MacNaughton Nov 04 '18 at 19:43
  • You are importing npm modules, but run your code in a browser? That seems wrong. npm is for node on the server side. Also, you'll have better results if you actually *use* your local apache server. Use `http://localhost` instead of `file://` – trincot Nov 04 '18 at 19:48
  • I have written a small line where I take normal.csv and feeds papa parse the document. But it doesn't give any output in the console. I don't know if I do anything wrong or if the program is running/install or something along does edges. Or if I have tried to print the output of papa Parse wrong – The_Mikkel Nov 04 '18 at 19:50
  • I have no experience in npm, and i would just like to use Papa parse to convert the csv file to an array. Is papa parse not for these kind of works that I am trying to work with? – The_Mikkel Nov 04 '18 at 19:53

3 Answers3

1

You don't need whole libs to parse CSV, which is the simplest format I can think of. Fetch the file via ajax then use one of these functions to do the CSV → array cast.

var CSVContent = `column1, column2, column3
1, 2, hello
3, 4, world`;

function CSVToArrayOfArray(content) {
  return content
    .split('\r\n').join('\n') // CRLF -> LF
    .split('\n')
    .map(line => line.split(',').map(value => value.trim()));
}

function CSVToArrayOfObjects(content) {
  let ret = CSVToArrayOfArray(content)
    .map((arr, index, all) => {
      if (index==0) {
        return arr;
      }
      let obj = {};
      all[0].forEach((field, i) => obj[field] = arr[i])
      return obj;
    });
  ret.shift();
  return ret;
}

console.log(CSVToArrayOfArray(CSVContent));
console.log(CSVToArrayOfObjects(CSVContent));
Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
  • This is a great code! - Now i just want to use a real csv file from localhost, and i write this; var CSVContent = "http://localhost/test/Short-test-file-9-boder.csv" | Is this the correct way or how should it look? – The_Mikkel Nov 04 '18 at 20:59
  • No CSVContent is only for the text content of the CSV file. Use it as such: `fetch('localhost/path/to/resource).then(content => console.log(CSVToArrayOfArray(content)))` – Nino Filiu Nov 04 '18 at 21:01
  • [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) is used to read a file over http – Nino Filiu Nov 04 '18 at 21:02
  • I got it at the point now, that i have loaded the csv file, but it just gives an error in console: Uncaught TypeError: content.split is not a function – The_Mikkel Nov 04 '18 at 21:11
  • `content` should be a string. Make sure it is. – Nino Filiu Nov 04 '18 at 21:19
  • I can't figure out what i have done wrong, or how to make the file to a string. I have made this, and this should work? `function CSVToArrayOfArray(content) { return content /*/n*/ .split('\r\n').join('\n') // CRLF -> LF /*/n*/ .split('\n') /*/n*/ .map(line => line.split(',').map(value => value.trim())); /*/n*/ } /*/n*/ fetch('http://localhost/test/short-test-file-9-boder.csv').then(content => console.log(CSVToArrayOfArray(content)));` – The_Mikkel Nov 05 '18 at 14:14
  • the error: `Uncaught (in promise) TypeError: content.split is not a function` – The_Mikkel Nov 05 '18 at 14:20
0

I think your best option is to simplify everything until you figure out exactly what you need. Here is a very basic working Papa.parse. You have no need for the config file unless you are doing something that specifically requires it. Here is a plnkr link

<html>

  <head>
    <script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.6.1/papaparse.min.js"></script>
  </head>

  <body>
    <script>
      let csvString = '2018-06-29,2018-06-29,111211,15:35:00,77,15:50:00,,Blah,Internet User,,Baln bla,0,4,0,0,0,$516.00 ,$120.00 ,$396.00 ,$19.80 ,$415.80 ,,$0.00 ,$0.00 ,$415.80';
      //let array = Papa.parse(csvString);
      //console.log(array);
     let array = Papa.parse('http://localhost/test/filename.csv',{download:true});
     console.log(array);

    </script>
  </body>

</html>

Once you have this working on your local server, delete the csvString, load the file in and go from there... edit: npm is a great tool for a lot of things, however from what I can tell, this doesn't seem like a great use case for it.

Andrew MacNaughton
  • 783
  • 2
  • 6
  • 21
  • Your solution is good, but I'm stuck at loading the CSV file from the host, replaced string with: "http://localhost/test/Short-test-file-9-boder.csv" | Is this the correct way, or how should I load the file? – The_Mikkel Nov 04 '18 at 21:03
0

The final codes. Tried to explain every step, so anybody knows how it works

<head>
        <meta charset="UTF-8">
</head>
<body>
    <!--Loading Papa.parse-->
    <script src="http://localhost/test/node_modules/papaparse/papaparse.min.js"></script> 
    <!--The script-->
    <script>
        //The file with the csv data
        var CSVFile = "http://localhost/test/download.csv"

        //papa.parse function, which converts CSV file to array
        function parse() {
            Papa.parse(CSVFile,{
                download: true, //When linking an URL the download must be true
                header: true, //makes the header in front of every data in the array
                complete: function (results) { //Runs log function, with results from the conversion
                    log(results);
                }
            });         
        }
        //Papa.parse does it own callback and launches this function when done
        function log(arrayFromPapa) {
            //Writes the array in the console
            console.log(arrayFromPapa);
            //Makes the array a global array
            array = arrayFromPapa
        }
        //luanching the program
        parse()
    </script>
</body>
The_Mikkel
  • 13
  • 5