I am working on Export to CSV in PHP. I have code that works fine it gives me output in ExcelSheet as I want.
Code snippet:
public function generate_csv() {
$data_rows = array();
$table = 'ProductDetails';
$data_rows = array();
global $wpdb, $bp;
$data= $wpdb->get_results("SELECT * FROM " . $table . "");
$fh = #fopen( 'php://output', 'w' );
foreach ($data as $u ) {
$row = array();
$row[0] = $u->productCode;
$row[1] = $u->productTitle;
$row[2] = $u->productDescription;
$row[3] = $u->specification;
$row[4] = $u->whereToBuy;
$data_rows[] = $row;
}
header("Pragma: public");
... Some more header ...
header("Content-Transfer-Encoding: binary");
fputcsv( $fh, $header_row );
foreach ( $data_rows as $data_row ) {
fputcsv( $fh, $data_row );
}
fclose( $fh );
die();
}
As you can see in code I am hard coding all column names and creating array. The problem is if phpMyAdmin add/remove column in database then to get perfect ExcelSheet necessary changes need to make in this code also. Can any one please help me to make this code dynamic.? Like what should be instead of $row[0], $row[1], $row[2].... ??
Thank You
More global approach is to use double foreaches
$data_rows=array();
foreach ($data as $u ) {
$row = array();
foreach ($u as $field)
{
$row[] = $field; // collect dynamic row fields
}
$data_rows[] = $row; // each row will have own array of fields
}
/// EDITED
public function generate_csv($table) // better to have table name here
{
$data_rows = array();
$data_rows = array();
global $wpdb, $bp;
$sql = "SELECT * FROM " . $table . "";
$data= $wpdb->get_results($sql);
$fh = #fopen( 'php://output', 'w' );
//following the example from: https://stackoverflow.com/a/31068464/1171074
$header_data=array();
foreach ( $wpdb->get_col( "DESC " . $table, 0 ) as $column_name ) {
$header_data[] = $column_name;
}
array_push($data_rows,$header_data); // first array will be columns names
foreach ($data as $u ) {
$row = array();
foreach ($u as $field)
{
$row[] = $field; // collect dynamic row fields
}
$data_rows[] = $row; // each row will have own array of fields
}
............ // rest of the code
}
You can use the virtual INFORMATION_SCHEMA.COLUMNS table to get the column names, like so:
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = {$table}"
This should get you pretty close, if not all the way there. It will query the table, build a headers row for the csv, then it will assemble each data row. You shouldn't need to know the row name, if you iterate the response row as value..
I apologize up front if it's a little buggy, since I don't have a PHP box handy where I'm at to verify the precise syntax.
public function generate_csv() {
global $wpdb;
global $bp;
$headers = array();
$data_rows = array();
$table = 'ProductDetails';
$data_rows = array();
$header_row;
# determine table field names
$table_sql = sprintf("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '%s'",$table);
# this will run the query and stuff field names into
$resp = $wpdb->get_results($table_sql);
foreach($resp as $row){
array_push($headers,$row[0]);
}
# get the records from the datbase
$data= $wpdb->get_results(sprintf("SELECT * FROM %s",$table));
# open output handle
$fh = #fopen( 'php://output', 'w' );
foreach ($data as $record ) {
$row = array();
foreach($record as $value){
array_push($row,$value);
}
array_push($data_rows,$row);
}
header("Pragma: public");
... Some more header ...
header("Content-Transfer-Encoding: binary");
fputcsv( $fh, $headers );
foreach ( $data_rows as $data_row ) {
fputcsv( $fh, $data_row );
}
fclose( $fh );
return;
}
Related
I have to export all my products from database into a csv file when executing the following script but i can't manage to put together the function that returns all my products from database into an array or iterator. My php code is put below. What am i doing wrong? Thank you.
<?php
require_once("config/db-connect.php");
function toate_produsele_active() {
$array_produse = mysqli_query($mysqli, "SELECT product_id, product_name, category_url, product_short_desc, product_price, product_photo FROM mb95_products");
while ($row = mysqli_fetch_assoc($array_produse)) {
print_r($row);
}
}
$f = fopen('php://output', 'wb');
if($f) {
foreach(toate_produsele_active() as $produs) {
$coloane = array(
$produs['product_id'],
$produs['product_name'],
$produs['category_url'],
$produs['product_short_desc'],
$produs['product_price'],
implode('[,]', str_replace('[,]', '[%2C]', $produs['product_photo'])),
);
fputcsv($f, $coloane, ';', '"');
}
fclose($f);
}
?>
My final desired result should look something like this:
1;Titlu produs1;categorie;Descriere produs1;RON;60;5;product_photo.jpg
let's say that toate_produsele_active() it's working as expected. I have created three functions, so the code can be reused and i have added the comments in the code:
<?php
// Create the header for the csv file (ID, Titlu, Descriere, Pret)
function getHeader()
{
$csv = '';
$headerData = array();
$header = 'ID, Titlu, Descriere, Pret';
$columns = explode(',', $header);
foreach ($columns as $column) {
$headerData[] = $column;
}
// the titles are separated by the semicolon
$csv .= implode(';', $headerData) . "\n";
return $csv;
}
// add the products data into an array and then fill the csv file
// with rows. Separated by semicolon
function iterateItems($csv)
{
$data = [];
foreach (toate_produsele_active() as $produs) {
$data[] = $produs['product_id'];
$data[] = $produs['product_name'];
$data[] = $produs['category_url'];
$data[] = $produs['product_short_desc'];
$csv .= implode(';', $data) . "\n";
}
return $csv;
}
function exportAll()
{
// name and location of the file
$csvFile = 'products.csv';
// create the header: ID, Titlu, Descriere, Pret
$csvHeader = getHeader();
// add the header and then the product data into the csv file
$csv = iterateItems($csvHeader);
// save he file (location, file)
file_put_contents($csvFile, $csv);
}
// call the function
exportAll();
I need to export the data from the Mysql table “tblinfoaanvraag” (see here for picture of the table: http://s29.postimg.org/qeqp43z4n/mysql.png)
I have a working code with the correct query and it triggers an Excel download and the data is in the file. However, The data inside the Excel file is still formatted as an sql query result and the headers (field names) are only shown as “Array”.
So there are two things I’m struggling with at this point: format the sql-results as cells in the .csv file and the headers/table field names should be shown correctly instead of just “Array”.
Here is a screenshot of the downloaded Excel-file: http://s13.postimg.org/p0rcehehj/excel1.png
The code:
<?php
if(isset($_POST['InfoaanvragenDownloaden']))
{
try
{
// Variables for later use
$header="";
$data="";
//connection
$sHost = "localhost";
$sUser = "root";
$sPassword = "";
$sDatabase = "corbati";
$link = #mysqli_connect($sHost, $sUser, $sPassword, $sDatabase) or die("Oop, dbase is gone!");
//create query to select as data from your table
$select = "select * from tblinfoaanvraag ORDER BY PK_Infoaanvraag DESC";
//run mysql query and then count number of fields
$export = mysqli_query ( $link, $select )
or die ( "Sql error : " . mysql_error( ) );
$fields = mysqli_num_fields ( $export );
//create csv header row, to contain table headers
//with database field names
for ( $i = 0; $i < $fields; $i++ ) {
$header .= mysqli_fetch_fields( $export ) . ",";
}
//this is where most of the work is done.
//Loop through the query results, and create
//a row for each
while( $row = mysqli_fetch_row( $export ) ) {
$line = '';
//for each field in the row
foreach( $row as $value ) {
//if null, create blank field
if ( ( !isset( $value ) ) || ( $value == "" ) ){
$value = ",";
}
//else, assign field value to our data
else {
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . ",";
}
//add this field value to our row
$line .= $value;
}
//trim whitespace from each row
$data .= trim( $line ) . "\n";
}
//remove all carriage returns from the data
$data = str_replace( "\r" , "" , $data );
//create a file and send to browser for user to download
header("Content-type: application/vnd.ms-excel");
header( "Content-disposition: filename=Infoaanvragen.csv");
print "$header\n$data";
exit;
}
catch (Exception $e)
{
$feedback = $e->getMessage();
}
}
?>
http://php.net/manual/en/function.fputcsv.php
You can pass it a file handle and your data for each row, and it formats it as a CSV line, with correct escapings. It uses a file, though you can use an in memory file stream to avoid hitting the disk
$filename = "php://memory";
$fp = fopen($filename, "w+b");
$rowNum = 1;
while( $row = mysqli_fetch_row( $export ) ) {
if ($rowNum == 1){
fputcsv($fp, array_keys($row)); // Headers
}
fputcsv($fp, $row) // Data
$rowNum++;
}
rewind($fp);
var_dump(stream_get_contents($fp));
You would use the array keys of a row for first CSV row, and array values of each row for data.
Use ';' as delimiter (fputcsv has a parameter for that and it's ',' by default) and set the end of lines in DOS format. At least it's what phpMyAdmin does when doing an export in the "CSV for MS Excel" format.
I want to extract some data and create a csv file. This is how my attributes table looks like. you can see it in the picture:
HERE
This is my code, what i tried:
$select = mysql_query("select * from attributes");
$final ="";
$i = 0;
while($row = mysql_fetch_array($select)) {
$id_produs = $row['id_produs'];
$n_attr = $row['nume_attr'];
$val = $row['val_attr'];
$final .= $id_produs . "%%" . $val . "%%";
$csv_array_attributes[$i] = $final;
$i++;
}
This is the part when i create the CSV file:
$file = fopen("attributes.csv", "w+");
foreach ($csv_array_attributes as $line) {
fputcsv($file, explode('%%', $line), "^", "`");
}
fclose($file);
AND this would be the wanted result: HERE. So, the nume_attr should be the header for every column in the csv and the val_attr should be the values for every nume_attr (see the image).
I tried many ways but I don't get this result from the image. I have to mention that my table "attributes" has more than 74000 rows.
This is the table structure:
CREATE TABLE `attributes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_produs` text NOT NULL,
`nume_attr` text NOT NULL,
`val_attr` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=673912 DEFAULT CHARSET=latin1;
/*Try following code */
$select = mysql_query("select * from attributes");
$i = 0;
$csv_array_attributes[$i]=array('sku','manufacturer_article','manufacturer');
$i++;
while($row = mysql_fetch_array($select)) {
$csv_array_attributes[$i] =array('sku'=>$row['id_produs'],'manufacturer_article'=>$row['nume_attr'],'manufacturer'=>$row['val_attr']);
$i++;
}
$file = fopen("attributes.csv", "w+");
foreach ($csv_array_attributes as $line) {
fputcsv($file,$line);
}
fclose($file);
Let's assume speed isn't the issue here and neither is concurrency, i.e. you just want the result now no matter how good, bad or ugly the solution is ;-)
First query all the attribute names via SELECT DISTINCT nume_attr FROM attributes
Store those names as keys of an array with empty string values, i.e. you should have an array like
$template = array(
'Manufacturer Article' => '',
'Manufacturer' => '',
...
)
Make a variable that stores the currently processed id_produs (start with false).
Make a variable that stores the current "csv"-record ( again start with false )
Query all records ordered by id_produs and iteratore over the result.
If the current record has a different id_produs than the "currently processed" write out the current "csv"-array and start anew with the template array created in the first step and the current id_produs as ...the current id_produs. For each record write the val_attr value to the key nume_attr in the csv array.
You will have to check/write the last record after the iteration.
/* try following code,and reply if it will helpful to you or not */
$select = mysql_query("select * from attributes");
$i = 0;
$i++;
while($row = mysql_fetch_array($select)) {
$csv_array_attributes[$row['id_produs']][$row['nume_attr']] =$row['val_attr'];
$i++;
}
$arraytempheader=array();
$arraytemp=array();
$arraytempheader[0]="";
$j=1;
foreach ($csv_array_attributes as $Colname=>$alline) {
if($j!=1)
{
foreach($arraytempheader as $key=>$val)
{
if($key!=$j && $key!=0)
$arraytemp[$Colname][$key]="";
}
}
foreach ($alline as $keyline=>$valline)
{
$arraytempheader[$j]=$keyline;
$arraytemp[$Colname][$j]=$valline;
$j++;
}
}
$file = fopen("attributes.csv", "w+");
fputcsv($file,$arraytempheader);
foreach ($arraytemp as $Colname=>$alline) {
$finalArray=array();
$finalArray[]=$Colname;
$finalArray=array_merge($finalArray,$alline);
fputcsv($file,$finalArray);
}
fclose($file);
Try to fix this in other way.
Here you select the attributes and store them into array
$select = mysql_query("select * from attributes");
$rezultat=array();
while($row = mysql_fetch_array($select)) {
$id_produs = $row['id_produs'];
$n_attr = $row['nume_attr'];
$val = $row['val_attr'];
//$final .= $id_produs . "%%" . $val . "%%";
$rezultat[] = array('id'=>$id_produs,'attr'=>$val);
}
And here you write them to the file.
$file = fopen("attributes.csv", "w+");
foreach ($rezultat as $line) {
fputcsv($file, $line, "^", "`");
}
fclose($file);
Having checked a variety of questions but not being able to find quite what I need, I am at a bit of a loss.
I am trying to chose the columns from MySQL I want exported to CSV by parsing the column names and adding the valid column names to a $colnames array, then adding those values as headers to the CSV and then only displaying the relevant data from the database through a while loop.
I have looked at the following in particular having been guided there from other questions: How to get all the key in multi-dimensional array in php
Here is the code:
function query_to_csv($query, $filename, $attachment = false, $headers = true, $specs_off = false) {
if($attachment) {
// send response headers to the browser
header( 'Content-Type: text/csv; charset=UTF-8' );
header( 'Content-Disposition: attachment;filename='.$filename);
$fp = fopen('php://output', 'w');
} else {
$fp = fopen($filename, 'w');
}
$result = mysql_query($query) or die( mysql_error() );
if($headers) {
// output header row (if at least one row exists)
$row = mysql_fetch_assoc($result);
if($row) {
// PRODUCTS TABLE SPECIFIC - get rid of specs_ and free_ columns so have nicer data set for user
if($specs_off) {
$columnames = array_keys($row);
$colnames = array();
//$colnames = array_keys($row);
foreach($columnames as $key => $value) {
if((substr_count($value, "spec_") < 1) && (substr_count($value, "free_") < 1)) {
array_push($colnames, $value);
}
}
}
else {
$colnames = array_keys($row);
}
// add in additional columns if exporting client data
if($table == 'clients') {array_push($colnames, "products", "last_order_date");}
//write the colnames to the csv file
fputcsv($fp, $colnames);
// reset pointer back to beginning
mysql_data_seek($result, 0);
}
} // done with the headers etc, now lets get on with the data
// clear out and create the $row_data array
$row_data = array();
// run through the row array adding values to row_data as we go
while($row = mysql_fetch_assoc($result)) {
// create the array_keys_multi from https://stackoverflow.com/questions/11234852/how-to-get-all-the-key-in-multi-dimensional-array-in-php/11234924#11234924
function array_keys_multi(array $array) {
$keys = array();
foreach ($array as $key => $value) {
$keys[] = $key;
if (is_array($array[$key])) {
$keys = array_merge($keys, array_keys_multi($array[$key]));
}
}
return $keys;
}
// run the function on the $row array
array_keys_multi($row);
// now use the $keys array
foreach($keys as $key => $value) {
// check if the value is in the colnames array and if so push the data on to the $row_data array ready for export to CSV
if(in_array($value, $colnames)) {
array_push($row_data, $row[$value]);
}
}
// now we are ready to write the CSV
fputcsv($fp, $row_data);
}
fclose($fp);
exit;
} // end of query_to_csv
// Write the sql statement
$sql = "SELECT * FROM ".$table." ";
if(isset($where_1_col)) { $sql .= " WHERE `".$where_1_col."` = '".$where_1_val."'"; }
if(isset($where_2_col)) { $sql .= " AND `".$where_2_col."` = '".$where_2_val."'"; }
if(isset($where_3_col)) { $sql .= " AND `".$where_3_col."` = '".$where_3_val."'"; }
if(isset($where_4_col)) { $sql .= " AND `".$where_4_col."` = '".$where_4_val."'"; }
if(isset($order_by_col)) { $sql .= " ORDER BY `".$order_by_col."` ". strtoupper($order_by_dir) ." "; }
// output as an attachment
query_to_csv($sql, $table."_export.csv", true, true, true);
All I am getting is a huge export of the chosen column names repeated as many times as there are values from the initial query. I don't know how to get the values in.
Any suggestions on where I am going wrong or how I can undertake this more neatly are welcomed.
It seems that you just append the new row data to $row_data but never clear that array.
array_push($row_data, $row[$value]);
What I did to fix it:
Move
// clear out and create the $row_data array
$row_data = array();
into the while loop.
Change
// clear out and create the $row_data array
$row_data = array();
while($row = mysql_fetch_assoc($result)) {
...
}
To
while($row = mysql_fetch_assoc($result)) {
// clear out and create the $row_data array
$row_data = array();
...
}
Note:
You are using $table everywhere but never define it. Like here if($table == 'clients')
If it is a global var you need to add global $table or a parameter to your function, too.
Edit:
As mentioned in my comment on your question you could just use array_keys() to get the keys.
php.net/manual/de/function.array-keys.php
And then change
array_keys_multi($row);
to
$keys = array_keys($row);
After that you can remove array_keys_multi()
Further you could move that part in front of your while-loop because you only need to calculate the column names you need once and not in every iteration.
I'm trying to get data from an off-site Miscrosoft SQL database using php's odbc connection, convert certain queries against it to arrays, and then turn those arrays into a csv that my cms can read and import. I'm able to succesfully conncect and return some results from the database, but my lack of php and SQL skills is killing me.
What I have right now, which is not much, but does what it's supposed to do:
$result = odbc_tables($connect);
$tables = array();
while (odbc_fetch_row($result))
{
if(odbc_result($result,"TABLE_TYPE")=="TABLE")
echo"<br>".odbc_result($result,"TABLE_NAME");
}
Is there any clear resource on the web on how to do what I want to do? The official php documentation seems to be about the most unhelpful documentation ever. A basic example: I want to return the entries here into csv format. I can get them in array format:
$query = "SELECT TOP 10 * FROM Communities";
$result = odbc_exec($connect, $query);
if ( $result )
{
while ( ($row = odbc_fetch_array($result)) )
{
print_r($row);
}
odbc_free_result($result);
}
else
{
echo 'Exec error: ' . odbc_errormsg();
}
odbc_close($conn);
Wish I had more, but I'm a bit lost on where to go next.
Using the tips, here's the working solution:
$theArray = array();
while ( ($row = odbc_fetch_array($result)) )
{
array_push($theArray, $row);
}
$header = array('Name', 'Hours', 'Fees', 'Notes', 'ShortDescription', 'URL');
$fp = fopen('array.csv', 'w');
fputcsv($fp, $header);
foreach ($theArray as $lines)
{
fputcsv($fp, $lines);
}
I just got done doing the exact project that you are asking about. I am running php 5.2 so you may be able to deal with the csv file more easily in a newer version. Here is my code:
<?php
// Uncomment this line for troubleshooting / if nothing displays
ini_set('display_errors', 'On');
$myServer = "GSRBI";
$myUser = "webuser";
$myPass = "Webuser1";
$myDB = "GSRBI";
$dbhandle = odbc_connect($myServer, $myUser, $myPass)
or die("Couldn't connect to SQL Server on $myServer");
$return = odbc_exec($dbhandle, 'select * from GSRBI.dbo.BounceBackEmail');
$subscribers_array = array();
$db_row = '';
$arrayrow = 0;
while ( $db_row = odbc_fetch_array($return) )
{
$arrayrow++;
$array[] = array(
'card_num' => $db_row['PlayerAccountNumber']
,'last_name' => ucfirst(strtolower($db_row['LastName']))
,'first_name' => ucfirst(strtolower($db_row['FirstName']))
,'email' => $db_row['EMailAddress']
,'earned_on_date' => date('m/d/Y', strtotime('-1 days'))
,'free_play' => $db_row['Offer1']
,'valid_through_date' => date('m/d/Y', strtotime('+15 days'))
);
}
echo print_r($arrayrow, true); ## display number of rows for sql array
echo " rows in ODBC ";
// Creates an array with GSR webteams contact info
$array1[] = array(
'card_num' => "123456789"
,'last_name' => "GSRwebteam"
,'first_name' => "GSRwebteam"
,'email' => "webteam#something.com"
,'earned_on_date' => date('m/d/Y', strtotime('-1 days'))
,'free_play' => "9"
,'valid_through_date' => date('m/d/Y', strtotime('+15 days'))
);
$result = array_merge((array)$array, (array)$array1); ## merge the two arrays together
// This will convert the array to csv format then save it
## Grab the first element to build the header
$arr = array_pop( $result );
$temp = array();
foreach( $arr as $key => $data )
{
$temp[] = $key;
}
$csv = implode( ',', $temp ) . "\n";
$csv .= to_csv_line( $arr ); ## Add the data from the first element
foreach( $result as $arr ) ## Add the data for the rest
{
$csv .= to_csv_line( $arr );
}
//echo print_r($csv, true); ## Uncomment to test output1
$f = fopen('reports/bounceback-'.date('m-d-Y').'.csv', "w");
fwrite($f, $csv);
fclose($f);
Echo "The report has ran";
return $csv;
function to_csv_line( $result )
{
$temp = array();
foreach( $result as $elt )
{
$temp[] = '' . addslashes( $elt ) . '';
}
$string = implode( ',', $temp ) . "\n";
return $string;
}