Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Outputting a CSV (not from DB table)

Go to End

2 Posts   1953 Views


Community Member, 545 Posts

1 January 2011 at 9:45am

I'm trying to create a csv report that calucualtes totals to be downloaded. I can write the file I'm just not sure how to get the button to push the file to the browser.

See bellow:

function downloadAirmilesReport(){
		$trainers = DataObject::get("Member", "MemberType = 'Trainer' OR MemberType = 'Supervisor' OR MemberType = 'Manager'");
		//CSV HeaderRow
		$report = array(array("Offer","Report Date", "Collector Number", "Amount"));
		//Open File
		$fp = fopen('AirmilesReport.csv', 'w');
		foreach ($trainers as $trainer) {
			$id = $trainer->ID;
			$memberType = $trainer->MemberType;
			switch ($memberType) {
				case "Trainer":
					$clients = DataObject::get("Client", "AirMilesApproved = 1 AND TrainerID = '$id'");
					$totalClients = $clients->count();
					$totalPoints = $totalClients * 20;
				case "Supervisor":
					$clients = DataObject::get("Client", "AirMilesApproved = 1 AND SupervisorID = '$id'");
					$totalClients = $clients->count();
					$totalPoints = $totalClients * 15;
				case "Manager":
					$clients = DataObject::get("Client", "AirMilesApproved = 1 AND ManagerID = '$id'");
					$totalClients = $clients->count();
					$totalPoints = $totalClients * 5;
			if ($clients){
				//Add Row to CSV
				array_push($report,array("xxx", "01.01.01",$trainer->AirmilesID, $totalPoints)) ;
			echo "<br>";
		foreach ($report as $line){
			fputcsv($fp, $line);
		return $fp;



Community Member, 473 Posts

1 January 2011 at 10:41am

Since you'll need to read the contents of the file back, I'd use a temp file, rather than one with a constant name. So, instead of fopen():

$fp = tmpfile();

Then, instead of your current call to fclose():

$contents = '';
fseek($fp, 0);
while(!feof($fp)) $contents .= fread($fp, 8192);

return SS_HTTPRequest::send_file($contents, 'AirmilesReport.csv', 'text/csv');

What this does is gets PHP to create a temporary file, which you write your CSV data to, then it returns to the start of the file, reads the contents of it into $contents, closes the file (which also gets PHP to delete it, as it was created with tmpfile()), then gets SilverStripe to force the browser to download $contents as AirmilesReport.csv with mime-type text/csv