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 trying to convert a tab delimited file to csv. The problem is its a huge file. 100000 plus records. And i want only specific columns from that file. The file is not generated by me but by amazon so i cant really control the format.
The code i made works fine. But i need to ignore/remove some columns or rather i want only few columns from that. How do i do that without effecting the performance of conversion from txt to csv.
$file = fopen($file_name.'.txt','w+');
fwrite($file,$report);
fclose($file);
$handle = fopen($file_name.".txt", "r");
$lines = [];
$row_count=0;
$array_count = 0;
$uid = array($user_id);
if (($handle = fopen($file_name.".txt", "r")) !== FALSE)
{
while (($data = fgetcsv($handle, 100000, "\t")) !== FALSE)
{
if($row_count>0)
{
$lines[] = str_replace(",","<c>",$data);
array_push($lines[$array_count],$user_id);
$array_count++;
}
$row_count++;
}
fclose($handle);
}
$fp = fopen($file_name.'.csv', 'w');
foreach ($lines as $line)
{
fputcsv($fp, $line);
}
fclose($fp);
I am using unset to remove any column. But is there a better way ? for multiple columns.
I would do that by checking keys. For example:
// columns keys you don't wanna skip
$keys = array(0, 1, 3, 4, 7, 9);
$lines = file($file_name);
$result_lines = array();
foreach ($lines as $line) {
$tmp = array();
$tabs = explode("\t", $line);
foreach($tabs as $key => $value){
if(in_array($key, $keys)){
$tmp[] = $value;
}
}
$result_lines[] = implode(",", $tmp);
}
$finalString = implode("\n", $result_lines);
// Then write string to file
Hope it helps.
Cheers,
SiniĊĦa
In its simplest form i.e. without worrying about removing columns from the output this will do a simple read line and write line, therefore no need to maintain any memory hungry arrays.
$file_name = 'tst';
if ( ($f_in = fopen($file_name.".txt", "r")) === FALSE) {
echo 'Cannot find inpout file';
exit;
}
if ( ($f_out = fopen($file_name.'.csv', 'w')) === FALSE ) {
echo 'Cannot open output file';
exit;
}
while ($data = fgetcsv($f_in, 8000, "\t")) {
fputcsv($f_out, $data, ',', '"');
}
fclose($f_in);
fclose($f_out);
This is one way of removing the unwanted columns
$file_name = 'tst';
if ( ($f_in = fopen("tst.txt", "r")) === FALSE) {
echo 'Cannot find inpout file';
exit;
}
if ( ($f_out = fopen($file_name.'.csv', 'w')) === FALSE ) {
echo 'Cannot open output file';
exit;
}
$unwanted = [26,27]; //index of unwanted columns
while ($data = fgetcsv($f_in, 8000, "\t")) {
// remove unwanted columns
foreach($unwanted as $i) {
unset($data[$i]);
}
fputcsv($f_out, $data, ',', '"');
}
fclose($f_in);
fclose($f_out);
Hello i have small problem with converting json to csv.
Here is my code:
$jsonString = '{"cod":"200","calctime":0.3107,"cnt":15,"list":[{"id":2208791,"name":"Yafran","coord":{"lon":12.52859,"lat":32.06329},"main":{"temp":9.68,"temp_min":9.681,"temp_max":9.681,"pressure":961.02,"sea_level":1036.82,"grnd_level":961.02,"humidity":85},"dt":1485784982,"wind":{"speed":3.96,"deg":356.5},"rain":{"3h":0.255},"clouds":{"all":88},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]}]}';
//Decode the JSON and convert it into an associative array.
$jsonDecoded = json_decode($jsonString, true);
//Give our CSV file a name.
$csvFileName = 'file.csv';
//Open file pointer.
$fp = fopen($csvFileName, 'w');
//Loop through the associative array.
foreach($jsonDecoded as $row){
//Write the row to the CSV file.
fputcsv($fp, $row);
}
//Finally, close the file pointer.
fclose($fp);
?>
I have tried with another json format like this [{"name":"Wayne","age":28},{"name":"John","age":21},{"name":"Sara","age":24}] and its working perfect.
How to modify my code to save it correctly in csv format.
Pictures:
Now it save it like this:
I need to save it like this:
Can someone help me ?
Hope this will work..
<?php
$jsonString = '{"cod":"200","calctime":0.3107,"cnt":15,"list":[{"id":2208791,"name":"Yafran","coord":{"lon":12.52859,"lat":32.06329},"main":{"temp":9.68,"temp_min":9.681,"temp_max":9.681,"pressure":961.02,"sea_level":1036.82,"grnd_level":961.02,"humidity":85},"dt":1485784982,"wind":{"speed":3.96,"deg":356.5},"rain":{"3h":0.255},"clouds":{"all":88},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}]}]}';
$jsonDecoded = json_decode($jsonString, true);
$csvHeader=array();
$csvData=array();
jsontocsv($jsonDecoded);
print_r($csvHeader);
print_r($csvData);
$csvFileName = 'file.csv';
$fp = fopen($csvFileName, 'w');
fputcsv($fp, $csvHeader);
fputcsv($fp, $csvData);
fclose($fp);
function jsontocsv($data)
{
global $csvData,$csvHeader;
foreach($data as $key => $value)
{
if(!is_array($value))
{
$csvData[]=$value;
$csvHeader[]=$key;
}
else
{
jsontocsv($value);
}
}
}
Json 2
<?php
$jsonString =file_get_contents("http://samples.openweathermap.org/data/2.5/box/city?bbox=12,32,15,37,10&appid=b1b15e88fa797225412429c1c50c122a1");;
$jsonDecoded = json_decode($jsonString, true);
$csvHeader=array();
$csvData=array();
$csvFileName = 'file.csv';
$fp = fopen($csvFileName, 'w');
$counter=0;
foreach($jsonDecoded["list"] as $key => $value)
{
jsontocsv($value);
if($counter==0)
{
fputcsv($fp, $csvHeader);
$counter++;
}
fputcsv($fp, $csvData);
$csvData=array();
}
fclose($fp);
function jsontocsv($data)
{
global $csvData,$csvHeader;
foreach($data as $key => $value)
{
if(!is_array($value))
{
$csvData[]=$value;
$csvHeader[]=$key;
}
else
{
jsontocsv($value);
}
}
}
try this:
$rowNr = 0;
$prevKey = "";
$target = [];
$iterator = new RecursiveArrayIterator($jsonDecoded['list'][$rowNr]);
iterator_apply($iterator, 'traverseStructure', array($iterator,$prevKey,&$target));
function traverseStructure($iterator, $prevKey, &$target) {
while ( $iterator -> valid() ) {
if ( $iterator -> hasChildren() ) {
$prevKey = $iterator->key();
traverseStructure($iterator -> getChildren(), $prevKey, $target);
}
else {
if(isset($prevKey) && !is_int($prevKey)){
$row1 = $prevKey."/".$iterator->key();
}else{
$row1 = $iterator->key();
}
$row2 = $iterator->current();
$target[$row1] = $row2;
}
$iterator -> next();
}
}
fputcsv($fp, array_keys($target));
fputcsv($fp, array_values($target));
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've searched the web and looked through existing answers but cant find a solution to this one. I want to use php to do the following task. Here are my files:
csv file 1: member.csv
member1|john|smith|2009
member2|adam|jones|2007
member3|susie|rose|2002
csv file 2: classes.csv
member1|massage|swimming|weights
member2|gym|track|pilates
member3|yoga|running|stretches
I want to output a third file called file3.csv which merges the two above files together based on the key field which is the member number. the output should be like this:
member1|john|smith|2009|massage|swimming|weights
member2|adam|jones|2007|gym|track|pilates
member3|susie|rose|2002|yoga|running|stretches
the delimiter is a bar character. I want to do this just using php - no other languages.
I would be very greatful for a solution.
Matt
Read both files and store data to the array with keys: member1, ...
Write a new file lines in loop:
foreach ($firstArray as $key => $value1) {
$value2 = $secondArray[$key];
// ...
}
<?php
$data = array();
if (($handle = fopen('file1.csv', 'r')) !== FALSE) {
while (($line = fgetcsv($handle, 0, '|')) !== FALSE) {
$memberId = $line[0];
unset($line[0]);
$data[$memberId] = $line;
}
fclose($handle);
}
if (($handle = fopen('file2.csv', 'r')) !== FALSE) {
while (($line = fgetcsv($handle, 0, '|')) !== FALSE) {
$memberId = $line[0];
unset($line[0]);
$data[$memberId] = array_merge($data[$memberId], $line);
}
fclose($handle);
}
ksort($data); // not needed, but puts records in order by member
if (($handle = fopen('file3.csv', 'w')) !== FALSE) {
foreach($data as $key => $value) {
fwrite($handle, "$key|" . implode('|', $value) . "\n");
}
fclose($handle);
}
Try this. It is untested.
$arr_one = array();
if (($fp = fopen("member.csv", "r")) !== FALSE) {
while (($data = fgetcsv($fp, 1000, ",")) !== FALSE) {
$arr_one[$data[0]] = $data;
}
fclose($fp);
}
$arr_two = array();
if (($fp = fopen("classes.csv", "r")) !== FALSE) {
while (($data = fgetcsv($fp, 1000, ",")) !== FALSE) {
$arr_two[$data[0]] = $data;
}
fclose($fp);
}
$classes_field_count = sizeof(current($arr_two));
$members = array_keys($arr_one);
foreach ($members as $key) {
if (!isset($arr_two[$key])) {
$arr_two[$key] = range(0, ($classes_field_count - 1));
}
unset($arr_two[$key][0]);
$result_arr[$key] = array_merge($arr_one[$key], $arr_two[$key]);
}
if (($fp = fopen("file3.csv", "w")) !== FALSE) {
foreach ($result_arr as $fields) {
fputcsv($fp, $fields, '|');
}
fclose($fp);
}