15

I am trying to create a button that will force a CSV file download but for some reason I am not able to get it working. This is the code that I have:

public function export_to_csv($result) {

$shtml="";

for ($i=0; $i<count($result); $i++){

$shtml = $shtml.$result[$i]["order_number"]. "," .$result[$i]["first_name"]. "," .$result[$i]["middle_name"]. "," .$result[$i]["last_name"]. "," .$result[$i]["email"]. "," .$result[$i]["shipment_name"]. "," .$result[$i]["payment_name"]. "," .$result[$i]["created_on"]. "," .$result[$i]["modified_on"]. "," .$result[$i]["order_status"]. "," .$result[$i]["order_total"]. "," .$result[$i]["virtuemart_order_id"]. "\n";

}

Header('Content-Description: File Transfer');
Header('Content-Type: application/force-download');
Header('Content-Disposition: attachment; filename=pedidos.csv');

}

The $result variable comes from here:

public function get_orders_k() {

$db=JFactory::getDBO();

    $query = " select o.order_number, o.virtuemart_order_id, o.order_total, o.order_status, o.created_on, o.modified_on, u.first_name,u.middle_name,u.last_name "
    .',u.email, pm.payment_name, vsxlang.shipment_name ' .
    $from = $this->getOrdersListQuery();

$db->setQuery($query);

$result=$db->loadAssocList();

    if ( $result > 0 )
    {
        $datos = VirtueMartModelKiala::export_to_csv($result);

    }else return 0;
}

Im not sure even where to start looking. I have look over the internet on various ways of doing this and tried all of them and still can't manage to get it working. Please help me out!

-Thanks

Victor York
  • 1,621
  • 4
  • 20
  • 55
  • 1
    So what happens instead? Error messages? Does the file display in the browser instead? Does the file download but is broken? – JJJ Jun 24 '13 at 06:54
  • The file doesnt download and when I use Firefox for example and use the Firebug to see what the button does I get this error: 500 Internal Server Error – Victor York Jun 24 '13 at 07:13

3 Answers3

42

Put this code below your loop.

header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="pedidos.csv"');

echo $shtml;

How did you find out the content type application/force-download? I've never heard of it. The proper MIME type for CSV is text/csv

You can find more examples how to use header function in php manual

You need also display $shtml you didn't do it in your code.

sdgluck
  • 24,894
  • 8
  • 75
  • 90
Robert
  • 19,800
  • 5
  • 55
  • 85
  • You mean put the headers right after the for or after the $shtml = $shtml.$result[$i].. ? -Thanks – Victor York Jun 24 '13 at 07:18
  • 3
    Headers should be sent before any other data is sent to browser. Even white character can break the script. – Robert Jun 24 '13 at 07:21
5

Well. you may try this, it'll work if your result is not empty

public function export_to_csv($result)
{
    if(!$result) return false;
    ob_end_clean();
    header( 'Content-Type: text/csv' );
    header( 'Content-Disposition: attachment;filename=pedidos.csv');
    $fp = fopen('php://output', 'w');
    $headrow = $result[0];
    fputcsv($fp, array_keys($headrow));
    foreach ($result as $data) {
        fputcsv($fp, $data);
    }
    fclose($fp);
    $contLength = ob_get_length();
    header( 'Content-Length: '.$contLength);
}
The Alpha
  • 143,660
  • 29
  • 287
  • 307
3

you need to echo your content after the header

header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename=pedidos.csv');
echo $shtml
Volomike
  • 23,743
  • 21
  • 113
  • 209
DevZer0
  • 13,433
  • 7
  • 27
  • 51