Outputting and saving a csv in PHP - php

I am currently creating and outputting a CSV as follows:
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file.csv');
header("Cache-Control: no-store, no-cache");
$df = fopen('php://output', 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($df, $csvLine);
}
exit;
However, I would like to not only output but also save this file to disk. How can I write $df to a file?
Note Suggestions on improving my generating the CSV are welcome :)

The simplest answer is to write to the file instead of php://output, and then send that file directly to the browser using readfile()
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=file.csv');
header("Cache-Control: no-store, no-cache");
$df = fopen('/path/to/where/you/want/the/file/on/disk.csv', 'w');
fprintf($df, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($df, $csvLine);
}
readfile('/path/to/where/you/want/the/file/on/disk.csv');
exit;

Simply write to two file pointers:
$out = fopen('php://output', 'w');
$file = fopen('somefile.csv');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
foreach ($csvLines as $csvLine) {
fputcsv($out, $csvLine);
fputcsv($file, $csvLine);
}
exit;

Related

Create CSV and Force to Download

I want write a CSV and force to Download it automatically. Bit it only displays the file. My code:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
// open to write
$fp = fopen($fileName, 'w');
// MS-Excel BOM:
fputs($fp, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
// write columns
foreach ($columnNames as $fields) {
fputcsv($fp, $fields, ';');
}
$exportData = array (
array($value1, $value2, $value3)
);
foreach ($exportData as $fields) {
fputcsv($fp, $fields, ';');
}
fclose($fp);
I have tried for hours. Nothing do the job. It will only be displayd.
You can try adding the file to a zip file and asking your visitors to change their settings so that zip files are automatically downloaded.
https://www.tipsandtricks-hq.com/forum/topic/force-a-file-to-download-instead-of-showing-up-in-the-browser

Forcing PHP to download file via browser

I'm currently trying to make a file download in the user's browser but have so far been unable to make it happen.
I've looked at other answers on stackoverflow.com and so far haven't found anything that has solved my problem.
My process is as follows:
I create the filename and filepath, then set headers:
$date = new DateTime();
$currentDateTime = $date->format("Y-m-d H:i:s");
$filename = "{$name}_{$currentDateTime}.csv";
$filepath = $rootfull . "/{$filename}";
// Set headers
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filepath . '"');
header('Content-Length: ' . filesize($filepath));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
I then create the file and start writing to it:
// Write header
fputcsv($output, $header);
fputcsv($output, array()); // Empty line
// Write column names
$column_headers = array_keys(array_flip($columns));
foreach ($data as $row)
{
fputcsv($output, $row);
}
echo readfile($filepath);
die();
The file gets generated and written to the specified location (in this case /var/www/<project>/<filename>.csv without any indication to the user that anything has happened. No download dialog, nothing.
If anyone can spot a problem with my code or my process, please point it out and preferably suggest a better/alternative way of doing it, any help at all is welcome at this point.
If no benefit (poor mans cache) to writing to disk then maybe something like this writing to buffer:
<?php
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="dump_' . date('Ymd') . '.csv"');
header("Pragma: no-cache");
header("Expires: 0");
$this->outputCSV($results);
exit(); //->
public function outputCSV($data, $useKeysForHeaderRow = true)
{
if ($useKeysForHeaderRow) {
array_unshift($data, array_keys(reset($data)));
}
$outputBuffer = fopen("php://output", 'w');
foreach($data as $v) {
fputcsv($outputBuffer, $v);
}
fclose($outputBuffer);
}
?>

Csv truncate 0 when generate php

I have the following code :
header('Content-Encoding: UTF-8');
header("Content-Type:application/csv;charset=UTF-8");
header('Content-Disposition: attachement; filename="' . $sFileName . '";');
header("Pragma: no-cache");
header("Expires: 0");
header("Refresh:0");
echo "\xEF\xBB\xBF";
$output = fopen('php://output', 'w');
fwrite($output, "sep=;\n");
fputcsv($output, array('1','2','3'), ";");
foreach ($aExport as $value) {
fputcsv($output, $value, ";");
}
fpassthru($output);
fclose($output);
exit;
For example if I have multiples 0000 witch need to be put in the first column it truncate the rest and it put only one zero. I dont'n understand why. Can you help me please ? Thx in advance

Read and write using fgetcsv and fputcsv

I have a 3rd party source from where I am getting "csv" file. I wrote it inside a quote because it says it's a csv file but basically it's not.
So I am taking that main source file then reading and putting the data in a "PROPER" csv file.
The read and write is fine but the problem is when it saves the properly quoted data is writing on the script file itself.For example if the my php file name is "fixcsv.php" then I am getting the downloadable file as "fixcsv.php".
My code
$headings = array('HID');
$handle = fopen("MonC1.csv", "r");
$data = fgetcsv($handle, 0, ";",'"');
$fh = fopen('php://output', 'w');
ob_start();
fputcsv($fh, $headings);
// Loop over the * to export
if (! empty($data)) {
foreach ($data as $item) {
// echo $item;
fputcsv($fh, array($item));
}
}
$string = ob_get_clean();
$filename = 'csv_' . date('Ymd') .'_' . date('His');
// Output CSV-specific headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment filename=\"$filename.csv\";" );
header("Content-Transfer-Encoding: binary");
exit($string);
Any help is highly appreciated. Thanks in advance.
Your Content-Disposition has a semi-colon in the wrong place (per the spec). Should be:
header("Content-Disposition: attachment; filename=\"$filename.csv\" );

php://output results in empty file

I have a Wordpress theme template file in use by a page. The template queries the db for an array and then attempts to output the result to a csv file. No output to the browser is expected. Here is code:
/***
* Output an array to a CSV file
*/
function download_csv_results($results, $name = NULL)
{
if( ! $name)
{
$name = md5(uniqid() . microtime(TRUE) . mt_rand()). '.csv';
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='. $name);
header('Pragma: no-cache');
header("Expires: 0");
$outstream = fopen("php://output", "w");
foreach($results as $result)
{
fputcsv($outstream, $result);
}
fclose($outstream);
}
The file is written to the user's downloads directory as expected, but it is empty. I've debugged to verify there is a result of 117 elements. The loop above is executing. It's as though the output buffer is not being flushed or is being cleared by Wordpress.
Could you try to use :
$outstream = fopen("php://output", "a");
instead of :
$outstream = fopen("php://output", "w");

Categories