5

I want to create csv files from lists and send an email attaching them, how to do that in a controller method?

  • Lists of what - SObjects? – Keith C Mar 13 '14 at 9:30
  • @KeithC Yes. Sending email is not problem but how to create csv files from List of SObject is main struggling point for me. – Sanjivani Mar 13 '14 at 9:41
15

Rob's link is interesting and worth considering, though it looks like you have to pull the report data by making HTTPS requests which apart from code involves setting up Remote Site Settings.

Assuming the volume of data is reasonably small (so governor limits don't get hit) below is some simple Apex code that will produce a CSV string that can be adapted to other SObjects (and have its format methods tweaked and added to). You can Google to find other similar code or code that works more generically (is not tied to a specific SObject or set of fields) if that is a requirement.

Documentation like this Creating an Email Attachment explains how to add the resulting data to an email (a file is never needed it can all be done in memory) and Blob.valueOf converts a String to a Blob.

public class Csv {
    public String generate(List<Contact> contacts) {
        String s = line(new String[] {
                format('First Name'),
                format('Last Name'),
                format('Birthdate'),
                format('Email'),
                format('Phone')
                });
        for (Contact c : contacts) {
            s += line(new String[] {
                    format(c.FirstName),
                    format(c.LastName),
                    format(c.Birthdate),
                    format(c.Email),
                    format(c.Phone)
                    });
        }
        return s;
    }
    private String line(String[] cells) {
        return String.join(cells, ',') + '\n';
    }
    private String format(Date d)    {
        return d != null ? '"' + d.format().escapeCsv() + '"' : '""';
    }
    private String format(String s) {
        return s != null ? '"' + s.escapeCsv() + '"' : '""';
    }
    private String format(Decimal d, Integer scale) {
        return d != null ? String.valueOf(d.setScale(scale)) : '';
    }
    private String format(Decimal d) {
        return format(d, 2);
    }
}

A test for it:

@isTest
private class CsvTest {
    @isTest
    static void generate() {
        Contact[] contacts = new Contact[]{
            new Contact(
                    FirstName = 'Jane',
                    LastName = 'Doe'
                    ),
            new Contact(
                    FirstName = 'John',
                    LastName = 'Smith',
                    Birthdate = Date.newInstance(1985, 2, 3),
                    Email = 'abc@def.com',
                    Phone = '222 444 55555'
                    )
        };
        insert contacts;
        String expected = ''
                + '"First Name","Last Name","Birthdate","Email","Phone"\n'
                + '"Jane","Doe","","",""\n'
                + '"John","Smith","2/3/1985","abc@def.com","222 444 55555"\n'
                ;
        System.assertEquals(expected, new Csv().generate(contacts));
    }
}
  • Isn't there a danger with the date.format() converting to the running users timezone? – Phil B May 18 '15 at 17:34
  • @PhilB Nice thing about Apex having a Date type is no timezone issues there. But fair point for DateTime values - care needed over which format method is used. – Keith C May 18 '15 at 17:43
2

I think this link will be useful in pulling the relevant data in .csv format. --- Can report data be accessed programatically?

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.