As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
What is the most efficient way to convert a MySQL query to CSV in PHP please?
It would be best to avoid temp files as this reduces portability (dir paths and setting file-system permissions required).
The CSV should also include one top line of field names.
SELECT * INTO OUTFILE "c:/mydata.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM my_table;
(the documentation for this is here: http://dev.mysql.com/doc/refman/5.0/en/select.html)
or:
$select = "SELECT * FROM table_name";
$export = mysql_query ( $select ) or die ( "Sql error : " . mysql_error( ) );
$fields = mysql_num_fields ( $export );
for ( $i = 0; $i < $fields; $i++ )
{
$header .= mysql_field_name( $export , $i ) . "\t";
}
while( $row = mysql_fetch_row( $export ) )
{
$line = '';
foreach( $row as $value )
{
if ( ( !isset( $value ) ) || ( $value == "" ) )
{
$value = "\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );
if ( $data == "" )
{
$data = "\n(0) Records Found!\n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";
Check out this question / answer. It's more concise than #Geoff's, and also uses the builtin fputcsv function.
$result = $db_con->query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++) {
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result) {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = $result->fetch_array(MYSQLI_NUM)) {
fputcsv($fp, array_values($row));
}
die;
}
Look at the documentation regarding the SELECT ... INTO OUTFILE syntax.
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
An update to #jrgns (with some slight syntax differences) solution.
$result = mysql_query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result)
{
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
die;
}
If you'd like the download to be offered as a download that can be opened directly in Excel, this may work for you: (copied from an old unreleased project of mine)
These functions setup the headers:
function setExcelContentType() {
if(headers_sent())
return false;
header('Content-type: application/vnd.ms-excel');
return true;
}
function setDownloadAsHeader($filename) {
if(headers_sent())
return false;
header('Content-disposition: attachment; filename=' . $filename);
return true;
}
This one sends a CSV to a stream using a mysql result
function csvFromResult($stream, $result, $showColumnHeaders = true) {
if($showColumnHeaders) {
$columnHeaders = array();
$nfields = mysql_num_fields($result);
for($i = 0; $i < $nfields; $i++) {
$field = mysql_fetch_field($result, $i);
$columnHeaders[] = $field->name;
}
fputcsv($stream, $columnHeaders);
}
$nrows = 0;
while($row = mysql_fetch_row($result)) {
fputcsv($stream, $row);
$nrows++;
}
return $nrows;
}
This one uses the above function to write a CSV to a file, given by $filename
function csvFileFromResult($filename, $result, $showColumnHeaders = true) {
$fp = fopen($filename, 'w');
$rc = csvFromResult($fp, $result, $showColumnHeaders);
fclose($fp);
return $rc;
}
And this is where the magic happens ;)
function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
setExcelContentType();
setDownloadAsHeader($asFilename);
return csvFileFromResult('php://output', $result, $showColumnHeaders);
}
For example:
$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);
// Export to CSV
if($_GET['action'] == 'export') {
$rsSearchResults = mysql_query($sql, $db) or die(mysql_error());
$out = '';
$fields = mysql_list_fields('database','table',$db);
$columns = mysql_num_fields($fields);
// Put the name of all fields
for ($i = 0; $i < $columns; $i++) {
$l=mysql_field_name($fields, $i);
$out .= '"'.$l.'",';
}
$out .="\n";
// Add all values in the table
while ($l = mysql_fetch_array($rsSearchResults)) {
for ($i = 0; $i < $columns; $i++) {
$out .='"'.$l["$i"].'",';
}
$out .="\n";
}
// Output to browser with appropriate mime type, you choose ;)
header("Content-type: text/x-csv");
//header("Content-type: text/csv");
//header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=search_results.csv");
echo $out;
exit;
}
Related
The code below exports data from mysql table correctly but the column names are not displayd in the outputted csv file. Please help
if(isset($_POST["export"])){
$branchcode=$_POST['branchcode'];
$start=$_POST['start'];
$end=$_POST['end'];
$sql=mysqli_query($conn,"select tk_file,tk_date,userid,tk_from,tk_to from rfc_timekeeping_history where branchcode='$branchcode' and (tk_date between '$start' and '$end');")or die(mysqli_error());
$output = "";
$columns_total = mysqli_num_fields($sql);
for ($i = 0; $i < $columns_total; $i++) {
$heading = mysqli_fetch_fields($sql, $i);
$output .= '"'.$heading.'",';
}
$output .="\n";
while ($row = mysqli_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
}
$output .="\n";
}
$filename = "myFile.csv";
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename='.$filename);
echo $output;
exit;
}
A different approach using the standard php methods of writing to a csv file ( fputcsv ) and using stdout stream you could try along these lines. The column names are obtained in the first loop before rewinding the recordset to actually process the recordset data.
<?php
if( isset( $_POST["export"], $_POST['branchcode'], $_POST['start'], $_POST['end'] ) ){
$filename = "myFile.csv";
$branchcode=$_POST['branchcode'];
$start=$_POST['start'];
$end=$_POST['end'];
/* store columns names in this array */
$headers=array();
/* Run the query */
$sql = mysqli_query( $conn, "select `tk_file`,`tk_date`,`userid`,`tk_from`,`tk_to` from `rfc_timekeeping_history` where `branchcode`='{$branchcode}' and ( `tk_date between` '{$start}' and '{$end}');")or die(mysqli_error());
/* fetch the fields */
$fields = mysqli_fetch_fields( $sql );
/* add each column name to the array */
foreach( $fields as $field ) {
$headers[]=$field->name;
}
/* establish basic csv formatting parameters */
$delimiter=',';
$enclosure='"';
/* write output to stdout */
$output=fopen('php://output','w+');
fputcsv( $output, $headers, $delimiter, $enclosure );
/* rewind the recordset to begin processing data */
mysqli_data_seek( $sql, 0 );
/* process each row - add to stdout */
while( $row = mysqli_fetch_array( $sql ) ) {
fputcsv( $output, $row, $delimiter, $enclosure );
}
/* close stdout stream */
fclose( $output );
/* send the data */
header("Content-Type: application/csv");
header("Content-Disposition: attachment; filename={$filename}");
ob_flush();
exit();
}
?>
I want to create a csv file from some results in my database. But it display the content instead of prompting the download.
I know there are alot of questions about this, but no luck for me.
if(isset($_POST['export'])){
$resultExport = mysql_query("SELECT question.id, question.question, answer, A, B, C, D, question.publish
FROM question
INNER JOIN packagequestion
ON question.id = packagequestion.questionid
WHERE packagequestion.packageid = '".$packageID."' AND question.publish = 1
ORDER BY question.id DESC");
if (!$resultExport) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($resultExport);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($resultExport , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $resultExport)
{
// name the file by current category and package
$filename = $categorie."".$packageName;
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.$filename.".csv");
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($resultExport))
{
fputcsv($fp, array_values($row));
}
die;
}
}
hope this will help you
<?php
include 'connection.php';
// Fetch Record from Database
$output = "";
$sql = mysql_query("select* from tablename");//your query
$columns_total = mysql_num_fields($sql);
// Get The Field Name
for ($i = 0; $i < $columns_total; $i++) {
$heading = mysql_field_name($sql, $i);
$output .= '"'.$heading.'",';
}
$output .="\n";
// Get Records from the table
while ($row = mysql_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
}
$output .="\n";
}
// Download the file
$filename = "myFile.csv";
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename='.$filename);
echo $output;
exit;
?>
for that you just have to remove following line from your code.
header('Content-Type: text/csv');
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
What is the most efficient way to convert a MySQL query to CSV in PHP please?
It would be best to avoid temp files as this reduces portability (dir paths and setting file-system permissions required).
The CSV should also include one top line of field names.
SELECT * INTO OUTFILE "c:/mydata.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM my_table;
(the documentation for this is here: http://dev.mysql.com/doc/refman/5.0/en/select.html)
or:
$select = "SELECT * FROM table_name";
$export = mysql_query ( $select ) or die ( "Sql error : " . mysql_error( ) );
$fields = mysql_num_fields ( $export );
for ( $i = 0; $i < $fields; $i++ )
{
$header .= mysql_field_name( $export , $i ) . "\t";
}
while( $row = mysql_fetch_row( $export ) )
{
$line = '';
foreach( $row as $value )
{
if ( ( !isset( $value ) ) || ( $value == "" ) )
{
$value = "\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );
if ( $data == "" )
{
$data = "\n(0) Records Found!\n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";
Check out this question / answer. It's more concise than #Geoff's, and also uses the builtin fputcsv function.
$result = $db_con->query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++) {
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result) {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = $result->fetch_array(MYSQLI_NUM)) {
fputcsv($fp, array_values($row));
}
die;
}
Look at the documentation regarding the SELECT ... INTO OUTFILE syntax.
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
An update to #jrgns (with some slight syntax differences) solution.
$result = mysql_query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++)
{
$headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result)
{
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = mysql_fetch_row($result))
{
fputcsv($fp, array_values($row));
}
die;
}
If you'd like the download to be offered as a download that can be opened directly in Excel, this may work for you: (copied from an old unreleased project of mine)
These functions setup the headers:
function setExcelContentType() {
if(headers_sent())
return false;
header('Content-type: application/vnd.ms-excel');
return true;
}
function setDownloadAsHeader($filename) {
if(headers_sent())
return false;
header('Content-disposition: attachment; filename=' . $filename);
return true;
}
This one sends a CSV to a stream using a mysql result
function csvFromResult($stream, $result, $showColumnHeaders = true) {
if($showColumnHeaders) {
$columnHeaders = array();
$nfields = mysql_num_fields($result);
for($i = 0; $i < $nfields; $i++) {
$field = mysql_fetch_field($result, $i);
$columnHeaders[] = $field->name;
}
fputcsv($stream, $columnHeaders);
}
$nrows = 0;
while($row = mysql_fetch_row($result)) {
fputcsv($stream, $row);
$nrows++;
}
return $nrows;
}
This one uses the above function to write a CSV to a file, given by $filename
function csvFileFromResult($filename, $result, $showColumnHeaders = true) {
$fp = fopen($filename, 'w');
$rc = csvFromResult($fp, $result, $showColumnHeaders);
fclose($fp);
return $rc;
}
And this is where the magic happens ;)
function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
setExcelContentType();
setDownloadAsHeader($asFilename);
return csvFileFromResult('php://output', $result, $showColumnHeaders);
}
For example:
$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);
// Export to CSV
if($_GET['action'] == 'export') {
$rsSearchResults = mysql_query($sql, $db) or die(mysql_error());
$out = '';
$fields = mysql_list_fields('database','table',$db);
$columns = mysql_num_fields($fields);
// Put the name of all fields
for ($i = 0; $i < $columns; $i++) {
$l=mysql_field_name($fields, $i);
$out .= '"'.$l.'",';
}
$out .="\n";
// Add all values in the table
while ($l = mysql_fetch_array($rsSearchResults)) {
for ($i = 0; $i < $columns; $i++) {
$out .='"'.$l["$i"].'",';
}
$out .="\n";
}
// Output to browser with appropriate mime type, you choose ;)
header("Content-type: text/x-csv");
//header("Content-type: text/csv");
//header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=search_results.csv");
echo $out;
exit;
}
I have a code that converts mysql table to excel sheet. It converts and the excel sheet is downloaded but whenever I try to open the file it gives an error msg in excel 2007:"The file you are trying to open is in a different format than specified by the extension...".The excel sheet opens after I click on 'Yes' but it is nothing but a white blank sheet.I have seen the similar posts but none of them solves my problem...Please help...Thank you
<?php
include('dbcon.php');
?>
<?php
$sql = "SELECT * FROM stu_gen_info";
$rec = mysql_query($sql) or die (mysql_error());
$num_fields = mysql_num_fields($rec);
for($i = 0; $i < $num_fields; $i++ )
{
$header .= mysql_field_name($rec,$i)."\\t";
}
while($row = mysql_fetch_row($rec))
{
$line = '';
foreach($row as $value)
{
if((!isset($value)) || ($value == ""))
{
$value = "\\t";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\\t";
}
$line .= $value;
}
$data .= trim( $line ) . "\\n";
}
$data = str_replace("\\r" , "" , $data);
if ($data == "")
{
$data = "\\n No Record Found!\n";
}
header("Content-Type: application/vnd.ms-excel");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=reports.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\\n$data";
?>
try adding this
header("Content-Type: application/vnd.ms-excel");
I see plenty of postings about the proper ways to export to CSV, and most developers recommend to use fputcsv()
How would I convert the script below to use fputcsv ?
You'll see I'm also exporting the Header row, which reflects the table column names, and I'd like to keep it.
<?php
$sql = "SELECT * FROM `tbl_customers`";
$result = mysql_query($sql, $dbdata_conn) or die(mysql_error());
$header = $csv_output = '';
$fields = mysql_num_fields($result);
for ($i = 0; $i < $fields; $i++) {
$header .= mysql_field_name($result, $i) . ",";
}
$header .= "\n";
while ($rowr = mysql_fetch_row($result)) {
for ($j=0; $j<$i; $j++) {
$csv_output .= $rowr[$j].", ";
}
$csv_output .= "\n";
}
$csv_output = $header.$csv_output;
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
print "$csv_output";
exit;
?>
I'm aware that mysql_query is deprecated, so this is for the sake of practice.
As a side note, I'm not familiar with fputcsv, but I am reading that it's rather useful for formatting the data for the csv output, saving us time with all the escapes and such.
(I'm also very very open to improvements to what's above)
Simple demonstration (following your mysql_* functions):
$header=array();
$fields = mysql_num_fields($result);
for ($i = 0; $i < $fields; $i++) {
$header[] = mysql_field_name($result, $i);
}
header("...");
$f=fopen("php://output","wt");
fputcsv($f,$header);
while ($row = mysql_fetch_row($result)) {
fputcsv($f,$row);
}
fclose($f);
As you have stated, mysql_* functions are deprecated, so you should work on that too.
If you want to download it as attachment, it is OK not to use fputcsv(), but if you want to use it, here is a workaround:
$sql = "SELECT * FROM `tbl_customers`";
$result = mysql_query($sql, $dbdata_conn) or die(mysql_error());
$header = array();
$csv_output = array();
$fields = mysql_num_fields($result);
for ($i = 0; $i < $fields; $i++) {
$header[] = mysql_field_name($result, $i);
}
$csv_output[] = $header;
while ($rowr = mysql_fetch_array($result)) {
$csv_output[] = $rowr;
}
$fp = fopen('/path/to/file.csv', 'w');
foreach ($csv_output as $line) {
fputcsv($fp, $line);
}
fclose($fp);
// if you pick up the file from the directory manually, the following is not needed
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=test.csv");
header("Pragma: no-cache");
header("Expires: 0");
print file_get_contents('/path/to/file.csv');
unlink('/path/to/file.csv');
exit;