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
Related
Could someone help me with this problem?
I have following function
public function exportcsv(){
//echo 'hi'; exit();
// file name
$filename = 'blocked_users_'.date('Y-m-d').'.csv';
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/csv; ");
// get data
$user_data = $this->Common_model->get_users_for_csv();
// file creation
$file = fopen($filename, 'w');
$header = array("full_name", "phone", "email", "payment_method", "delivery_address", "delivery_city", "timestamp");
fputcsv($file, $header);
foreach ($user_data as $key=>$line){
fputcsv($file,$line);
}
fclose($file);
exit;
}
File it's generated 2 times, one, on server root second it's downloaded to disk, but on server root file it's ok with headers and content, the second one which is downloaded on disk it's empty.
I am trying to export and download a csv file through php. I have done exactly what was suggested in Export to CSV via PHP
I can see my array dump in the response but the csv file is just not downloading. Please Help.
Here is my code:
function download_send_headers($filename) {
// disable caching
$now = gmdate("D, d M Y H:i:s");
header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
header("Last-Modified: {$now} GMT");
// force download
Header('Content-Description: File Transfer');
header("Content-Type: application/force-download");
// header("Content-Type: application/octet-stream");
// header("Content-Type: application/download");
// disposition / encoding on response body
header("Content-Disposition: attachment;filename={$filename}");
header("Content-Transfer-Encoding: binary");
}
function array2csv(array &$array)
{
// if (count($array) == 0) {
// return null;
// }
ob_start();
$df = fopen("php://output", 'w');
fputcsv($df, array_keys(reset($array)));
foreach ($array as $row) {
fputcsv($df, $row);
}
fclose($df);
return ob_get_clean();
}
Here is how im using it:
download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo array2csv($modsucc);
die();
This is javascript function:
function exporttocsv(filter){
var fd = new FormData();
fd.append('filter', filter);
fd.append("form", "export_to_csv");
$.ajax({
url: getBaseURL()+'assets/handler/OrderManagementHandler.php',
type: 'POST',
data: fd,
enctype: 'multipart/form-data',
processData: false,
contentType: false,
})
.done(function(res) {
})
.fail(function() {
});
}
Handler:
case 'export_to_csv':
$controller->exportToCSV($_POST);
break;
Controller:
public function exportToCSV($data){
$filter = $data['filter'];
$mod = new OrderManagementModel();
$modsucc = $mod->exportToCSV($filter);
if($modsucc){
// var_dump(ini_get('output_buffering'));
//var_dump($modsucc);
download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo array2csv($modsucc);
die();
}
}
Your code not work because you use ajax and you cant download files with ajax itself, simple way is this:
...
if($modsucc){
$file = /* directory */"data_export_" . date("Y-m-d") . ".csv";
$df = fopen(file, 'w');
fputcsv($df, array_keys(reset($array)));
foreach ($array as $row) {
fputcsv($df, $row);
}
fclose($df);
echo $file;
}
...
this will save file, and in your ajax done function:
window.open(res);
this will open new window with address to previously saved file or
window.location.href = res;
this will redirect you to address where the file was saved
to force download you could do it like this:
//force-download.php
if(file_exists($_GET['file'])){
download_send_headers("data_export_" . date("Y-m-d") . ".csv");
echo file_get_contents($_GET['file']); // warning: unsafe !! session for example will be better
}
this will send headers for force download and read data from disk where data was previosly saved and echo them
and in your ajax done function:
window.open('force-download.php?file=' + res);
or
window.location.href = 'force-download.php?file=' + res;
this use address where force download headers will be sent
Another possibility is, change $_POST to $_GET and instead of using ajax just redirect to url and it will work with your old code
Your code work, only think what could be wrong is if your server dont have enabled output buffering and you output something before calling function download_send_headers
I want to generate a .csv file then download it with AJAX
Insite csv.php I have this code:
<?php
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$file = fopen("th.csv","r");
$list = array();
while(! feof($file))
{
$list[] = (fgetcsv($file));
}
fclose($file);
$list[] = array('name5', 'town5');
$list[] = array('name6', 'town6');
$list = array_filter($list);
outputCSV($list);
function outputCSV($list) {
$output = fopen("php://output", "w");
foreach ($list as $row) {
fputcsv($output, $row);
}
fclose($output);
}
?>
so when I'm going to csv.php it makes me download the csv file.
Then inside test.php I have this jQuery code:
$(document).on('click', '#listCSV', function() {
var el = $(this),
csv = el.attr('csv');
$.ajax({
type: 'POST',
url: 'csv.php',
data: {
listCSV: csv
},
success: function(data, textStatus, jqXHR) {
el.html($(data));
}
});
});
But when I'm clicking on #listCSV nothing happens, nothing is being downloaded
Any idea how can I download the csv file when clicking on #listCSV?
generate the csv file and store it in a directory.
say:
root/csv/file_timestamp.csv
when the file is generated just use the file_timestamp.csv location on you're link.
so if your file_timestamp.csv is can be accessed via
http://project/csv/file_timestamp.csv
then just link it to a regular link:
<a href="http://project/csv/file_timestamp.csv"/>download csv</a>
Note:
if you're not expecting multiple users to generate csv files then just make a temporary file then you can set the link as static. if not just delete every file in the csv folder every 3mins
You need to change header information to output it as download :
$out = fopen("php://output", 'w');
$emails = array();
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="'.$this->filename.'.csv"');
foreach($contacts as $adr) $emails[] = $adr->getEmail();
fputcsv($out, $emails);
fclose($out);
exit;
With PHP I'm opening a .csv file, I'm adding som rows in it then I'm downloading the new .csv file.
the code I'm using is:
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$file = fopen("csv.csv","r");
$list = array();
while(! feof($file))
{
$list[] = (fgetcsv($file));
}
fclose($file);
$list[] = array('name5', 'town5');
$list[] = array('name6', 'town6');
$list = array_filter($list);
outputCSV($list);
function outputCSV($list) {
$output = fopen("php://output", "w");
foreach ($list as $row) {
fputcsv($output, $row);
}
fclose($output);
}
My issue is the other PHP code in the page don't generate, and only the .csv file is being download.
for exemple if I'm adding:
echo "test";
it won't be display and only csv.csv will be downloaded
How can I display my "echo test;" ?
With the headers you are telling the browser to download a CSV, there is no where to output your echo.
You could make a page with the information you want to show that has an iframe with the csv code in it.
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";
?>