Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Direcly outputting to a CSV from an array without saving to a CSV file

Tags:

arrays

file

php

csv

I am looking for a simple way to take an array, turn it into a CSV and have a user be able to download the CSV, all without saving the CSV to the server.

like image 552
Lee Avatar asked May 15 '12 18:05

Lee


People also ask

How do I export a CSV file from Ajax?

ajax({ url: 'exportCSV. php', type: 'post', dataType: 'html', data: { Year: $('input[name="exportYear"]'). val() }, success: function(data) { var result = data console. log(result); } }); });


2 Answers

$array = [
    ['name', 'email'],
    ['Doe, John', 'johndoe@foo'],
    ['Jane Doe', 'janedoe@foo'],
    ['Ron "SuperFly" O\'Neal', 'supafly@foo'],

];
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
$fp = fopen('php://output', 'w'); // or use php://stdout
foreach ($array as $row) {
    fputcsv($fp, $row);
}

see fputcsv()

The benefit of using fputcsv is it will handle escaping and enclosing of fields for you, ensuring valid, rugged output that will never break even if your columns values happen to contain csv control characters such as commas, quotes, newline characters etc... If you don't take care to handle control characters robustly, and instead take a common shortcut such as using implode(',', $row) your (low quality) code will produce broken csv output.

Unfortunately, fputcsv cant output to a string, only to a stream, so I write to php's output stream via php://output which is equivalent to echo'ing it out. Note that just like output via echo, it will go through php's output buffer mechanism, and that includes any possible output handlers, such as ob_gzhandler or customer output buffer callback functions that may modify the output. If you wish to bypass the output buffer, you can instead write directly to php://stdout.

You could also write to php://memory, php://temp, or a file if you need to access the csv file contents as a string before outputting it.

$fp = fopen('php://memory', 'w+'); // or php://temp
foreach ($array as $row) {
    fputcsv($fp, $row);
}

// Read it back into a string, if desired.
// Rewind the stream to start.
fseek($fp, 0);
// Read the entire stream back to string.
$csvContents = stream_get_contents($fp);

info on stream wrappers http://www.php.net/manual/en/wrappers.php.php

like image 80
goat Avatar answered Sep 30 '22 17:09

goat


header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "name,city,street\n";

Sometimes it's better to use

header("Content-Type: application/octet-stream");

for IE...

like image 41
powtac Avatar answered Sep 30 '22 17:09

powtac