Stuck on what is likely a silly problem and only posting after reading several related threads.
Have a page with a lot going on, one of the form options I'm trying to add is so the user can select to download array results in CSV. Problem is HTML header info is coming through in addition to the CSV data I want.
Code is:
function Array2Csv($result, $filename){
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=' .$filename);
$output = fopen('php://output', 'w');
while($row = mysql_fetch_assoc($result)) {
fputcsv($output, $row,'|','"');
}
}
Problem is the result file includes BOTH undesired markup (headers and scripting references) in addition to the CSV itself. Desired output should only include the CSV data.
You have send the the header before any output was send. Disable view and layout.
See also http://php.net/manual/en/function.header.php
Related
I am using fputcsv function to export data as CSV file but it is displaying all data in browser instead of downloading this as CSV file. Here is my code
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=export.csv');
$output = fopen('php://output', 'w');
fputcsv($output, $column_headings);
fclose($output);
Data is displaying correctly in browser but I want to download this as export.csv file.I do not know what is wrong with this. Any suggestion regarding this will be appreciated.
You cannot control how the browser handles the text/csv content type, however, you can tell the browser it should treat the data as binary.
header('Content-Type: application/octet-stream');
I added ob_start(); at the start of my file and now I can export files.
I'm trying to output data returned by an MS SQL query to an Excel or CSV file with PHP.
I've used the script in this answer and can output the file OK. Without the header lines (at the bottom of my code) it saves in my server's folder structure rather than outputs as a download to the browser.
If I add the header lines, it ouputs to a CSV file but writes the page's HTML to the file rather than the extract from the database! Am I missing a setting somewhere? I tried running the code on a page with no HTML in it (PHP and SQL code only), but it still happens.
// Give the file a suitable name:
$FileName= $PartNumber.".csv";
$fp = fopen($FileName, 'w');
// Connect to MS SQL server; the actual database is chosen in the form
// ConnSQL defined in inc/dbconn/config.php
ConnSQL($idDatabase);
// the query is a biggie; here it is:
require 'inc_sql.php';
// run it through the SQL server
$rstBOM = sqlsrv_query($GLOBALS['ConnSQL'], $sqlBOM);
while ($export= sqlsrv_fetch_array($rstBOM, SQLSRV_FETCH_ASSOC)) {
if (!isset($headings))
{
$headings = array_keys($export);
fputcsv($fp, $headings, ',', '"');
}
fputcsv($fp, $export, ',', '"');
}
// force download csv - exports HTML to CSV!
header("Content-type: application/force-download");
header('Content-Disposition: inline; filename="'.$FileName.'"');
header("Content-Transfer-Encoding: Binary");
header("Content-length: ". filesize($FileName));
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="'.$FileName.'"');
fclose($fp);
Any ideas where I'm going wrong please?
You need to output your csv file to the browser simply by putting
readfile($FileName);
At the end of your code after the fclose($fp); function.
Otherwise, browser receives the headers for files, but no content in sent from your PHP code.
You could also generate your csv file on the fly and just echo $csvFileContents; instead. This would prevent server from creating and writing data to file, which could lead to security breaches.
Good luck!
Im trying to make a CSV export from data entered in an array on my website. I was using this question to help me. I am getting the data that should be in the CSV echoed on my website but not exported to a file. This is the code that I took from the question:
header( "Content-Type: text/csv;charset=utf-8" );
header( "Content-Disposition: attachment;filename=\"$filename\"" );
header("Pragma: no-cache");
header("Expires: 0");
$fp= fopen('php://output', 'w');
foreach ($data as $fields){
fputcsv($fp, $fields);
}
fclose($fp);
exit();
I dont exactly understand what the header() functions are doing. How would I get this to download to a file?
if it helps my array is in this format:
$data = array(dataset1(array, of, data), dataset2(array, of, data), dataset#(array, of, data));
EDIT:My $data array is in a session varible and the reason it wasnt downloading was because there I had session_start() and some includes at the top. Instead of downloading it would echo to the screen but if I remove this it downloads at the cost of there being no data to export. Anyone have a solution to this?
The header() function is sending HTTP headers to your browser with the respective values.
It then sends the CSV data to the output stream which the browser interprets as a downloadable file due to the headers.
I'm serving some records from a MySQL database using PHP's fputcsv() by creating a file on the server, filling it, then linking to it on the next page.
This works and is great but as this could be sensitive data, I don't want a buch of files hanging about on the server when they were created for (probably) a one-time download.
So what I want to know is this: is there a way to create this file & serve it for download without actually writing a permanent file on the server?
For instance could I create a comma separated string instead of using fputcsv() and serve that with the right headers in an output buffer?
The obvious move is to delete the file but I need to wait until the client downloads it first so that makes it a little difficult to decide when to do it.
Any suggestions welcome
The code:
$fp = fopen($filename, 'w');
fputcsv($fp, array("Last Name", "First Name"));
foreach ($result as $fields)
{
fputcsv($fp, $fields);
}
fclose($fp);
http://php.net/manual/en/function.fputcsv.php
fputcsv() is a fabulous little function, so I wouldn't abandon it.
Instead, I suggest you play around with PHP's built-in I/O Wrappers
You, can, for example, do this to "stream" your CSV data line-by-line (subject to various output buffers, but that's another story):
<?php
header('Content-type: text/csv; charset=UTF-8');
header('Content-disposition: attachment; filename=report.csv');
$fp = fopen('php://output','w');
foreach($arrays as $array) fputcsv($fp, $array);
That works great, but if something goes wrong, your users will have a broken download.
So, if you don't have too much data, you can just write to an in-memory stream, just swap out php://output with php://memory and move things around:
<?php
$fp = fopen('php://memory','rw');
// our generateData() function might throw an exception, in which case
// we want to fail gracefully, not send the user a broken/incomplete csv.
try {
while($row = generateData()) fputcsv($fp, $row);
}catch(\Exception $e){
// display a nice page to your user and exit/return
}
// SUCCESS! - so now we have CSV data in memory. Almost like we'd spooled it to a file
// on disk, but we didn't touch the disk.
//rewind our file handle
rewind($fp);
//send output
header('Content-type: text/csv; charset=UTF-8');
header('Content-disposition: attachment; filename=report.csv');
stream_get_contents($fp);
Rather than that, why not just have your page echo out a csv mime type and then echo out the file to the user?
It works a charm, the file is never created and passed as a one off to the client.
Something like this:
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo "col1,col2";
for($i=0; $i<25;$i++)
{
echo "key :".$i.", ".($i*$i)."\r\n";
}
You should be able to test that out as is and see how it works.
The added beauty is that most users will be directed to download the file rather than opening it, so the user doesn't even leave the page (most of the time).
I've learned how to create CSV files from MySQL data from another StackOverflow question. My problem is, for some reason when I call this code, it tries to save a file called index.php (which is the current page). Inside the index.php file my data from the table is there, separated by commas. I'm guessing I have a small typo somewhere, but after playing with the code I cannot find it. Thanks to anyone who can help.
$result=mysql_query("SELECT * from tbl_email");
if(mysql_num_rows($result)) {
header ("Content-type: application/csv Content-Disposition:\"inline; filename=messages.csv\"");
echo "REF #,Company,Name,Email,Message,Date\n";
while($row = mysql_fetch_row($result)) {
$companyname = mysql_query("SELECT company FROM tbl_users WHERE user_id ='$row[1]'");
$datname = mysql_fetch_array($companyname);
echo"$row[7],$datname[company],$row[2],$row[4],$row[5],$row[6]\n";
}
die();
}
You need multiple header() calls rather than one call which supplies multiple headers on a single line, and I believe the most appropriate mime type for a CSV is text/csv.
header("Content-type: text/csv");
header("Content-Disposition: inline; filename=messages.csv");
And more commonly, we would use Content-Disposition: attachment to force a download.
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=messages.csv");
It should be:
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename="messages.csv"');
Notice that the value for filename is not encased correctly with double quotes. Try to use single quotes in php, this will save you alot of trouble. ;)
Have a look at http://www.techcoil.com/blog/php-codes-to-tell-browsers-to-open-the-download-dialog-box-for-users-to-download-a-file/ to learn more about telling browser to download your file.