Jump to:

23377 Posts in 18296 Topics by 2867 members

General Questions

SilverStripe Forums » General Questions » Outputting a CSV (not from DB table)

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

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

Page: 1
Go to End
Author Topic: 1273 Views
  • zenmonkey
    Avatar
    Community Member
    527 Posts

    Outputting a CSV (not from DB table) Link to this post

    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

  • simon_w
    Avatar
    Forum Moderator
    471 Posts

    Re: Outputting a CSV (not from DB table) Link to this post

    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

    1273 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.