Downloaded file after exporting data using PHP is empty - php

I have this PHP script to update a specific table of MySQL db:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
//Include connection file
require_once('../connection/connect.php');
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=reports.csv");
header("Pragma: no-cache");
header("Expires: 0");
$sql = "SELECT * FROM patient";
$stmt = $conn->prepare($sql);
$stmt->execute();
//var_dump($stmt->fetch(PDO::FETCH_ASSOC));
$data = fopen('backup.csv', 'w');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
// Export every row to a file
fputcsv($data, $row);
}
?>
I created a file in the same directory called: backup.csv and the data are updated correctly each time I execute this script. But the problem is that I can't add a header to table inside the .csv file.
And the downloaded file is empty. I need to download backup.csv and not reports.csv.
I tried:
header("Content-Disposition: attachment; filename="'.$data.'";");
But it didn't helped. The file is still empty.

Your problem is that you have not actually sent the file that you have created.
This is a better structure but remember you also have to sent the file you have built to the browser
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
//Include connection file
require_once('../connection/connect.php');
$sql = "SELECT * FROM patient";
$stmt = $conn->prepare($sql);
$stmt->execute();
$data = fopen('backup.csv', 'w');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
// Export every row to a file
fputcsv($data, $row);
}
fclose($data); // <- close file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=reports.csv");
header("Pragma: no-cache");
header("Expires: 0");
readfile('backup.csv'); // <- new line
?>

You should do fclose($data); right after while loop. I recommend you to use headers after execution of your query code. Please try/see the following example code.
Example
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
//Include connection file
require_once('../connection/connect.php');
$sql = "SELECT * FROM patient";
$stmt = $conn->prepare($sql);
$stmt->execute();
//var_dump($stmt->fetch(PDO::FETCH_ASSOC));
$data = fopen('backup.csv', 'w');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
// Export every row to a file
fputcsv($data, $row);
}
// Closing the file
fclose($data);
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=backup.csv");
header("Pragma: no-cache");
header("Expires: 0");
?>

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

Ignore included header for PHP csv file download

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

Adding the headers when creating a csv file PhP, SQL

I have the following code:
PhP
function write_csv($filename, $rows) {
$file = fopen($filename, 'w');
while($row = mysqli_fetch_assoc($rows)) :
fputcsv($file, $row);
endwhile;
fclose($file);
}
// $db is a class I have and this function just returns a SQL result set
$result_set = $db->run_query("SELECT * FROM Users");
write_csv('../MOCK_USERS_DATA.csv', $result_set);
I am correctly getting a created CSV file with the the users information for example
1,greg,mason,407-356-3322,greg#gmail.com
2,derek,herd,407-234-4352,derek#gmail.com
etc...
My question is how do I get the headers from the table as the first row in my CSV file. I am new to creating CSV files and am stuck on getting that first row of headers in that file that match the name of the column in my database. Any suggestions?
Easy export to CSV
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
ob_start();
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings -> trim is used for lang translates
// or use SQL query to get table columns headers name
fputcsv($output, array(
trim('Product name'),
trim('Pellet number'),
trim('Quantity'),
trim('Date')
), ";");
// use foreach
***********
// force download
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=pelletlist-' . time() . '.csv');
header("Content-Transfer-Encoding: binary");
header("Cache-control: private"); //use this to open files directly
header('Expires: 0');
header("Pragma: no-cache");
header("Connection: close");
fclose($output);
exit();
for load column name from db use:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'my_database' AND TABLE_NAME = 'my_table';
or
SHOW COLUMNS FROM my_table;

Why the extra information getting added to the Excel file which is to be downloaded using PHP headers?

