javascriptcsvexport-to-csv

Creating CSV string without plugin


I am trying to let the user download a list of filtered members from our app. I've done a much more complicated CSV String which works fine but for some reason I cannot get this one to work.

The code is:

  function getCSVString(){
    return ['nom', 'telèfon', 'email'].join(',') + '\n'
    + filteredMembers.value.map(member => {
      return [member.nom, member.telèfon, member.email].join(',') + '\n'
    })
  }

I have tried so many variants, with some '\r\n' or the joins somewhere else, and downloaded 42 test files already, but the closest I get looks like this, with a stupid white space after the first line that shifts everything:

Excel table with a stupid whitespace

What am I not seeing???

Thank you in advance!!!


Solution

  • NB: To highlight/repeat the comments for anyone viewing this in the future. The below answers the question:

    Why is there is an extra whitespace at the start of each row

    This is not an fully fledged CSV export and should not be used in "real" code unless there's a known set of values (ie non-user input).

    Anyone looking for CSV export code should consider all the rules required to build a functioning CSV, or look for an existing package/library.


    Your issue is the .map is returning an array.

    When you combine a str + array JS converts the array to a string representation, which is a comma-separated string - ie each line is comma separated - thus adding a comma at the start of each line.

    Fix is to .join() the array returned by .map without commas

    let members = [ 
        { nom:"A", tel:"1", email:"A" },
        { nom:"B", tel:"2", email:"B" },
        { nom:"C", tel:"3", email:"C" }
    ]
        
    let result = ['nom', 'telèfon', 'email'].join(',') + '\n' +
      members.map(member => {
        return [member.nom, member.tel, member.email].join(',') + '\n'
      }).join("");
    
    console.log(result);

    An alternative is to remove the +'\n' from each line then the array/map .join("\n")

    let members = [ 
        { nom:"A", tel:"1", email:"A" },
        { nom:"B", tel:"2", email:"B" },
        { nom:"C", tel:"3", email:"C" }
    ]
        
    let result = ['nom', 'telèfon', 'email'].join(',') + '\n' +
      members.map(member => {
        return [member.nom, member.tel, member.email].join(',')
      }).join("\n");
    
    console.log(result);