Skip to main content

How to Dynamically Generate and Download CSV Files in Salesforce LWC

In plain words: Exporting data to a CSV (Comma Separated Values) file is a frequent business request. Instead of making server-side Apex calls to generate and store files, modern Lightning Web Components (LWC) can bundle raw records into a text file directly in the user's browser, and instantly trigger a local file download using a temporary anchor link.

Allowing users to export data into a clean spreadsheet format is essential for reporting and offline analysis. In Salesforce, you can accomplish this efficiently on the client side using the HTML5 Blob API and JavaScript.

In this guide, we will walk through how to build a lightweight LWC component that converts structured data into a downloadable CSV file instantly.

Step 1: Create the LWC Component

Open your terminal and use the Salesforce CLI to generate your component files:

sf lightning generate component -n csvGenerator -d force-app/main/default/lwc

Step 2: Build the HTML Template

Open csvGenerator.html. We will add a simple, professional button that triggers the export action when clicked.

<template>
    <lightning-card title="Dynamic CSV Exporter" icon-name="standard:file">
        <div class="slds-m-around_medium">
            <p class="slds-m-bottom_medium">Click the button below to download your generated report.</p>
            <lightning-button 
                variant="brand" 
                label="Download CSV" 
                title="Generate and download CSV file"
                onclick={handleGenerateCSV}>
            </lightning-button>
        </div>
    </lightning-card>
</template>

Step 3: Write the JavaScript Controller

Open csvGenerator.js. We will write the logic that formats text into standard CSV rows, packages it into a Blob object, and simulates a browser click to download the file.

import { LightningElement } from 'lwc';

export default class CsvGenerator extends LightningElement {

    handleGenerateCSV() {
        // 1. Sample data rows (In a real app, this would come from an Apex query)
        const sampleRecords = [
            { Id: '001', Name: 'Acme Corp', Industry: 'Manufacturing', Employees: 150 },
            { Id: '002', Name: 'Global Tech', Industry: 'Technology', Employees: 420 },
            { Id: '003', Name: 'Salesforce', Industry: 'Software', Employees: 75000 }
        ];

        // 2. Define CSV Headers
        const headers = ['Record ID', 'Company Name', 'Industry', 'Employee Count'];
        
        // 3. Convert records into CSV string rows
        let csvRows = [];
        csvRows.push(headers.join(',')); // Add header row first

        sampleRecords.forEach(record => {
            const rowValues = [
                record.Id,
                `"${record.Name}"`, // Wrap strings in quotes to handle commas safely
                record.Industry,
                record.Employees
            ];
            csvRows.push(rowValues.join(','));
        });

        // Join all rows with line breaks
        const csvString = csvRows.join('\n');

        // 4. Create a Blob and temporary download link
        const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8;' });
        const filename = 'Account_Export.csv';

        const link = document.createElement('a');
        if (link.download !== undefined) {
            const url = URL.createObjectURL(blob);
            link.setAttribute('href', url);
            link.setAttribute('download', filename);
            link.style.visibility = 'hidden';
            
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}
Developer Trap: Unescaped Commas in Data
If a user's company name is Acme, Inc. and you don't wrap the string in quotation marks ("Acme, Inc."), the comma inside the company name will be interpreted by Excel as a column separator, shifting all subsequent columns out of alignment. Always wrap string values in quotes!
360 Card: Client-Side vs. Server-Side CSV Generation
  • Client-Side (LWC Blob): Instant execution, zero Apex governor limit consumption, and no storage overhead in Salesforce. Perfect for exporting lists currently visible on screen.
  • Server-Side (Apex): Necessary if you are exporting hundreds of thousands of records that exceed browser memory limits, or if the file needs to be automatically attached directly to a Salesforce record.
Core Takeaway: You can generate and download files directly in Salesforce LWC without calling Apex by utilizing the HTML5 Blob API combined with a temporary programmatic anchor link.

Conclusion

Generating CSV files dynamically inside a Lightning Web Component gives your users a fast, responsive data export tool. By handling the file assembly on the client side using standard JavaScript and blobs, you keep your code efficient while delivering an exceptional user experience.

Happy coding!