I'm writing PHP array data to the excel file using some library. When I write the data to the excel file and echo some success message, it works fine. No other data than the intended array gets added to the file.
But when I use headers to make the download of same file functionality workable some additional information present on page (like header menu, some heading, copyright line at bottom of page, etc.)gets added to the file. How to avoid adding this extra information to the excel file? Following is my code:
<?php
require_once( CORE_PATH."/libs/excelwriter.inc.php" );
$objRebateReports = new RebateReports();
if($_POST['btnDownload']!='') {
$rebate_ret = $objRebateReports->GetRebateReport($_POST);
$rebate_data = $objRebateReports->GetResponse();
$t=time();
$fileName = ADMIN_ROOT."modules/rebates/rebate_report_".$t.".xls";
$excel = new ExcelWriter($fileName);
if($excel==false) {
echo $excel->error;
die;
}
$myArr = array('Sr. No.', 'Product','Manufacturer','User Name','Date','Status','Transaction Date');
$excel->writeLine($myArr, array('text-align'=>'center', 'color'=> 'red'));
$id=1;
foreach ($rebate_data as $value) {
$temp_rebate_data =array();
$temp_rebate_data['id'] = $id;
$temp_rebate_data['product'] = "";
$temp_rebate_data['manufacturer'] = "";
$temp_rebate_data['user_name'] = $value['customer_first_name']."".$value['customer_last_name'];
$temp_rebate_data['date'] = $value['created_at'];
$temp_rebate_data['status'] = $value['request_status'];
$temp_rebate_data['transaction_date'] = "";
$row = $temp_rebate_data;
$excel->writeLine($row, array());
$id++;
}
$excel->close();
//Following is the header information in order to download the excel file
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=".$fileName);
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
//Below is the success message after printing the data successfully to the file
//echo "Data written to file $fileName Successfully.";
}
?>
You should use output buffering for this.
//start of the page
ob_start();
//ur code
//headers
ob_clean();
flush();
readfile($file);
exit;
I think this will solve your problem

CSV Downloaded To Chrome - Error: MIME Type text/csv

I am using jQuery to recognise a click on a button which then fires a call to a file:
window.location.href = "url";
This file queries the database, returns results then writes it to a CSV file. I have the following headers set:
header('Content-Type: text/csv;');
header('Content-Disposition: attachment; filename=data.csv');
This works on all browsers except Chrome which returns the following error in the console log "Resource interpreted as Document but transferred with MIME type text/csv: "url"".
The weird thing is that if I call the file directly it works in all browsers.
Code:
$fp = fopen('php://output', 'w');
header('Content-Type: text/csv;');
header('Content-Disposition: attachment; filename=data.csv');
header("Expires: 0");
header("Cache-control: private");
//Field Headers
$ncols = oci_num_fields($stid);
$headers_row = array();
for ($i = 1; $i <= $ncols; ++$i) {
$headers_row[] = oci_field_name($stid, $i);
}
while ($row = oci_fetch_array($stid, OCI_NUM+OCI_RETURN_NULLS)) {
if(!empty($row)){
if(!empty($headers_row)){
fputcsv($fp, $headers_row);
$headers_row = '';
}
fputcsv($fp, $row);
}
}
fclose($fp);
oci_close($conn);
Anyone got any ideas?
try {
$conn = new PDO("mysql:host=$servername;dbname=db_1", $username, $password);
//set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
$query = $conn->prepare("SELECT * FROM csv_filds order by id asc");
$query->execute();
$data = "";
while($row=$query->fetch(PDO::FETCH_BOTH)){
$data .= $row['id'].",".$row['Name'].",".$row['father_name'].",".$row['address']."\n";
}
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="csvfile.csv"');
echo $data; exit();
header("content-type: application/force-download");
header("Expires: 0");
header("Cache-control: private");
I had the same problem but chrome was showing it as a warning rather than an error. I managed to stop the warning showing by changing the header to 'Content-Type', 'text/plain'.
Pretty annoying that this issue is still around 6 years after op.
Try Application Content Type
header("content-type: application/octet-stream");
Also User Public access so user can download
header("Pragma: public");
Try a readfile() of the produced file and add the header "content-length".
If it works then you may have to write to file first and then do the output.

Categories