Building Reusable Utility to Generate CSV in LWC
You will learn the following things
- How to Create a component
- How to Create reusable Utility
- How to convert data in proper format
- Fetch data from apex and generating the CSV file
- CSV file with custom header, file name and data
Video Tutorial
Code
- Create Lwc component
csvDemo
and add the following code to the respective files.
csvDemo.html
<template>
<lightning-card title="CSV utility demo">
<template for:each={userData} for:item="user">
<div key={user.username}>
<p>{user.username} {user.age}, {user.title}</p>
</div>
</template>
<lightning-button variant="brand" label="download user data" onclick={downloadUserDetails}></lightning-button>
<lightning-button variant="brand" label="download account data" onclick={downloadAccountData}></lightning-button>
</lightning-card>
</template>
csvDemo.js
import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/tableController.getAccounts'
import {exportCSVFile} from 'c/utils'
export default class CsvDemo extends LightningElement {
accountData
@wire(getAccounts)
accountHandler({data}){
if(data){
console.log(data)
this.accountData = data
}
}
userData= [
{
username:"Nikhil",
age:25,
title:"Developer"
},
{
username: 'Salesforcetroop',
age: 2,
title: 'Youtube channel'
},
{
username: 'Friends',
age: 20,
title: 'Netflix series'
}
]
headers = {
username:"User Name",
age:"Age",
title:"Title"
}
accountHeaders ={
Id:"Record Id",
Name:"Name",
AnnualRevenue:"Annual Revenue",
Industry:"Industry",
Phone:"Phone"
}
downloadUserDetails(){
console.log("download triggered.")
exportCSVFile(this.headers, this.userData, "user detail")
}
downloadAccountData(){
exportCSVFile(this.accountHeaders, this.accountData, "accounts detail")
}
}
csvDemo.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>50.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
- Create Another Lwc component
utils
and convert it into the utility by deleting the html file from the component. - Add the following code to the
utils.js
utils.js
export function exportCSVFile(headers, totalData, fileTitle){
if(!totalData || !totalData.length){
return null
}
const jsonObject = JSON.stringify(totalData)
const result = convertToCSV(jsonObject, headers)
if(result === null) return
const blob = new Blob([result])
const exportedFilename = fileTitle ? fileTitle+'.csv' :'export.csv'
if(navigator.msSaveBlob){
navigator.msSaveBlob(blob, exportedFilename)
} else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)){
const link = window.document.createElement('a')
link.href='data:text/csv;charset=utf-8,' + encodeURI(result);
link.target="_blank"
link.download=exportedFilename
link.click()
} else {
const link = document.createElement("a")
if(link.download !== undefined){
const url = URL.createObjectURL(blob)
link.setAttribute("href", url)
link.setAttribute("download", exportedFilename)
link.style.visibility='hidden'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
}
}
function convertToCSV(objArray, headers){
const columnDelimiter = ','
const lineDelimiter = '\r\n'
const actualHeaderKey = Object.keys(headers)
const headerToShow = Object.values(headers)
let str = ''
str+=headerToShow.join(columnDelimiter)
str+=lineDelimiter
const data = typeof objArray !=='object' ? JSON.parse(objArray):objArray
data.forEach(obj=>{
let line = ''
actualHeaderKey.forEach(key=>{
if(line !=''){
line+=columnDelimiter
}
let strItem = obj[key]+''
line+=strItem? strItem.replace(/,/g, ''):strItem
})
str+=line+lineDelimiter
})
console.log("str", str)
return str
}
- Keep the code of utils.js-meta.xml as it is.
- Create an Apex class
tableController.cls
and add the following code to the file.
tableController.cls
public with sharing class tableController {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts() {
return [SELECT Id, Name, AnnualRevenue, Industry, Phone from Account];
}
}
Final Output
Now place your component to the record page. You will see the following output
on click of download user data local data gets downloaded and on click of download account data data from apex gets donwloaded