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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

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   2240 Views

Avatar
zenmonkey

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;
					break;
				case "Supervisor":
					$clients = DataObject::get("Client", "AirMilesApproved = 1 AND SupervisorID = '$id'");
					$totalClients = $clients->count();
					$totalPoints = $totalClients * 15;
					break;
				case "Manager":
					$clients = DataObject::get("Client", "AirMilesApproved = 1 AND ManagerID = '$id'");
					$totalClients = $clients->count();
					$totalPoints = $totalClients * 5;
					break;
			}
			
			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);
		}
	
		
		fclose($fp);
		
		return $fp;
	}

Thanks

Avatar
(deleted)

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);
fclose($fp);

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