Save query results to .csv with PHP - php

I have the following query running and I am looking at the best way to export the data to a .csv or .xls file.
<?php
$channels = ee()->db->select('channel_titles.entry_id, channel_titles.title, channel_data.field_id_164')
->from('channel_titles')
->join('channel_data', 'channel_titles.entry_id = channel_data.entry_id')
->where(array(
'channel_titles.channel_id' => '12',
))
->or_where(array(
'channel_titles.channel_id' => '31',
))
->get();
if ($channels->num_rows() > 0)
{
$i = 0;
foreach($channels->result_array() as $row)
{
$i++;
echo $row['field_id_164'].",".$row['title']."<br />\n";
}
echo $i;
}
?>
I have tried a few methods but cannot seem to figure out the best option.

The classic echo explode(',',$col) etc way is fine, but you can also write directly to the csv file using php's built in functions.
$filename = 'test.csv';
$file = fopen($filename,"w");
if ($channels->num_rows() > 0) {
foreach($channels->result_array() as $key => $row) {
if ($key==0) fputcsv($file, array_keys((array)$row)); // write column headings, added extra brace
foreach ($row as $line) {
$line = (array) $line;
fputcsv($file, $line);
}
}
}
fclose($file);
edit:
If you want to download/view the file instantly you have to set the headers.
$filename = 'test.csv';
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename=' . $filename);
header("Content-Transfer-Encoding: UTF-8");
$file = fopen('php://output', 'a');
if ($channels->num_rows() > 0) {
foreach($channels->result_array() as $key => $row) {
if ($key==0) fputcsv($file, array_keys((array)$row)); // write column headings, added extra brace
foreach ($row as $line) {
$line = (array) $line;
fputcsv($file, $line);
}
}
}
fclose($file);

Related

How to write and save CSV file to server in PHP?

I am trying to create a new CSV file using PHP and upload or move it to a new part of the server but the spreadsheet it returns is a spreadsheet that has only the first cell in the first row with a value of either 404 or 1. What am I doing wrong?
My code is attached below.
// genrate new general spreadsheet
$filepath = substr($file_path, 1);
$data = load_csv_file($filepath);
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename="file-saved.csv"');
$fp = fopen('php://output', 'wb');
foreach ($data as $row) {
$output = fputcsv($fp, $row);
}
$filename = "file-saved.csv";
file_put_contents( $filename, $output);
fclose($fp);
The $data variable is an array of values from another CSV file.
$output = [];
foreach($data as $row) {
$output[] = ..
}
...
error_reporting(0);
$file_n = public_path('/csv_file/product_details.csv');
$infoPath = pathinfo($file_n);
if($infoPath['extension'] == 'csv'){
$file = fopen($file_n, "r");
$i = 0;
$all_data = array();
while ( ($filedata = fgetcsv($file, null, "|")) !==FALSE) {
$num = count($filedata );
for ($c=0; $c < $num; $c++) {
$all_data[$i][] = $filedata [$c];
}
$i++;
}
fclose($file);
foreach($all_data as $importData){
$insertData = array(
"article_number"=>$importData[0],
"article_name"=>$importData[1],
"article_description"=>$importData[2],
"article_price"=>$importData[3],
"article_manufacturer"=>$importData[6],
"article_productgroupkey"=>$importData[7],
"article_productgroup"=>$importData[8],
"article_ean"=>$importData[9],
"article_hbnr"=>$importData[10],
"article_shippingcosttext"=>$importData[11],
"article_amount"=>$importData[12],
"article_paymentinadvance"=>$importData[13],
"article_maxdeliveryamount"=>$importData[14],
"article_energyefficiencyclass"=>$importData[15]
);
insertData($insertData);
}
}else{
echo "Invalid file extension.";
}
function insertData($data){
if($article_number->count() == 0){
//write your insert query here for $data
}elseif($article_number->count() > 0){
//article_number already present then update the table.UPDATE QUERY
}
}

“How to export other next file‘ after 2000 rows data

