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);
Related
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
}
}
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>';
}
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);
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 :)
I'm currently using this script:
<?php function jj_readcsv($filename, $header=false) { $handle = fopen($filename, "r"); echo '<table>'; //display header row if true if ($header) {
$csvcontents = fgetcsv($handle);
echo '<tr>';
foreach ($csvcontents as $headercolumn) {
echo "<th>$headercolumn</th>";
}
echo '</tr>'; } // displaying contents while ($csvcontents = fgetcsv($handle)) {
echo '<tr>';
foreach ($csvcontents as $column) {
echo "<td>$column</td>";
}
echo '</tr>'; } echo '</table>'; fclose($handle); } jj_readcsv('partitiontable.csv',true);
?>
I have a CSV table with 8 columns.
I would like to know if it possible to get only on element of the column when making a query. Here is what look like my CSV :
"HEMSI, Alberto",P_000001,P_1,Partition,169864,"Hemsi, Myriam","HEMSI, Alberto","Una matica de ruda",
"HEMSI, Alberto",P_000002,P_2,Partition,169865,"Hemsi, Myriam","HEMSI, Alberto","Ya salio de la mar",
the idea is :
query a value for example: P_1
and get in result: Una matica de ruda
For each line, when asking P_1 getting the value which is in the 8 column.
And the same for P_2
Yes, this is possible using two methods:
At the beginning create an associative array and insert as key the 4th column, and as value with 8th column. Then use this as a lookup table in all further code.
If you don't do 1. , you can make a for loop that goes through the CSV data and looks with IF that the 4th row value is the one you are looking for. When found, return the 8th column value.
Example of first approach with associative array
<?php
$array = array();
jj_readcsv("csv.txt");
echo $array["P_1"]."<br/>";
echo $array["P_2"]."<br/>";
function jj_readcsv($filename, $header = false)
{
global $array;
$row = 1;
if (($handle = fopen($filename, "r")) !== FALSE) {
echo '<table>'; //display header row if true if ($header) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
//print_r($data);
$num = count($data);
echo '<tr>';
for ($c=0; $c < $num; $c++) {
if($row > 1)
echo "<td>$data[$c]</td>";
else
echo "<th>$data[$c]</th>";
if($c==2)
$array[$data[$c]]= $data[7];
}
echo '</tr>';
$row++;
}
fclose($handle);
}
}
?>
Try this:
$row = 1;
$handle = fopen ("teste.csv","r");
$head = Array();
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
//register head rows with names
if($row == 1){
$num = count ($data);
for ($c=0; $c < $num; $c++) {
$colName = trim($data[$c]);
$head[$colName] = $c;
}
}else{
echo $data[$head['COL_NAME']];
}
$row++;
}
fclose ($handle);
This will make var $head an associative array where the key is the col name and value his position in csv, after that you can easy identify what col you want.
Even if you named your function jj_readcsv(), if you look more closely, this name is a liar, the function does much more: opening a file, reading the lines.
If you don't want to separate the concerns but also easily modify it, just make the actual reading method optional:
function jj_readcsv($filename, $header = FALSE, callable $fgetcsv = NULL)
########################
{
$fgetcsv || $fgetcsv = 'fgetcsv';
#################################
$fileHandle = fopen($filename, "r");
if (!$fileHandle) {
return;
}
$csvLine = $fgetcsv($fileHandle);
#####################
echo '<table>';
echo '<tr>';
foreach ($csvLine as $headercolumn) {
echo "<th>$headercolumn</th>";
}
echo '</tr>';
while ($csvLine = $fgetcsv($fileHandle)) {
#####################
echo '<tr>';
foreach ($csvLine as $column) {
echo "<td>$column</td>";
}
echo '</tr>';
}
echo '</table>';
fclose($fileHandle);
}
This little modification allows you to specify the reading function, therefore you can control what is read. So you can inject it as third parameter, for example to only return the eighth column:
jj_readcsv('test.csv', FALSE, function($fileHandle) {
if ($csvLine = fgetcsv($fileHandle))
{
$csvLine = [$csvLine[7]];
}
return $csvLine;
});
Output:
<table><tr><th>Una matica de ruda</th></tr><tr><td>Ya salio de la mar</td></tr></table>