The website I'm building enables users to book places on events. This is simply a form which creates an entry in a channel containing 2 fields: "related user" and "related event". In the control panel I've written a simple plugin which displays all the entries in that channel exactly the same as the control panel normally would do, but now I can display any fields I want instead of just title and post date.

My client wants to be able to export the entry data from the control panel into Excel (xls or csv). What's the simplest way to do this? I read somewhere about changing http headers to force a download of a file, so can I just force a browser download of a dynamically generated page containing a table of all that entry data?

When I say "force a download" I mean I probably just need a button that says "Export", but it should download the file instead of opening it in the browser.

2 Answers 2


Craft's HttpRequestService has a sendFile method (available via craft()->request->sendFile()).

The 3rd parameter is an optional $options array that accepts key => value pairs. One of those is 'forceDownload' => true and when that is passed in, Craft will set the proper HTTP headers to force the given file to be sent to the browser as a download.

You could do this from inside an action in one of your plugin's controllers. Something like:

public function actionDownloadFile()
    // Grab your file content from wherever you have it stored. Here, it's just hard coded into a string.
    $contents = 'row1column1,row2column2'.PHP_EOL.'row2column1,row2column2'.PHP_EOL;    

    // Call sendFile, giving it the name of the file to send, the contents and tell it to force a download to the browser.
    craft()->request->sendFile('filename.csv', $contents, array('forceDownload' => true));
  • That sounds exactly like what I need Brad, but I have to be honest I'd have no idea how to implement it. I spent 3 days trying to learn how to write Craft Plugins and got nowhere (my brain's fault, not the documentation's). The plugin I've written is literally one template that outputs entries the same way as a front end template would. How would I implement your answer in simple terms? Commented Aug 26, 2014 at 16:14
  • 1
    Updated the answer with some more details.
    – Brad Bell
    Commented Aug 26, 2014 at 17:07
  • I've implemented the above on one of our sites. However it appears to split fields on commas in the title of the entry and not escape them for csv files. I can code for the data to be escaped before it is used in the sendFile function but wanted to check that I wasn't missing something that would automatically escape it or change the delimiter as a param?
    – Lettie
    Commented Oct 26, 2015 at 10:19
  • Brad this is great, but an extension on how to pull all contents from a table and export to CSV would be AWESOME!
    – H2ONOCK
    Commented Jul 5, 2016 at 14:30

For a plugin-based solution, it's possible to create Reports based on arbitrary queries using Sprout Reports. Reports created in Sprout Reports can all be viewed in the same area of the Control Panel. A user can run reports from a simple user interface and export the results as a CSV.

You can create reports that are just a specific query or customizable reports that give the user any number of options to customize the results.

A report based on a Custom SQL query can be created in the interface, or you can create a more customized report via the Custom Reports Data Source API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.