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.

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   1919 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