function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Rajesh Kumar MaharanaRajesh Kumar Maharana 

Show data of a csv file in tabular form in LWC

I want to display the data of a .csv file in a tabular form using LWC.(Below is the image for the reference.)User-added image
Requirement: Whenever I upload a csv file, the data in the csv file should show in a tabular form(like above image.) in LWC.

Problem: Whenever I try to show the data in a <table>. The value is not showing in the <thead> &<tbody> (i.e. html). If I print the values of columnHeader and rows in the console, it gets displayed. 
As I am not able to find where is the problem?
(If there is any doubt in understanding, please mention here.)
Below is the code.
<!-- html file -->
<template>
  <lightning-card>
    <h3>
      <lightning-icon icon-name="utility:database" size="small"></lightning-icon>  CSV Dataloader
      <button class="slds-button slds-button_destructive" style="margin-right:0; margin-left:auto; display:block;">
        Clean Data
      </button>
    </h3>
    <lightning-input type="file" name="file" label="Attachment" accept=".csv" onchange={handleUploadFinished}>
    </lightning-input>

    <template if:true={showTable}>
      <table>
        <thead>
          <tr>
            <template for:each={csvString} for:item="head">
              <th key={head.column_name}>
                {head.column_name}
              </th>
            </template>
          </tr>
        </thead>
        <tbody>
          <template for:each={lines} for:item="row">
            <tr key={row}>
              <!--<template for:each={row} for:item="rowData">-->
                <td key={row}>{row}</td>
              <!--</template>-->
            </tr>
          </template>
        </tbody>
      </table>
    </template>
  </lightning-card>
</template>
=================================

// Javascript File

import { LightningElement, track, wire } from 'lwc';
import getCSVObject from '@salesforce/apex/CSVCreator.getCSVObject';

export default class CustomCSVDataloaderInLWC extends LightningElement {
  
    @track colHeader = [];
    @track showTable = false;
    @track csvString;
    @track st;
    @track csvFile;
    @track lines;
    
    handleUploadFinished(event) {
        
        const uploadedFiles = event.detail.files;
        const file = uploadedFiles[0];
        console.log("file : " + file);

        if (file) {
            this.showTable = true; //show the table
            console.log("this.showTable : " + this.showTable);
            let reader = new FileReader();
            reader.readAsText(file, "UTF-8");
            reader.onload = function (evt) {
                const csv = evt.target.result;
                console.log('csv : ' + csv);
                this.csvFile = csv;

                getCSVObject({
                    csv_str: csv
                })
                    .then(response => {
                        console.log("response : " + JSON.stringify(response));
                        this.csvString =JSON.stringify([...response.headers]);
                        console.log('this.csvString : '+this.csvString);
                       
                        this.lines = [...response.lines];
                        console.log('this.lines : '+JSON.stringify(this.lines));
                     
                        
                        let temp = response.headers;
                        let col_head;
                        this.colHeader = [];
                        temp.forEach(element => {

                            col_head = element.column_name;//JSON.stringify(element.column_name);
                            console.log("col_head : " + col_head);
                            this.colHeader = [...this.colHeader,col_head];                         
                        });
                        console.log("this.colHeader : " + this.colHeader);

                    }).catch(error => {
                        console.log("error2 ==> " + error);
                        console.log("error ==> " + error.body.message);
                    });

            };
        }
    }
}
Below is the console.log output of chrome in browser.
console window
Best Answer chosen by Rajesh Kumar Maharana
Rajesh Kumar MaharanaRajesh Kumar Maharana
Found the solution to the above issue. Actually the issue was, File reader is async method. So getCSVObject executes first then the File reader is executed. So in the UI, the column header and row data values are getting blank. So, I have used Promises in javascript.
Below is the code for the handleUploadFinished.
handleUploadFinished(event) {
        console.clear();
        let csvFile = event.detail.files;

        //Creating a Promise
        let newPromise = new Promise((resolve, reject) => {
            var reader = new FileReader();
            reader.onload = function () {
                resolve(reader.result);
            };
            reader.readAsText(csvFile[0]);
        })
            .then(result => {
                this.csvString = result;
                console.log("this.csvString : ");
                console.log(this.csvString);
                getCSVObject({ csv_str: this.csvString })
                    .then(response => {
                        console.log(response);
                        //Store the column header values
                        this.columnHeader = response.headers;
                        //Store the row values
                        this.lines = response.lines;
                    })
                    .catch(error => {
                        console.log("Error : " + error.body.message);
                    });
            })
            .catch(error => {
                console.log(error.message.body);
            });
    }

