I am trying to create a CSV file that can be downloaded by the user and not have the data permanently saved on the server.
I am using mySQL and PHP for this page. I get the data in the right format to show up ("echo") on the webpage but not able to get the file to generate/download...maybe I am missing something or looking in the wrong place but any help would be great!
I have been trying several script both my own and others I have found but the one I currently have is below:
$file = 'export';
$colresult = mysql_query("SHOW COLUMNS FROM ".$tbl_name."");
if (mysql_num_rows($colresult) > 0) {
while ($row = mysql_fetch_assoc($colresult)){
$csv_output .= $row['Field'].", "; $i++; } } $csv_output .= "\n";
$csvresult = mysql_query($sql);
while ($rowr = mysql_fetch_row($csvresult)) {
for ($j=0;$j<$i;$j++) { $csv_output .= $rowr[$j].", ";
}
$csv_output .= "\n"; }
$filename = $file."_".date("Y-m-d_H-i",time()).".csv";
header("Content-type: application/csv");
header("Content-disposition: attachment;filename=".$filename.".csv");
readfile("../documents/csv/".$filename.".csv");
$fp = fopen($filename, 'w');
foreach($csvret as $csvret){
fputcsv($fp, $csvret);
}
print $csv_output;
print $filename;
Thanks!
You'll need to pass some headers to force the web browser to recognize the file as "downloadable":
<?php
header('Content-Description: File Transfer');
header("Content-Type: application/csv");
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit;
Simply add that code in place of:
print $csv_output;
print $filename;
Related
The task is to create a controller to count the number of file downloads. It also must be able to account for failed or cancelled downloads. I was wondering if anyone knew the best way to go about accomplishing this.
$file = $_GET['download'];
if (ob_get_level()) {
ob_end_clean();
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
return filesize($file);`
$size = filesize($file);
Then if the number of bytes given is approximately equal to the file size:
if ( $size < given bytes) {
$handle = fopen("counter.txt", "r");
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$buffer=$buffer+1;
}
fclose($handle);
$fp = fopen("counter.txt", "w");
$test = fwrite( $fp, $buffer);
fclose($fp);
}
How to know the number of bytes sent by server to the user after clicking on link?
I'll start with what should be comments:
You've tagged this as javascript, but your quesiotn appears to have nothing to do with javascript. Please don't do that.
I assume you are aware of the gaping security hole exposed by your script / that you are not concerned about it.
Your handling of output buffering is wrong.
return filesize($file);
What is this line of code supposed to do?
header('Expires: 0');
no.
header('Pragma: public');
again, no.
As to your question - its all covered in the manual:
<?php
ignore_user_abort(1);
$file = $_GET['download'];
if (!is_readable($file)) {
die "No such file";
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0; must-revalidate');
header('Content-Length: ' . filesize($file));
$count=0;
$ih=fopen($file, 'r');
while (CONNECTION_NORMAL==connection_status() && !feof($ih)) {
print fgets($ih, 4096);
}
log_completion(feof($ih));
BTW: This does not give an accurate record if the file was downloaded - you can only tell if the content has left PHP land.
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);
}
?>
I am having a problem that I just can't solve and I'm going madness with this!
Basically I have to export a csv file. The site is obviously running on a server, and the idea is that onclick the file is generated and automatically downloaded.
Everything is just fine, however, the file is being download to the server directory instead of the local user machine. I just can't make it.
What is wrong? Thank you very much!
if(!isset($crm_contas))
$crm_contas = new crm_contas;
$resultGetValues = $crm_contas->getExportContas($filtros, $idsToSend);
// filename for download
$filename = "ContasExportadas" . date('Ymd') . ".csv";
$output = fopen($filename, 'w');
foreach($resultGetValues as $row) {
fputcsv($output, $row);
}
fclose($output);
$filename = realpath($filename);
$fp = #fopen($filename, 'rb');
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename='.$filename);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($filename));
} else {
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename='.$filename);
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($filename));
}
fpassthru($fp);
fclose($fp);`
--> This is the action that calls the code above.
echo "<a href='#' onclick='changeFormAction(\"form_list\",\"".$CONF['HOME']."/contas/index.php?view=export\");document.form_list.submit();changeFormAction(\"form_list\",pesquisa);'><img src='".$CONF['HOME']."/images/structure/excel.png' alt='Exportar' title='Exportar'></a>";
Meanwhile, I noticed that error_log is writting down this lines when I try do download.
[21-Apr-2016 16:23:44 UTC] PHP Warning: Module 'imap' already loaded in Unknown on line 0
I had created a website using php. In that website,I want to create a report like thing,which involves transferring details from one table to an excel sheet which is downloadable.Is there any way to do this work? Please help me to find the solution.
Thank you.
You can fetch all rows from the database and use fputcsv function to put it as csv
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=export.csv");
header("Content-Transfer-Encoding: binary");
$csvHandler = fopen("php://output", 'w');
while ($row = mysql_fetch_array ($res))
{
fputcsv($csvHandler, $row);
}
You can use PHPExcel for generating data
and a simple function for file download:
function show_download($data, $name, $type = "unknown/unknown") {
header('Content-Type: ' . $type);
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Content-Length: ' . strlen($data));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
print $data;
exit();
}
You can create a script that exports a CSV file like this :
header('Content-type: text/csv');
header("Content-Disposition: attachment; filename=clients_" . date("Ymd") . ".csv");
//Open PHP output stream
$fd = fopen('php://output', 'w');
$tab = array();
//get your results from your database
foreach ($results as $res)
$tab[] = array($res->Client_Name, $res->Client_Email);
foreach ($tab as $val)
fputcsv($fd, $val);
fclose($fd);
Or possible for users to download the file without saving it on the server?
I am getting data from the database, and I want to save them .doc (MS Word) file.
if(isset($_POST['save']))
{
$file = "new_file2.doc";
$stringData = "Text text text text...."; //This data put in new Word file
$fh = fopen($file, 'w');
fwrite($fh, $stringData);
fclose($fh);
header('Content-Description: File Transfer');
header('Content-type: application/msword');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
unlink($file);
exit;
}
How should the code look like without this:
" $fh = fopen($file, 'w');
fwrite($fh, $stringData);
fclose($fh);"
and this "unlink($file);"
I hope to understand what I need
enter code here
You just need to output headers and then the content:
header(...);
echo $stringData;
No need to play with any files.
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment;
filename=\"$_fileName\"");
ob_clean();
readfile($_filePath);