Laravel 3 create Text (CSV) file - php

Hello I am trying to grab all the emails from the database, then output them into a text (comma separated) file. Here is what I have done but does not work:
public function get_textfile() {
$emails = Staff::get('email');
header("Content-type: text/csv");
header("Cache-Control: no-store, no-cache");
header('Content-Disposition: attachment; filename="filename.txt"');
$stream = fopen("php://output", 'w');
foreach($emails as $email) {
fputcsv($stream, $email, ',');
}
fclose($outstream);
}
return (something)?
getting this: Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.
This is my route:
Route::get('textfile', array('as' => 'textfile','uses' => 'admin#textfile'));

try file_put_contents($filename, implode(',', Staff::get('email')));

Collect all of your data into a string and then output it like this:
$data = '';
foreach ($emails as $email)
{
// If you want 1 email per line
$data .= '"'.$email.'"'.PHP_EOL;
// If you want all emails on 1 line
$data .= '"'.$email.'",';
}
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename=My Cool File.csv');
header('Pragma: no-cache');
header('Expires: 0');
echo $data;

Related

PHP: PDO + CSV export not downloading (headers issue?)

I'm having a hard time making my CSV export function work.
I've found around plenty of examples using mysqli_* functions, but I'm actually using PDOs so I had to adapt some questions/answers to my needs.
From what I can see, I'm properly parsing and writing data to the *.csv file, but at the end I don't simply get any "Download" modal from the browser.
Again, looking around, I've understood I may have some kind of problem with my headers, so I'm asking for your help.
This is my PHP function snippet:
function downloadAsCSV($dsn, $dbUser, $dbPsw, $options) {
// New PDO connection.
$pdo = pdoConnect($dsn, $dbUser, $dbPsw, $options);
$query = ... // Not going to write it down.
// Let's query the database, ...
$stmt = $pdo->prepare($query);
// Setting up the query variables here...
[...]
// Executing the statement...
$stmt->execute();
// Headers.
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='export.csv'");
header("Pragma: no-cache");
header("Expires: 0");
// Let's open tbe "*.csv" file where we'll save the results.
$fp = fopen("php://output", "w");
if ($fp) {
$first_row = $stmt->fetch(PDO::FETCH_ASSOC);
$headers = array_keys($first_row);
fputcsv($fp, array_values($first_row));
fputcsv($fp, $headers);
// ... fetch the results...
$workpiecesArray = $stmt->fetchAll();
// ... and, finally, export them.
foreach ($workpiecesArray as $workpiece) {
fputcsv($fp, array_values($workpiece));
}
}
fclose($fp);
// Closing the connection.
$stmt = null;
$pdo = null;
}
function mysqli_field_name($result, $field_offset) {
$properties = mysqli_fetch_field_direct($result, $field_offset);
return is_object($properties) ? $properties->name : null;
}
I've taken inspiration to write the table column titles from this answer.
What you need to do is to print the file, which you're not doing right now.
See this example using readfile:
http://php.net/manual/en/function.header.php#example-5554
Simply put:
1.Replace
$fp = fopen("php://output", "w");
with
$tmpfname = tempnam("/", "");
$fp = fopen($tmpfname, "w");
2.Replace
fclose($fp);
with
fclose($fp);
readfile($tmpfname);
unlink($tmpfname);
and this will work
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="export.csv"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('export.csv'));
readfile($csvFile);
exit;
`put this after` fclose($fp);

Issues with exporting a csv file

I'm creating a function that, when you click on a button, submits datas to a this function and in return, creates a .csv file and makes the browser download it. I followed the huge amount of tutorials that can be found online, but maybe I'm mixing up things:
header("Content-Type: application/x-excel");
header("Content-disposition: attachment; filename=export".date('d-m-Y') .".csv");
header('Expires : 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
$list = array
(
"Peter,Griffin,Oslo,Norway",
"Glenn,Quagmire,Oslo,Norway",
);
$file = fopen("contacts.csv","w");
foreach ($list as $line) {
fputcsv($file,explode(',',$line));
}
die($file);
readfile($file);
Just keep in mind that these aren't my real datas, I just want to set everything up before continuing, because I have 50 lines of an array to handle.
With this code, If I keep die($file), the file gets downloaded but is empty. If I remove it, my browser tells me that the website is unavailable.
What am I missing?
try this
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="sample.csv"');
$data = array(
"Peter,Griffin,Oslo,Norway",
"Glenn,Quagmire,Oslo,Norway",
);
$fp = fopen('php://output', 'w');
foreach ( $data as $line ) {
$val = explode(",", $line);
fputcsv($fp, $val);
}
fclose($fp);

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);
}
?>