/* ============================================================================ */

/* ---Html code--- */

<table>
<thead>
<tr class="slds-line-height_reset">
<template for:each={columnHeader} for:item="header">
<th key={header.column_name} scope="col" style="max-width: 250px;">
{header.column_name}
</th>
</template>
</tr>
</thead>
<tbody>
<template for:each={lines} for:item="line">
<tr key={line} class="slds-hint-parent">
<template for:each={line} for:item="lineItem">
<td key={lineItem} style="max-width: 250px;">
<div class="slds-truncate" title={lineItem}>
{lineItem}
</div>
</td>
</template>
</tr>
</template>
</tbody>
</table>

 

All Answers

ANUTEJANUTEJ (Salesforce Developers) 
Hi Rajesh Kumar,

I found the below code can you try checking this code once:

HTML file:
<template>
    <lightning-card icon-name="custom:custom19" title='Read CSV File Demo In LWC'>
        <div style="margin-left: 3%">
            <lightning-file-upload accept={acceptedFormats} 
                                   label="Attach receipt" 
                                   multiple="multiple" 
                                   onuploadfinished={handleUploadFinished} 
                                   record-id={recordId}></lightning-file-upload>
        </div>


        <div if:true={error}>
            {error}
        </div><br/>

        <div if:true={data}>
            <lightning-datatable columns={columns} 
                                 data={data} 
                                 hide-checkbox-column="true" 
                                 key-field="id"></lightning-datatable>
        </div>

    </lightning-card>
</template>
JS file:
import { LightningElement, track, api } from 'lwc';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
import readCSV from '@salesforce/apex/LWCExampleController.readCSVFile';

const columns = [
    { label: 'Name', fieldName: 'Name' }, 
    { label: 'Industry', fieldName: 'Industry' },
    { label: 'Rating', fieldName: 'Rating'}, 
    { label: 'Type', fieldName: 'Type'}, 
    { label: 'Website', fieldName: 'Website', type:'url'}
];

export default class ReadCSVFileInLWC extends LightningElement {
    @api recordId;
    @track error;
    @track columns = columns;
    @track data;

    // accepted parameters
    get acceptedFormats() {
        return ['.csv'];
    }
    
    handleUploadFinished(event) {
        // Get the list of uploaded files
        const uploadedFiles = event.detail.files;

        // calling apex class
        readCSV({idContentDocument : uploadedFiles[0].documentId})
        .then(result => {
            window.console.log('result ===> '+result);
            this.data = result;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success!!',
                    message: 'Accounts are created based CSV file!!!',
                    variant: 'success',
                }),
            );
        })
        .catch(error => {
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error!!',
                    message: JSON.stringify(error),
                    variant: 'error',
                }),
            );     
        })

    }
}
Apex class:
public inherited sharing class LWCExampleController {

    @AuraEnabled
    public static list<Account> readCSVFile(Id idContentDocument){
        list<Account> lstAccsToInsert = new list<Account>();
        if(idContentDocument != null) {
            
            // getting File Data based on document id 
            ContentVersion objVersion = [SELECT Id, VersionData FROM ContentVersion WHERE ContentDocumentId =:idContentDocument];
            // split the file data
            list<String> lstCSVLines = objVersion.VersionData.toString().split('\n');

            for(Integer i = 1; i < lstCSVLines.size(); i++){
                Account objAcc = new Account();
                list<String> csvRowData = lstCSVLines[i].split(',');
                System.debug('csvRowData====> '+csvRowData);
                objAcc.Name = csvRowData[0]; // accName
                objAcc.Industry = csvRowData[1];
                objAcc.Rating = csvRowData[2];
                objAcc.Type = csvRowData[3];
                objAcc.Website = csvRowData[4];
                lstAccsToInsert.add(objAcc);
            }

            try{    
                if(!lstAccsToInsert.isEmpty()) {
                    insert lstAccsToInsert;
                }
            }
            catch (Exception ex) {
                throw new AuraHandledException(ex.getMessage());
            } 
        }
        return lstAccsToInsert;    
    }
}

