I've got a CSV file with product information for a e-commerce platform. The CSV file contains multiple rows with same product ID and multiple description. Each value is seperated by "^" instead of comma.
What i want to achieve is to combine these multiple rows into one and comma seperated and have only 1 row with the product information. So my problem is to combine multiple rows with same attribute.
Here is the formating of the file today
productID^Element^Value<br>
id01^Status^01<br>
id01^edited^2016-01-01<br>
id01^Longdesc^Here goes the description<br>
id01^Longdesc^Here is the second line of description<br>
id01^longdesc^And the third row<br>
id01^image^Link to image 1<br>
This is what i'm looking for to achieve:
ID01, 2016-01-01, Here goes the description Here is the second line of description And the third row, link to image
The other idea is to put structure to an nice XML file.
Hope you guys have some good solutions for this and can help me out.
Thank you!
Please try to bellow code. I am sure this code will work fine.
public function import_product_from_csv() {
ini_set('max_execution_time', 1000);
$fh = fopen('your_csv_file.csv', 'r');
fgets($fh, 4096);
while (!feof($fh)) {
$buffer = fgets($fh, 4096);
$arrTemp = explode('^',$buffer);
if($arrTemp[0] != "") {
$data = array(
'productID' => $arrTemp[0], // codice provincia
'Element' => $arrTemp[1], //codice comune
'Value' => $arrTemp[2] //denominazione
);
$sql_query = "insert into table_name (productID, Element, Value) values ('".$arrTemp[0]."', '".$arrTemp[1]."', '".$arrTemp[2]."')";
mysql_query($sql_query);
}
/*echo "<pre>";
print_r($arrTemp);
echo "</pre>";*/
}
fclose($fh);
echo "Uploaded";
}
Happy code...
Related
This question already has answers here:
Group subarrays by one column, make comma-separated values from other column within groups
(2 answers)
Closed last month.
I've got an old script from someone that I want to remodel but unfortunately I am not that experienced in PHP. What it does is, it reads article information from a CSV file into an array and then basically posts the output into a HTML table, which can then be saved into a PDF file.
One thing I couldn't quite wrap my head around is, the file provides duplicate lines for an article while only some values changed (size, color etc). The article does have the same name but is not repeated twice in the output, the "new" values are just added to the already existing record and I am quite unsure how to do that. Let me give you a simplified example:
CSV Example:
ArtNo,Name,Color,Size
DEF270, Fingal, Stellar, 3XL
DEF270, Fingal, White, 4XL;
So, in a regular loop, the output would be like this
ArtNo
Name
Color
Size
DEF270
Fingal
Stellar
3XL
DEF270
Fingal
White
4XL
What I would need is this
ArtNo
Name
Color
Size
DEF270
Fingal
Stellar, White
3XL, 4XL
Can you guys give me a hint on how to achieve this?
Let you loaded data from CSV to plain array. After this you can apply array_reduce in next way:
$res = array_reduce(
$rows,
function($res, $row) {
if (isset($res[$row[0]])) {
$res[$row[0]][1] .= ", $row[1]";
$res[$row[0]][2] .= ", $row[2]";
$res[$row[0]][3] .= ", $row[3]";
}
else $res[$row[0]] = $row;
return $res;
},
[]
);
var_export($res);
PHPize - run php code online
You can process the whole file by grouping the article number and add the properties to each an array. On output you implode them comma delimited.
$csv = <<<'_CSV'
ArtNo,Name,Color,Size
DEF270, Fingal, Stellar, 3XL
DEF270, Fingal, White, 4XL;
_CSV;
$csv_handle = fopen('php://memory', 'rw');
$fwrite = fwrite($csv_handle, $csv);
fseek($csv_handle, 0);
$articles = [];
while (($data = fgetcsv($csv_handle)) !== false) {
[$articleNumber, $name, $color, $size] = array_map('trim', $data);
if (!isset($articles[$articleNumber])) {
$articles[$articleNumber] = [
'names' => [$name],
'colors' => [$color],
'sizes' => [$size],
];
continue;
}
$article = &$articles[$articleNumber];
if (!in_array($name, $article['names'])) {
$article['names'][] = $name;
}
if (!in_array($color, $article['colors'])) {
$article['colors'][] = $color;
}
if (!in_array($size, $article['sizes'])) {
$article['sizes'][] = $size;
}
unset ($article);
}
fclose($csv_handle);
echo "<table>\n";
foreach ($articles as $articleNumber => $article) {
$names = implode(', ', $article['names']);
$colors = implode(', ', $article['colors']);
$sizes = implode(', ', $article['sizes']);
echo "<tr><td>$articleNumber</td><td>$names</td><td>$colors</td><td>$sizes</tr>\n";
}
echo "</table>\n";
Output
<table>
<tr><td>ArtNo</td><td>Name</td><td>Color</td><td>Size</tr>
<tr><td>DEF270</td><td>Fingal</td><td>Stellar, White</td><td>3XL, 4XL;</tr>
</table>
What I need to do is to be able to move the first row from a testdata.csv every time I run the .php to another .csv with the name testdata_new.csv(appending data).
This is an example of data that includes Name, Age, Job
Example data testdata.csv:
John,32,Scientist
Mary,25,Employer
Nick,36,Designer
Miky,46,Sales
Alex,29,Logistics
This is what the .php will do running it:
Cut the first row from testdata.csv(john,32,scientist) and paste it to the new testdata_new.csv under the first row(header) that will always be "Name Age Job".
Save testdata_new.csv and testdata.csv with the remaining rows.
I did some tests but I'm still far away from the solution.
<?php
$file = "testdata.csv";
$f = fopen($file, "r");
$i = 0;
$file2 = str_replace(".csv", "_new.csv", $file);
$f2 = fopen($file2,"a");
while ($i<2) {
$record = fgetcsv($f);
foreach($record as $field) {
echo $field . "<br>";
}
$i++;
}
fwrite($f2,fread($f, filesize($file)));
fclose($f);
fclose($f2);
?>
Executing the script will display the first row of the template.csv file
and will produce another file with the name template_new.csv with the following rows:
Mary,25,Employer
Nick,36,Designer
Miky,46,Sales
Alex,29,Logistics
What I really need to have in the template_new.csv file is only the first row displayed:
John,32,Scientist
And save again the template.csv without the first row as the idea is to cut and paste the rows, as following:
Mary,25,Employer
Nick,36,Designer
Miky,46,Sales
Alex,29,Logistics
Thank you all in advance for your help!
As easy as this ;-)
$old_file = 'testdata.csv';
$new_file = 'testdata_new.csv';
$file_to_read = file_get_contents($old_file); // Reading entire file
$lines_to_read = explode("\n", $file_to_read); // Creating array of lines
if ( $lines_to_read == '' ) die('EOF'); // No data
$line_to_append = array_shift( $lines_to_read ); // Extracting first line
$file_to_append = file_get_contents($new_file); // Reading entire file
if ( substr($file_to_append, -1, 1) != "\n" ) $file_to_append.="\n"; // If new file doesn't ends in new line I add it
// Writing files
file_put_contents($new_file, $file_to_append . $line_to_append . "\n");
file_put_contents($old_file, implode("\n", $lines_to_read));
Is it possible to export csv data in to two parts:
From the below image i have two things to be considered
1. summery
2. Detail information
I worked with only 2nd type is it possible to do like 2 batches(like shown in image)..?
please suggest any alternate idea if you got.
Example:
summary header
$titleSummery = array('Course Name','Average watched','semi watched','notwached','sudents attempted','sudents notattempted','Total students','Branch','passout');
/*summery data */
Details header
$titleDetail = array('student','passout','branch','percentage watched','student email');
/*Details data */
In this case how can i export the data..?
$output = fopen('php://output', 'w');
fputcsv($output, $title);
foreach($data as $k=>$res){
fputcsv($output,$res);
}
You need to prepare array for each line. see my inline comments.
$titleSummery = array('Course Name','Average watched','semi watched','notwached','sudents attempted','sudents notattempted','Total students','Branch','passout');
$titleSummeryData = array('Number System','50%','40%',....); // fill remaining data.
$output = fopen('php://output', 'w');
// put first table
foreach($titleSummery as $key=>$val){
fputcsv($output,array($val,$titleSummeryData[$key]));
}
// begin second table
// put all title/header
fputcsv($output,$titleDetail);
// For second table i assume that you have data in 2D array
foreach($titleDetailsData as $row){
fputcsv($output);
}
fclose($output);
You direction is good, you just need to understand that each call to fputcsv prints a line, so you'll need to call it for each row in the first batch of data also, for example:
fputcsv($output,"course name","php for dummies");
I'm trying to display only the rows that contain a specific word in a specific column. Basically I would like to show only the rows that have "yes" in the Display column.
First_Name, Last_Name, Display
Kevin, Smith, yes
Jack, White, yes
Joe, Schmo, no
I've been trying various things with fgetcsv & str_getcsv from other answers and from php.net but nothing is working so far.
It doesn't do anything but this is my current code:
$csv = fopen('file.csv', 'r');
$array = fgetcsv($csv);
foreach ($array as $result) {
if ($array[2] == "yes") {
print ($result);
}
}
Let's have a look at the documentation for fgetcsv():
Gets line from file pointer and parse for CSV fields
fgetcsv reads a single line, not the whole file. You can keep reading lines until you reach the end of the file by putting it in a while loop, e.g.
<?php
$csv = fopen('file.csv', 'r');
// Keep looping as long as we get a new $row
while ($row = fgetcsv($csv)) {
if ($row[2] == "yes") {
// We can't just echo $row because it's an array
//
// Instead, let's join the fields with a comma
echo implode(',', $row);
echo "\n";
}
}
// Don't forget to close the file!
fclose($csv);
You should use data tables.
https://datatables.net/examples/basic_init/zero_configuration.html
That's how I deal with my textfiles. But be carefull, with a large amount of Data (> 10000 rows) you should have a loog at the deferRender option.
https://datatables.net/reference/option/deferRender <-- JSON DATA required.
This is a totally experimental question, but if answered it will save me hours of manual HTML mark up.
In theory it should work, but can appreciate advice if I'm talking rubbish.
I need a loop to pull column data from columns in a CSV spreadsheet, and echo them in HTML mark up.
I can't write PHP but this is how I envisage the loop work...
<?php
// here it needs to load the CSV file and get the column data and output them as variables (I guess)
echo <div id="interactive-map">
// here a loop needs to begin to output this line off HTML...
// with the arrayed variables...
<div id="[varible-1]" class="[varible-2]" title="[varible-3]"><span>[varible-3]</span></div>
// loop finished once no more rows left in CSV
echo </div>
?>
So the result should look like this...
<div id="interactive-map">
<div id="1" class="free" title="Uber"><span>Uber</span></div>
<div id="2" class="free" title="Howdy"><span>Howdy</span></div>
<div id="3" class="free" title="Love"><span>Love</span></div>
<div id="4" class="free" title="Gimme"><span>Gimme</span></div>
<div id="5" class="free" title="Totally"><span>Totally</span></div>
<div id="6" class="free" title="Spank"><span>Spank</span></div>
</div>
The CSV files looks like this...
(source: motocom.co.uk)
Any help or advice would be TRULY amazing! Thanks
// UPDATE BELOW FOLLOWING FIRST ANSWER
My CSV below viewed as text...
id,class,name
1,free,Uber
2,free,Howdy
3,free,Love
4,free,Gimme
5,free,Totally
6,free,Spank
The PHP below...
<?php
$file = fopen('file.csv', 'r');
$fields = array();
if ($file) {
while (($data = fgetcsv($file)) !== false) {
if(empty($fields)) {
$fields = $data;
continue;
}
$row = array_combine($fields, $data);
$output = sprintf("% is ID, % is CLASS, % is NAME",
$row['id'],
$row['class'],
$row['name']);
echo $output;
}
fclose($file);
}
?>
It's not quite working properly, what am I doing wrong?
With regards to adding the HTML, I put the mark up inside where the echoed text is and it gets confused :-/
It is echoing stuff but not the desired info from the csv.
To read the file, the easiest is to use the built-in fgetcsv in a loop. You can cook up your own parsing code, but it's really thankless work to make it behave correctly in the presence of field delimiters and escaped characters.
After reading the names of the CSV fields (first iteration) and their values for each row (subsequent iterations), you can use sprintf or vsprintf to easily construct an HTML string to output.
For example:
$file = fopen('php://stdin', 'r'); // or open any other file you want
$fields = array(); // this holds the name of the fields, read from the 1st row
if ($file) {
while (($data = fgetcsv($file)) !== false) {
// If this is the first row, we assume it holds field names.
// So just remember what they are and loop to the next.
if(empty($fields)) {
$fields = $data;
continue;
}
// Subsequent rows are assumed to contain data.
// array_combine associates the data in the current row with the field
// names from the first row, allowing us to refer to them using those
// names and be independent of the order the fields appear in the input.
$row = array_combine($fields, $data);
// Format output conveniently with sprintf
$output = sprintf("%s is %d years old.\n",
$row['name'],
$row['age']);
echo $output;
}
fclose($file);
}
See it in action.