So I'm trying to find a way to download a report from salesforce programmatically, to a local machine.

so, I've found the XMLStreamWriter class, and am writing the XML just fine... I'm just wondering if it is possible to save this XML string to a file and then downloading it. Has anyone done something similar to this before? Any pointers/examples would be awesome!

2 Answers 2


I've worked on this multiple times recently for a client who needs to output various fixed width file formats - not quite the same situation as you, but once you've got yourself down to a string it's a piece of cake.

Check out this Gist for some boilerplate to get you going: https://gist.github.com/Oblongmana/78c2807c91903bfe22b9

So say you have a String called 'txt':

    Blob txtBlob = Blob.valueOf(txt); //Convert it to a blob

    Attachment attach = new Attachment(); //Make an attachment
    attach.Name ='text.xml';  
    attach.Body = txtBlob;
    attach.ContentType= 'application/xml'; //Signal what the file's MIME type is
    attach.ParentID = [parentIDGoesHere];
    insert attach;

You can then serve this file up like so:

    <a href="/servlet/servlet.FileDownload?file=' + attach.ID +'">Download me!</a>
  • How do you know what should be used for the parentID? For example, I'm querying data from an sObject and writing that data to a csv that will need to be downloaded. I tried using the id shown in the url of the layout page for the object, but I got the error Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, Parent ID: id value of incorrect type. May 1, 2018 at 18:47
  • @loremIpsum1771 What are you trying to attach it to? The parentID is the ID of the object which the file will sit against. So any object which has Notes and Attachments enabled can be the parent
    – James Hill
    May 3, 2018 at 8:50
  • I was trying to attach it to a custom object so I was using the object id as the parent id. May 3, 2018 at 13:47
  • Double check that the custom object has notes and attachments turned on, that's the only source of this error I've encountered before, hopefully that's it!
    – James Hill
    May 4, 2018 at 0:28

Although the above answer is the better solution IMO (and I have upvoted), this is an alternative solution I helped create a few years back. The scenario was similar, a fixed-width file needed to be generated and extracted twice a day.

The solution was to build a custom object where each record stored a line of the file - seems odd but the file could be of varying sizes and there were different 'types' of line so the ordering was important too.

Twice a day a batch file (it had to be a Windows box unfortunately) would fire up dataloader to pull out the lines in the correct order and then it'd use a command line substitution tool (similar to sed) to do a bit of cleanup (removing the CSV parts) before moving the file into another directory where it was needed.

The batch would then use the success log to update the downloaded records setting a checkbox to true, and those would subsequently be deleted from the system by a scheduled batch apex job.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .