1

I have a requirement to export data from an Aura component to a CSV. My solution is working until I hit around 3k records at that point the CSV no longer seems to contain all the data. At 6k records, I get a "download failed Network Error" message. And at around 7k, the browser will time out.

Is there a way to implement this to deal with larger data volumes? Up to 10k records or so?

I used a solution I found here and was also mention in another thread on Stack Exchange.

Here is my controller

handleExport: function(component, event, helper){

        var contactList = component.get('v.completeResults');
        var csv = helper.convertListToCSV(component, contactList);

        var hiddenElement = document.createElement('a');
        hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
        hiddenElement.target = '_self'; //
        hiddenElement.download = 'EmailSendList.csv';  // CSV file Name* you can change it.[only name not .csv]
        document.body.appendChild(hiddenElement); // Required for FireFox browser
        hiddenElement.click(); // using click() js function to download csv file

    }

Here is my helper

convertListToCSV: function (component, list) {

        var csvStringResult, counter, keys, columnDivider, lineDivider;
        var csvHeader = '*** Changes to CSV Will Not be Saved Back To Event App *** ';

        // check if "list" parameter is null, then return from function
        if (list == null || !list.length) {
            return null;
        }
        // store ,[comma] in columnDivider variabel for sparate CSV values and
        // for start next line use '\n' [new line] in lineDivider varaible
        columnDivider = ',';
        lineDivider =  '\n';

        // in the keys valirable store fields API Names as a key
        // this labels use in CSV file header
        keys = ['Delivery_Name', 'InformalSalutation', 'Last_Name', 'Email1', 'Inviter_Name', 'GalileoId', 'Relationship_Type',
                'Age', 'BAOffice', 'MarketingRestrictions', 'OptOut', 'PrimaryContact', 'BillingCity', 'BillingState',
                'Company', 'BA_Relationship', 'LastModifiedName', 'LastModifiedDate', 'LastModifiedDate', 'contactId'];

        csvStringResult = csvHeader + lineDivider;
        csvStringResult += keys.join(columnDivider);
        csvStringResult += lineDivider;

        for(var i=0; i < list.length; i++){
            counter = 0;

            for(var sTempkey in keys) {
                var skey = keys[sTempkey] ;

                // add , [comma] after every String value,. [except first]
                if(counter > 0){
                    csvStringResult += columnDivider;
                }
                csvStringResult += '"'+ list[i][skey]+'"';

                counter++;

            } // inner for loop close
            csvStringResult += lineDivider;
        }// outer main for loop close

        // return the CSV format String
        return csvStringResult;
    }
1

I have used Sheet.js and FileSaver.js to implements downloads.

I think you can use your code with FileSave.js (https://github.com/eligrey/FileSaver.js/).

For FileSave to work in Aura components, you have to add the line:

window.saveAs = saveAs;

after the definition of the variable "saveAs" (after line 275 in FileSaver.js). Because imported libraries in Aura are encapsulated/something like that. I think it's a locker security thing.

1

There is a limit to number of characters a string variable can store in javascript. And if you are creating a string for records in thousands and that also more than 10 fields, it is likely to fail. And another reason could be execution time. If a file has 10K records, it will take a lot of time to create string for those records and it is not a good solution to do this much big operation in javascript.

Alternatively, you can use visualforce page and render that visualforce page as csv. You just need to pass list of records(Or query string) to apex controller and from there you can send list to visualforce page to render it on visualforce page.

To pass data or query string from lightning to vf page, you can use postMessage(). Check below link for communication between lightning and vf page.

let me know if this helps.

https://developer.salesforce.com/blogs/developer-relations/2017/01/lightning-visualforce-communication.html

There are some limitations with excel as well. Check out below link.

Visualforce to excel for more than 20K records

0

As a follow up this looks like it could just be a browser or a machine issue. I am running a Macbook pro and the file downloaded fine while running Safari. But failed in Firefox, chrome and MS Edge.

It looks like there were two issues at play here. The time complexity in the nested for loop. At around 150k iterations Chrome started to fire off alerts to the user about killing an unresponsive page. Note that Safari did not and handled the operation.

Two Chrome limits the size of a download that can be attached to a tag to 2 MB.

https://stackoverflow.com/questions/38781968/problems-downloading-big-filemax-15-mb-on-google-chrome

3
  • So you found root cause for that? Jan 20 '20 at 6:04
  • No, I did not The download fails in Chrome and Firefox but works in Safari. I think it will need a redesign. Do you think it is better to call a Visualforce page that renders to a csv? Or to generate the CSV string server-side in Apex and pass that to the Component? I will need to be able to export up to 7 or 8 thousand records. Jan 20 '20 at 17:02
  • I would suggest to send query string only from lightning to VF and then render that as csv. But has also some limitations. I have added a link in my solution. Please check that. And let me know if this helps. Jan 21 '20 at 7:50

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.