Ignore included header for PHP csv file download - php

I am trying to download a query as a .csv on a PHP web page, which has include_once ($_SERVER['DOCUMENT_ROOT'].'header.php'); at the top. When I use the PHP header() function to download it, the .csv file contains the html code from header.php followed by the .csv data. How do I get the .csv without the html (only the query data)?
For downloading I use:
$query_file_name = "App_data.csv";
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=$query_file_name");
$query_file = fopen("php://temp", "w");
// write file
$row = $results->fetch_assoc();
fputcsv($query_file, array_keys($row)); // csv head
fputcsv($query_file, $row); // first line
while($row = $results->fetch_assoc()) {
fputcsv($query_file, $row);
}
fclose($query_file);
I realize I could trim the top of the file, but I do not know how to catch this before the file downloads. Optimally, I would only like to have the html from header.php not included at all.

You need to add a condition to skip Html Code in header.php when you are calling from csv file. I hope it' will work. please refer below code.
$fromCsv = true;
require_once 'header.php';
ob_start();
$query_file_name = "App_data.csv";
$query_file = fopen("php://output", "w");
// write file
$row = $results->fetch_assoc();
fputcsv($query_file, array_keys($row)); // csv head
fputcsv($query_file, $row); // first line
while($row = $results->fetch_assoc()) {
fputcsv($query_file, $row, ",");
}
header('Content-type: application/csv');
header('Content-Disposition: attachment;filename="' . $query_file_name . '.csv"');
header('Cache-Control: max-age=0');
header("Expires: 0");
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
fpassthru($query_file);
fclose($query_file);
exit;
in header.php, all html code move to if condition
if (!$fromCsv)
{
//move all html code here
}

I ended up trying a question I found that previously didn't work. After adding ob_clean() to it, it works. My code ended up being
ob_end_clean();
ob_clean();
$query_file_name = "FabApp_data.csv";
$query_file = fopen("php://output", "w");
// write file
$row = $results->fetch_assoc();
fputcsv($query_file, array_keys($row));
fputcsv($query_file, $row);
while($row = $results->fetch_assoc()) {
fputcsv($query_file, $row, ",");
}
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=$query_file_name");
exit();

Related

CSV file generated correctly but with wrong format when is downloaded

I am a beginner student of PHP and i am doing some practice by coding a script to generate a CSV file.
Once that the csv file is generated , the format is correct as I've expected :
See the attached :
But if i add the download option the csv is generated wrongly with all the PHP page (i can see all the code)
Here the picture of the wrong csv
Could you help me to find the issue ?
Here the code :
<?php
include("db.php");
session_start();
$sql = "SELECT isocode FROM test_geo ORDER BY isocode";
$result_csv = mysqli_query($conn, $sql);
//facebook csv creation //
$filename = 'test.csv';
$fp = fopen($filename, 'w');
$headers = ['key', 'country'];
fputcsv($fp, $headers);
foreach ($result_csv as $key => $id) {
$new = array_push($id, "country");
fputcsv($fp, $id);
var_dump($id);
}
fclose($fp);
?>
Try this
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=result_file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$output = fopen("php://output", "w");
foreach ($new as $row) {
fputcsv($outputt, $row);
}
fclose($outputt);
exit();
I believe you put the header statements at the top of your script, so the download data includes the HTML codes too (like below...)
<!DOCTYPE html><html lang="en"><meta charset=...... >
You may use ob_flush() and set header (at the appropriate position of the code) so that the file will be correctly downloaded as csv when it is generated.
Here is the code:
<?php
session_start();
include("db.php");
$sql = "SELECT isocode FROM test_geo ORDER BY isocode";
$result_csv = mysqli_query($conn, $sql);
$data=array();
while($row = mysqli_fetch_array($result_csv, MYSQLI_ASSOC)) {
$ok=$row["isocode"] . "," . "Country";
array_push($data ,$ok);
}
ob_flush();
$filename="ok1.csv";
$csvData = join("\n", $data);
header('Content-Disposition: attachment; filename="'.$filename.'";');
header('Content-Type: application/csv; charset=UTF-8');
die($csvData);
?>

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

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 a .csv file in PHP stops my other PHP code

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.

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