I found the above example in  https://www.salesforcecodecrack.com/2019/09/read-csv-file-using-lightnig-web.html can you try checking this?

Regards,
Anutej
Rajesh Kumar MaharanaRajesh Kumar Maharana
Hi Anutej,

Thank you for replying.

Actually, I am trying to make it in a dynamic way. If any csv file is uploaded, it will show in tabular form. It is not specific to a particular object. Already I have implemented it using aura component, which is working fine.
But when I'm migrating it to LWC, I'm getting stuck. I'm not able find where is problem, in the Js or html. The values from .then(response => method, is not showing in the html part.

My full requirement is, to view the data of any csv file in the browser,  after the file gets uploaded if we want to import the records in database. Then we can import it by selecting object name from a drop down list and a button Import.
Rajesh Kumar MaharanaRajesh Kumar Maharana
Found the solution to the above issue. Actually the issue was, File reader is async method. So getCSVObject executes first then the File reader is executed. So in the UI, the column header and row data values are getting blank. So, I have used Promises in javascript.
Below is the code for the handleUploadFinished.
handleUploadFinished(event) {
        console.clear();
        let csvFile = event.detail.files;

        //Creating a Promise
        let newPromise = new Promise((resolve, reject) => {
            var reader = new FileReader();
            reader.onload = function () {
                resolve(reader.result);
            };
            reader.readAsText(csvFile[0]);
        })
            .then(result => {
                this.csvString = result;
                console.log("this.csvString : ");
                console.log(this.csvString);
                getCSVObject({ csv_str: this.csvString })
                    .then(response => {
                        console.log(response);
                        //Store the column header values
                        this.columnHeader = response.headers;
                        //Store the row values
                        this.lines = response.lines;
                    })
                    .catch(error => {
                        console.log("Error : " + error.body.message);
                    });
            })
            .catch(error => {
                console.log(error.message.body);
            });
    }

/* ============================================================================ */

/* ---Html code--- */

<table>
<thead>
<tr class="slds-line-height_reset">
<template for:each={columnHeader} for:item="header">
<th key={header.column_name} scope="col" style="max-width: 250px;">
{header.column_name}
</th>
</template>
</tr>
</thead>
<tbody>
<template for:each={lines} for:item="line">
<tr key={line} class="slds-hint-parent">
<template for:each={line} for:item="lineItem">
<td key={lineItem} style="max-width: 250px;">
<div class="slds-truncate" title={lineItem}>
{lineItem}
</div>
</td>
</template>
</tr>
</template>
</tbody>
</table>

 
This was selected as the best answer
Ravi Singh 2696Ravi Singh 2696
Hi rajesh,
can you share the complete code of this problem 
Madhava Reddy GudaMadhava Reddy Guda

Hi Rajesh,

Could you please share the complete code for this requirement including apex class.
Thanks in advance.
 

dsfr drydfydsfr drydfy

I found the tutorial on displaying CSV file data in a tabular form in LWC truly helpful, especially for someone like me, spectrumspeed , who is exploring Salesforce development. The step-by-step guide and code examples made it easy to understand and implement. Thanks for sharing this valuable resource! spectrum speed (https://spectrumspeed.org/)