Downloading csv file in firefox bug

There is a download in CSV feature in my current CodeIgniter project. When a user click the link, it will download a file in CSV. The downloaded CSV file's filename is incorrect once the provided filename in the code has a question mark character. To make things clear, below is the code.
public function download($role = NULL, $id = 0, $eid = 0) {
$this->load->helper('download');
$list = $this->respondent->get_respondents($eid);
$questions = $this->respondent->get_all_questions($eid);
$fp = fopen('php://output', 'w');
$fields = array(
'Timestamp',
'First Name',
'Middle Name',
'Last Name',
);
$fields = array_merge($fields, $questions);
fputcsv($fp, $fields);
foreach ($list as $respondent) {
$respondent_data = array(
$respondent->since,
$respondent->first_name,
$respondent->middle_name,
$respondent->last_name,
);
$query = $this->respondent->get_responses($respondent->rid);
foreach($query as $response) {
array_push($respondent_data, $response->answer, $response->duration);
}
fputcsv($fp, $respondent_data);
}
$data = file_get_contents('php://output');
$name = $this->respondent->get_experiment($respondent->eid)->title.'.csv';
// Build the headers to push out the file properly.
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Disposition: attachment; filename="'.basename($name).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: close');
exit();
force_download($name, $data);
fclose($fp);
}
In the line header('Content-Disposition: attachment; filename="'.basename($name).'"');, once the $name has a question mark character, downloading the file in Firefox or Chrome browser can't interpret it correctly. Rather than a question mark character, the generated character is an underscore or hyphen, respectively. However, when Safari is used to download, the filename is just fine. Is the problem in the code or the browsers?
What I meant in my comment is this.
str_replace('?', '_', $name); //when saving file on the server
This way there is no limit for users simply every question mark is replaced with _, I guess no big deal.
The part about FF and GCH I can not answer.

Download csv from codeigniter mysql