I am using PHP for export CSV file this is working, but i export 2000 or greater rows how to create automatic next CSV file.
How to Move other file on after 2000 rows?
<?php
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename = records.csv');
echo $header = "Name";
echo "\r\n";
$sql = mysql_query(“Select * from table”);
while ($getData = mysql_fetch_assoc($sql)) {
echo '"'.$name.'"';
echo "\r\n";
}
exit;
?>
You can use array_chunk function to keep the records of 2000 and export them in csv.
For example
$rowData = [
[1,2,3],
[11,21,31],
[21,22,32],
[31,42,73],
[111,222,333]
];
foreach(array_chunk($rowData, 2) as $key => $records){
$file_name = 'export_data_'.$key.'.csv';
writeToCsv($file_name,$records);
}
//funtion to export data to csv
function writeToCsv($fileName, $rowData){
$fp = fopen($fileName, 'w');
foreach ($rowData as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
}
In your case use array_chunk($rowData, 2000)
<?php
$rowLimit = 2000;
$fileIndex = 0;
$i = 1;
$handle = null;
$fileList = array();
$timestampFolder = strtotime("now").'/';
mkdir($timestampFolder);
$sql = mysql_query("Select * from table");
while ($getData = mysql_fetch_assoc($sql)) {
if( ($i%$rowLimit) == 1) {
$fileIndex+=1;
if(!is_null($handle)) {
fclose($handle);
}
$fileName = "records".$fileIndex.".csv";
$handle = fopen($timestampFolder.$fileName, "a");
$fileList[] = $fileName;
}
fputcsv($handle, $getData);
$i++;
}
foreach($fileList as $file) {
echo ''.$file.'<br>';
}

Data from separate function being merged in excel

Im working on 2 json data which I need to transfer the data to separate excel files. What I did is, I made 2 function so that I can choose what file to be downloaded. The problem is when I tried to call both, the data is merged on a single excel. What I expect is it will be downloaded separately.
I tried adding sleep after the first function but didn't work, still the same output. I tried also using die after both function but only the first one is working.
Hope you help me.
SAMPLE CODE
function.php
<?php
function bjpk(){
$json = 'api link...';
$arr = json_decode(file_get_contents($json), true);
$name = $arr['code'];
header("Content-Disposition: attachment; filename=\"$name.xls\"");
header("Content-Type: application/vnd.ms-excel;");
header("Pragma: no-cache");
header("Expires: 0");
$out = fopen("php://output", 'w');
$data = array();
foreach ($arr['data'] as $key => $value) {
$data['date'] = substr($value['opentime'], 0, -9);
$data['num'] = substr($value['expect'], 4);
$codes = explode(',', $value['opencode']);
foreach ($codes as $key => $code) {
$data[$key] = $code;
}
fputcsv($out, $data,"\t");
}
fclose($out);
}
function cqssc(){
$json = 'api link..';
$arr = json_decode(file_get_contents($json), true);
$name = $arr['code'];
header("Content-Disposition: attachment; filename=\"$name.xls\"");
header("Content-Type: application/vnd.ms-excel;");
header("Pragma: no-cache");
header("Expires: 0");
$out = fopen("php://output", 'w');
$data = array();
foreach ($arr['data'] as $key => $value) {
$date = DateTime::createFromFormat('Ymd', substr($value['expect'], 0, -3));
$data['date'] = $date->format('Y-m-d');
$data['num'] = substr($value['expect'], 8);
$codes = explode(',', $value['opencode']);
foreach ($codes as $key => $code) {
$data[$key] = $code;
}
fputcsv($out, $data,"\t");
}
fclose($out);
}
index.php
<?php
require_once ('function.php');
bjpk();
cqssc();

Convert csv in php and get unique value

I would like to convert a csv file that has duplicate contents and i would like to sum the quantity and extract the price without sum it.
file.csv :
code,qty,price
001,2,199
001,1,199
002,2,159
002,2,159
Actual php that sum the quantiy and get a result with unique value and total qty.
<?php
$tsvFile = new SplFileObject('file.csv');
$tsvFile->setFlags(SplFileObject::READ_CSV);
$tsvFile->setCsvControl("\t");
$file = fopen('file.csv', 'w');
$header = array('sku', 'qty');
fputcsv($file, $header, ',', '"');
foreach ($tsvFile as $line => $row) {
if ($line > 0) {
if (isset($newData[$row[0]])) {
$newData[$row[0]]+= $row[1];
} else {
$newData[$row[0]] = $row[1];
}
}
}
foreach ($newData as $key => $value) {
fputcsv($file, array($key, $value), ',', '"');
}
fclose($file);
?>
the result for this is:
code,qty
001,3
002,4
and i would like to add price, but without sum it.
The result i need is:
code,qty,price
001,3,199
002,4,159
I haven't tested this yet, but I think this is what you are looking for:
<?php
$tsvFile = new SplFileObject('file.csv');
$tsvFile->setFlags(SplFileObject::READ_CSV);
$tsvFile->setCsvControl("\t");
$file = fopen('file.csv', 'w');
$header = array('sku', 'qty');
fputcsv($file, $header, ',', '"');
foreach ($tsvFile as $line => $row) {
if ($line > 0) {
if(!isset($newData[$row[0]])) {
$newData[$row[0]] = array('qty'=>0, 'price'=>$row[2]);
}
$newData[$row[0]]['qty'] += $row[1];
}
}
foreach ($newData as $key => $arr) {
fputcsv($file, array($key, $arr['qty'], $arr['price']), ',', '"');
}
fclose($file);
?>
To start with, there's a nice function on the PHP page str_getcsv which will help you end up with a more legible array to work with:
function csv_to_array($filename='', $delimiter=',') {
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
This is purely for legibility sake but now comes the code which would allow you to work over the array.
$aryInput = csv_to_array('file.csv', ',');
$aryTemp = array();
foreach($aryInput as $aryRow) {
if(isset($aryTemp[$aryRow['code'])) {
$aryTemp[$aryRow['code']['qty'] += $aryRow['qty'];
} else {
$aryTemp[$aryRow['code']] = $aryRow;
}
}
In the above code, it simply:
Loops through the input
Checks whether the key exists in a temporary array
If it does, it just adds the new quantity
If it doesn't, it adds the entire row
Now you can write out your expectant csv file :)

insert a 2d array into a csv file in php

I'm trying to insert the 2d array into a csv file
here is my code below
<?php
$cars = array( array("Volvo",100,96), array("BMW",60,59), array("Toyota",110,100));
$fp = fopen('file.xls', 'w');
foreach ($cars as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
but the values are inserted in single row in csv file.
any ideas
EDIT 1:
This version saves it to file without prompting to save and outputs in a table with a slight border. The border in the table is not written to file, it only outputs to screen.
<?php
$fp = fopen('file.xls', 'w');
$cars = array( array(Volvo,100,96), array(BMW,60,59), array(Toyota,110,100));
$titleArray = array_keys($cars[0]);
$delimiter = "\t";
$filename="file.xls";
//Loop through each subarray, which are our data sets
foreach ($cars as $subArrayKey => $subArray) {
//Separate each datapoint in the row with the delimiter
$dataRowString = implode($delimiter, $subArray);
// print $dataRowString . "\r\n"; // prints output to screen
fwrite($fp, $dataRowString . "\r\n");
} // keep this always end of routine
// start of cell formatting
$row = 1;
if (($handle = fopen("file.xls", "r")) !== FALSE) {
echo '<table border="1" cellspacing="0" cellpadding="3">';
while (($data = fgetcsv($handle, 1000, '\t')) !== FALSE) {
$num = count($data);
if ($row == 1) {
echo '<thead><tr>';
}else{
echo '<tr>';
}
for ($c=0; $c < $num; $c++) {
//echo $data[$c] . "<br />\n";
if(empty($data[$c])) {
$value = " ";
}else{
$value = $data[$c];
}
if ($row == 1) {
echo '<th>'.$value.'</th>';
}else{
echo '<td align="center">'.$value.'</td>';
}
}
if ($row == 1) {
echo '</tr></thead><tbody>';
}else{
echo '</tr>';
}
$row++;
}
echo '</tbody></table>';
fclose($handle);
}
?>
EDIT 2:
This version will process the data then prompt to save the file.
Output:
Volvo 100 96
BMW 60 59
Toyota 110 100
PHP code:
<?php
$cars = array( array(Volvo,100,96), array(BMW,60,59), array(Toyota,110,100));
$titleArray = array_keys($cars[0]);
$delimiter = "\t";
$filename="file.xls";
//Send headers
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Pragma: no-cache");
header("Expires: 0");
//Loop through each subarray, which are our data sets
foreach ($cars as $subArrayKey => $subArray) {
//Separate each datapoint in the row with the delimiter
$dataRowString = implode($delimiter, $subArray);
print $dataRowString . "\r\n";
}
?>
1st version:
Output will be:
Volvo
100
96
BMW
60
59
Toyota
110
100
If this is the desired result, then this is the code to accomplish this:
<?php
$cars = array( array(Volvo,100,96), array(BMW,60,59), array(Toyota,110,100));
$fp = fopen('file.xls', 'w');
foreach ($cars as $fields) {
fputcsv($fp, $fields, "\n");
}
fclose($fp);
?>
You need to seperate the contents with comma to write in seperate rows.
$export_arr =$_POST['dataString'];
$fp = fopen('file.xls', 'w');
foreach ($export_arr as $fields) {
fputcsv($fp, $fields,",");
}
fclose($fp);

Categories