I am posting a HTML table data as json to server side using jquery $.post for writing the whole table data to csv file. but this is not outputting csv as downloadable for user.
I want to pop up the csv file (which normally happens when we download a file. you know the SAVE or OPEN box for csv)
Client side code
//selectedData is having the data as json
$.post('ajax/csv_download.php', {
selectedData: JSON.stringify(selectedData)
}, function(html){ });
Server Side code
global $fh;
$fh = #fopen( 'php://output', 'w' );
$post_data = json_decode($_POST['selectedData']);
foreach ($post_data as $arr)
{
$val1 = $arr->val1 ;
$val2 = $arr->val2 ;
$val3 = $arr->val3 ;
$val4 = $arr->val4 ;
$val5 = $arr->val5 ;
$out = array($val1,$val2,$val3,$val4,$val5);
fputcsv($fh, $out);
}
Sounds like you want to write the contents of the CSV file back to the browser after setting the 'Content-Type' to 'text/plain' in php. Depending how the web browser is configured, it will prompt the user to Save/Open the file.
<?php
$content="name,age,height,weight,gender";
$file="persons.csv";
header("Content-Type: text/plain");
header("Content-disposition: attachment; filename=$file");
header("Content-Transfer-Encoding: binary");
header("Pragma: no-cache");
header("Expires: 0");
echo "$content";
?>
Related
I'm trying to input data from csv to a php array, do some calculations and sort the data then write the new output back into csv from the array ready to go from a download button.
Here's what I've got:
f(isset($_POST["download_csv"])){
$fileName = 'csv-report.csv';
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$fileName}");
header("Expires: 0");
header("Pragma: public");
$fh = #fopen( 'php://output', 'w' );
foreach ( $table as $subids => $values ) {
// Put the data into the stream
fputcsv($fh, $values);
}
// Close the file
fclose($fh);
// Make sure nothing else is sent, our file is done
exit;
}
For some reason, it's giving me code in the csv file that downloads and no values. It's confusing because when I use just this part written this way to write to a csv file in the root directory it works just fine and gives expected output:
$fh = #fopen( 'csv-report.csv', 'w' );
foreach ( $table as $subids => $values ) {
// Put the data into the stream
fputcsv($fh, $values);
}
// Close the file
fclose($fh);
Any help would be greatly appreciated
EDIT1:
this is what I mean by its giving me code in the csv output instead of the array values. When I remove the post check it's giving me the values properly but it's now in the middle of a bunch of html.
Summary
I am trying to use fread (or readfile) function (PHP) to get the output result of another PHP page. For example, I want to read (or even download as another file to my PC) the output result of the page “add.php?a=1&b=4”. Below is the PHP codes.
Code
read.php
<?php
$filename = "add.php?a=1&b=4";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
echo $contents; //I hope it can output “5” (the output result of the page “add.php?a=1&b=4”)
fclose($handle);
?>
add.php
<?php
echo $_GET["a"]+$_GET["b"];
?>
Below is the example of the readfile function. I want to download the output result of the page “add.php?a=1&b=4” as the file "result.txt". But it doesn't work either.
readfile.php
<?php
header("Content-type:application");
header("Content-Disposition: attachment; filename=result.txt");
readfile("add.php?a=1&b=4");
?>
How can I modify it?
If you want to read the web output, you need to read it through the HTTP server.
<?php
header("Content-type:application");
header("Content-Disposition: attachment; filename=result.txt");
echo file_get_contents("http://yourserver.example.com/add.php?a=1&b=4");
$url = "[absolute url]/add.php?a=1&b=4";
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"result.txt\"");
readfile($url);
I am creating a web app in my company. The user can click on a button and an csv is created with MySQL data.
So far so god.
In jquery, when the user clicks the button it redirect to:
document.location.href = '/SDR/SDRJSON.php?type=' + id;
On PHP the csv file is created:
I connect to the database and create a the csv file:
while($row = $stmt->fetch(PDO::FETCH_NUM))
{
array_push($csv, $row);
}
$fp = fopen('file.csv', 'w');
foreach ($csv as $row) {
fputcsv($fp, $row, ';');
}
$FileName = 'PEW_'.$CountryCode;
fclose($fp);
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header("Content-Disposition: attachment; filename='".$FileName."'.csv");
header("Pragma: public");
header("Expires: 0");
echo "\xEF\xBB\xBF"; // UTF-8 BOM
readfile('file.csv');
On the page where the button is, the user clicks there and the page starts waiting for the server and then the csv file starts downloading.
For small files is ok, because it is instantaneous. But for larger files it takes like 10 / 15 seconds. Is it possible to show a message while the page waits for the server?
I don't Think PHP can echo while the csv is being made ... What you could do is split the "Document Formation" and "Document Download" into two parts.
Let Ajax Make a query for the CSV to be made . And when that has been completed the PHP (Document Formation) will echo the Path of the File.
Then After that You can use document.location.href to Newly Created File.
I ll give the code
ajax-code
$('#sample-button').click(function(){
$.ajax({
url : '/SDR/SDRJSON.php?type=' + id,
success : function(data){
if(data.url)
{
var urlToDownload = data.url;
alert("File is ready for download");
document.location.href = "http://www.domain.com/file/path/"+data.url;
// Make sure data.url has the full path or append the data.url
// with some strings to make sure the full path is reflected
// into document.location.href ...
}
else
{
alert("Something went wrong");
}
}
});
alert("CSV is being prepared Please wait... ");
});
documentFormation.php
while($row = $stmt->fetch(PDO::FETCH_NUM))
{
array_push($csv, $row);
}
$FileName = 'PEW_'.$CountryCode;
$fp = fopen($FileName, 'w');
foreach ($csv as $row) {
fputcsv($fp, $row, ';');
}
fclose($fp);
$response = array();
$response['url'] = $FileName;
echo json_encode($response); // You can handle rest of the cases where to display errors (if you have any)
// Your DocumentFormation PHP Ends here. No need for header() or readFile.
If you dont want the file to stay on server , Edit the document href to This PHP passing 'path' as the parameter
document.location.href = "documentDownload.php?path="+data.url;
documentDownload.php
$path = $_GET['path'];
$filename = end(explode("/" , $path));
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
//Assuming $filename is like 'xyz.csv'
header("Content-Disposition: attachment; filename='".$filename);
header("Pragma: public");
header("Expires: 0");
echo "\xEF\xBB\xBF"; // UTF-8 BOM
// Reading file contents
readfile('Relative Path to File'.$path);
// Deleting after Read
unlink('Relative Path to File'.$path); // To Delete right after reading
I'm trying to get an export to CSV script to download to the server when run as a cronjob but also still work via web.
When I run the script from web it forces a CSV to download which is great, however when I run it on the server (CentOS Server) it just echos the file contents instead.
I need it to download the file into the area defined in the cronjob.
//OK lets export
include("config.php");
$table = "data";
$filename = "Export_" . date("Y-m-d_H-i");
header("Content-type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=" . $filename . ".csv");
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('artist', 'title', 'presenter', 'timeplayed'));
// fetch the data
mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db('prs');
$rows = mysql_query('SELECT * FROM '.$table.' WHERE timeplayed >= NOW() - INTERVAL 24 HOUR ORDER BY id DESC');
if($rows === FALSE)
{
die(mysql_error());
}
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);
Anyone with any other ideas?
See the manual
php://output is a write-only stream that allows you to write to the output buffer mechanism
in the same way as print and echo.
That really says it all.
So when you run this from a browser the standard output mechanism is send it to the browser as that is what echo or print would do. But in PHP CLI mode it sends the output to the terminal.
Answer is change this line from
$output = fopen('php://output', 'w');
to
$output = fopen($filename, 'w');
You then just have to decide if you are running through the browser or the CLI(cron job) and here is a suggestion
if ( php_sapi_name() !== 'cli' ) {
header("Content-type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=" . $filename . ".csv");
readfile($filename);
}
You are going to have to check what your system reports using php_sapi_name() just to be sure you are testing for the right condition.
I am creating a csv file from nested array and it works fine with a download link to the csv file in the localhost, but on live host it won't download. This is what is in my php file:
The headers declared:
/**
* Declare headers for CSV
*/
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=registration.csv");
header("Pragma: no-cache");
header("Expires: 0");
The Function that outputs the csv file:
/**
* Function will output the scsv file
* #param the csv $data in nested array form array(array("","",""),array("",""...)...)
*/
function outputCSV($data) {
$outstream = fopen("php://output", "w");
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals); // add parameters if you want
}
array_walk($data, "__outputCSV", $outstream);
fclose($outstream);
}
The link that I used in local:
Download CSV
Won't work on Live site. Instead of downloading it just takes me to the csv.php page and outputs the array in a string like this.
...ID,"Coach One","Coach Two",Work,Cell,Email,...
Try hardcoding the csv into the code. Replace these lines with the ones you have to see if your data being passed has bad characters. Maybe specifying the charset will help.
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
fputcsv($output, array('Column 1', 'Column 2', 'Column 3'));
As described here:
http://code.stephenmorley.org/php/creating-downloadable-csv-files/
I'm not setup to really debug your code. You can try this though if you like. I know it works.
$out = fopen("php://temp", 'r+');
while (($row = $res->fetch(Zend_Db::FETCH_NUM)) != false) {
fputcsv($out, $row, ',', '"');
}
rewind($out);
$csv = stream_get_contents($out);
header("Content-Type: application/csv;");
header("Content-Disposition: attachment; filename=\"foo.csv\"");
header("Pragma: no-cache");
header("Expires: 0");
echo $csv;
exit(0);
Adjust the loop as needed to iterate on your results.