I think I'm missing something obvious. I'm trying to export a dataset from a MySQL query to CSV without printing it to the browser.
Here's my code:
<?php
$this->load->helper('download');
$list = $stories;
$fp = fopen('php://output', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
$data = file_get_contents('php://output'); // Read the file's contents
$name = 'data.csv';
force_download($name, $data);
fclose($fp);
?>
$stories is my array created from the MySQL query.
Currently everything prints to the browser with no errors and no download but I would like to force a CSV download. How can I do this?
final working code:
$this->load->helper('download');
$list = $stories;
$fp = fopen('php://output', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
$data = file_get_contents('php://output');
$name = 'data.csv';
// Build the headers to push out the file properly.
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Disposition: attachment; filename="'.basename($name).'"'); // Add the file name
header('Content-Transfer-Encoding: binary');
header('Connection: close');
exit();
force_download($name, $data);
fclose($fp);
You can call model CSV() from your controller as
$this->load->model('Users_model');
$this->Users_model->csv();
and in the model
function csv()
{
$this->load->dbutil();
$this->load->helper('file');
$this->load->helper('download');
$query = $this->db->query("SELECT * FROM Users");
$delimiter = ",";
$newline = "\r\n";
$data = $this->dbutil->csv_from_result($query, $delimiter, $newline);
force_download('CSV_Report.csv', $data);
}
Your File will start downloading
I can't tell what headers are set from the Codeigniter force_download() function sets. If it is indeed going to the screen I would suspect the necessary headers are missing. You can add the below headers to your code to set correct csv dowload headers (The cache control will ensure fresh data download each time:
header('Content-Description: File Transfer');
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename='.$name);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
i am use this and its work
header('Content-Type: text/csv; charset=utf-8');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header("Content-Disposition: attachment; filename=backup" . date('y-m-d') . ".csv");
header('Last-Modified: ' . date('D M j G:i:s T Y'));
$outss = fopen("php://output", "w");
$this->db->order_by('ID', 'DESC');
$query = $this->db->get('urls');
foreach ($query->result_array() as $rows) {
fputcsv($outss, $rows);
}
fclose($outss);
return;
If you are trying to generate reports in csv format then it will quite easy with codeigniter.
Place this code in your Controller
function get_report()
{
$this->load->model('Main_Model');
$this->load->dbutil();
$this->load->helper('file');
/* get the object */
$report = $this->Main_Model->print_report();
$delimiter = ",";
$newline = "\r\n";
$new_report = $this->dbutil->csv_from_result($report, $delimiter, $newline);
write_file( 'application/third_party/file.csv', $new_report);
$this->load->view('report_success.php');
}
Put this code into Model
public function print_report()
{
return $query = $this->db->query("SELECT * FROM Table_name");
}
report_success.php is just Successful Notification.
Your Report is being Exported. Thank you
Finally Your "file.csv" is generated.
its basically stored at physical storage.
In CodeIgniter/application/third-party/file.csv
it works.
it will help you.
Here we have sample result set from MySQL and want to export in CSV file.
Step 1: Get MySql data in key value pair.
$data = array(
'0' => array('Name'=> 'Parvez', 'Status' =>'complete', 'Priority'=>'Low', 'Salary'=>'001'),
'1' => array('Name'=> 'Alam', 'Status' =>'inprogress', 'Priority'=>'Low', 'Salary'=>'111'),
'2' => array('Name'=> 'Sunnay', 'Status' =>'hold', 'Priority'=>'Low', 'Salary'=>'333'),
'3' => array('Name'=> 'Amir', 'Status' =>'pending', 'Priority'=>'Low', 'Salary'=>'444'),
'4' => array('Name'=> 'Amir1', 'Status' =>'pending', 'Priority'=>'Low', 'Salary'=>'777'),
'5' => array('Name'=> 'Amir2', 'Status' =>'pending', 'Priority'=>'Low', 'Salary'=>'777')
);
Step 2: PHP code to get options type and force to browser download file instead of display.
if(isset($_POST["ExportType"]))
{
switch($_POST["ExportType"])
{
case "export-to-csv" :
// Submission from
$filename = $_POST["ExportType"] . ".csv";
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=\"$filename\"");
ExportCSVFile($data);
//$_POST["ExportType"] = '';
exit();
default :
die("Unknown action : ".$_POST["action"]);
break;
}
}
function ExportCSVFile($records) {
// create a file pointer connected to the output stream
$fh = fopen( 'php://output', 'w' );
$heading = false;
if(!empty($records))
foreach($records as $row) {
if(!$heading) {
// output the column headings
fputcsv($fh, array_keys($row));
$heading = true;
}
// loop over the rows, outputting them
fputcsv($fh, array_values($row));
}
fclose($fh);
}
Step 3: Define html layout for display data in table and button to fire export-to-csv action.
<div>Export to csv</div>
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post" id="export-form">
<input type="hidden" value='' id='hidden-type' name='ExportType'/>
</form>
<table id="" class="table table-striped table-bordered">
<tr>
<th>Name</th>
<th>Status</th>
<th>Priority</th>
<th>Salary</th>
</tr>
<tbody>
<?php foreach($data as $row):?>
<tr>
<td><?php echo $row ['Name']?></td>
<td><?php echo $row ['Status']?></td>
<td><?php echo $row ['Priority']?></td>
<td><?php echo $row ['Salary']?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Step 3: Now we will use jQuery code to get click event.
<script type="text/javascript">
$(document).ready(function() {
jQuery('#export-to-csv').bind("click", function() {
var target = $(this).attr('id');
switch(target) {
case 'export-to-csv' :
$('#hidden-type').val(target);
//alert($('#hidden-type').val());
$('#export-form').submit();
$('#hidden-type').val('');
break
}
});
});
</script>

Categories