1

I am converting an array of JS object to CSV by using below code

downloadCSVFromJson(filename, arrayOfJson) {
    // convert JSON to CSV
    const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
    const header = Object.keys(arrayOfJson[0]);
    let csv = arrayOfJson.map(row => header.map(fieldName =>
        JSON.stringify(row[fieldName], replacer)).join(','));
    csv.unshift(header.join(','));
    csv = csv.join('\r\n');

    // Create link and download
    var link = document.createElement('a');
    link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(csv));
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

And it is working as expected now I need to do vice versa csv to an array of objects to do the same I am using below approach

 handleUploadFinished() {
    this.showSpinner = true;

    [...this.template
        .querySelector('input[type="file"]')
        .files].forEach(async file => {
            try {
                const csv = await this.load(file);
                console.log(csv);

            } catch (e) {
                console.log('Error in Parsing CSV ' + e);
            }
        });
}

async load(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = function () {
            resolve(reader.result);
        };
        reader.onerror = function () {
            reject(reader.error);
        };
        reader.readAsText(file);
    });
}

without changing anything in the csv if I try to read it using the above code then I get below JSON

 "category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"

but when I do changes in the CSV, file save it and then try to read it by using the same code above then I get whole ouput surrounded by double quotes as shown below

"category,name,includeInAuto,srNumber,testType 
Test1,Name1,true,1,type1 
Test2,Name2,true,2,type2
Test3,Name3,true,3,type3
Test4,Name4,true,4,type4
Test5,Name5,true,5,type5
Test6,Name6,true,6,type6
Test7,Name7,true,7,type7"

the problem is not just with the quotes coming or not but when I change name7 to name,7 then I get something like below

"category,name,includeInAuto,srNumber,testType 
    Test1,Name1,true,1,type1 
    Test2,Name2,true,2,type2
    Test3,Name3,true,3,type3
    Test4,Name4,true,4,type4
    Test5,Name5,true,5,type5
    Test6,Name6,true,6,type6
    Test7,\"Name,7\",true,6,type6"

Above whole csv string is in double quotes but the name name, 7 is also in double quotes with some extra slashes now instead of 4 comma separated values we have 5 comma separated values which is incorrect

by spending some time on google I came across with this JS library called papaParse, if anyone has used this js library then please do let me know how can I use in LWC I am familiar till adding it as static resource and then importing in JS but not sure how to call method from this library.

2
  • Your code is not generating valid CSV data (it doesn't do anything to handle embedded commas or quotes), and you have not written code to parse a CSV - you're just reading a big string. I really recommend you use a parsing library and post here with a specific question about that library if you get stuck. – David Reed Apr 28 '20 at 12:15
  • I am sorry David, I I didn't post how I was parsing it, the above issue I mentioned can be resolved when we are parsing the csv string, I did not know that when I was posting this question. – gs650x Apr 28 '20 at 16:37
3

Here's a very simple CSV parsing demo from papaparse:

import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import PAPA from '@salesforce/resourceUrl/papaparse';

export default class Q304122 extends LightningElement {
    ready = false;
    connectedCallback() {
        loadScript(this, PAPA)
        .then(()=>{this.ready=true;});
    }
    onchange(event) {
        [...event.target.files].forEach(file => {
            Papa.parse(file, {
                complete: results => { console.log(results); }
            });
        })
    }
}

<template>
    <input if:true={ready} type="file" multiple accept=".csv" onchange={onchange} />
    <lightning-spinner if:false={ready}>
    </lightning-spinner>
</template>

Simply download the papaparse.min.js file from PapaParse, upload it as a static resource (here called papaparse), then in your connectedCallback(), you load the script, and in a handler, you load the files. I chose an onchange handler, but it could easily be an onclick handler. Showing the spinner and other niceties are left as an exercise to the reader.

You'll want to read the documentation; Papa can also convert objects into CSV files as well!

1
  • Thank you Brain, for your kind help – gs650x Apr 28 '20 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.