csv file semicolon separated - issue with comma in field - php

I have a csv file where fields are separated by semicolons. Inside each field we can have comma (decimal separator for numbers in italy is comma).
a sample data is:
15/01/2021;15/01/2021;ADDEBITO SDD;PAGAMENTO NEXI 8000640000030620818186 NEXI S.P.A. CORSO SEMP - ADDE BITO SPESE CARTA DI CREDITO ESTRATTO CONTO DEL : 31/ 12/2020 - UNCRITMMXXX IT500040000004107060966;1.501,2;;Uscita;
I explode this line by semicolon and then build a table row out of it:
while (($line = fgetcsv($f)) !== false) {
$row = $line[0];
$cells = explode(";",$row);
echo "<tr>";
foreach ($cells as $cell) {
echo "<td>";
echo htmlspecialchars($cell);
echo "</td>";
$cur_col_num+=1;
}
echo "</tr>\n";
The issue I have is that the string "1.501,2" is echoed as 1.501 loosing the decimals.
If the source is "1501.2" this is echoed correctly as "1501.2".
How do I keep the decimal if the separator is a comma? I have no control over the content of the csv that is coming from different sources and so I need to handle both situations.
EDIT: after some more tests I realized that actually for any line containg the comma it stops processing the line after the comma (ignoring the following fields). So in the example I never see "Uscita" in its table cell
EDIT 2: this is the output of my code on the browser for this specific line

CSV means "comma separated values", so fgetcsv() splits the line at , characters by default. Your file uses ; as the field separators, so you should tell fgetcsv() to use that instead.
Then you don't need to call explode() yourself.
while ($cells = fgetcsv($f, null, ';')) {
echo "<tr>";
foreach ($cells as $cell) {
echo "<td>";
echo htmlspecialchars($cell);
echo "</td>";
$cur_col_num+=1;
}
echo "</tr>\n";
}

Related

PHP - Add newline to table cell with multiple lines [duplicate]

This question already has an answer here:
How to force PHP to read newlines and returns as <br>
(1 answer)
Closed 4 years ago.
I am having trouble creating a new line in a HTML table cell. The data is coming from a CSV file and each cell has multiple lines. I tried using '\n', '\r'but it's not working. I searched the forums but haven't found a solution. Any suggestions on how I can achieve this? Should I use a different function? Thanks..
The CSV Looks like this:
header,header,header,header,header
,,,,"title
aaaaaaa
bbbbbbb
ccccccc","title
ddddddd"
The code I am using outputs the file like this:
header header
title aaaaaaa bbbbbbb title ddddddd
ccccccc
I want it to output like this:
header header
title title
aaaaaaa ddddddd
bbbbbbb
ccccccc
The code I am using is from this thread: Dynamically display a CSV file as an HTML table on a web page
<?php
echo "<html><body><table>\n\n";
$f = fopen("my.csv", "r");
while (($line = fgetcsv($f, 0)) !== false) {
echo "<tr>";
foreach ($line as $cell) {
echo "<td>" . htmlspecialchars($cell) . "</td>";
}
echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
?>
I ended up using nl2br. Working code below.
<?php
echo "<html><body><table>\n\n";
$f = fopen("my.csv", "r");
while (($line = fgetcsv($f, 0)) !== false) {
echo "<tr>";
foreach ($line as $cell) {
echo nl2br("<td>" . htmlspecialchars($cell) . "\n" . "</td>");
}
echo "</tr>\n";
}
fclose($f);
echo "\n</table></body></html>";
?>
You can try the predefined constant PHP_EOL, which is «the correct 'End Of Line'» following the php docs.
In fact, "\n" is a typical unix end of line, and most windows don't well understand it. Php will take care of that with PHP_EOL.
echo "</tr>".PHP_EOL;
You can also try to use heredoc (EOF)
http://php.net/manual/en/reserved.constants.php
http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

PHP read text file and display formatted results

My goal is to use PHP to read data from a text file and display a page based on said data.
The text file would look something like this...
joe smith|ceo|chief executive officer|10|14|126
Jane Doe|cfo|chief financial officer|8|12|94
What I need to be able to do is read the text file, extract each of the values, separated by the "|" token, and format the output in a table-like display. When reading the text file, the first column (name) equates to a picture, located in a subfolder. Therefore, the output should look something like this...
Can anyone out there assist with this request?
Thanks in advance.
You need something like that:
I would save the Data in this example in a file called test.csv
But I think you get some problems with the first row. A Space in the src of the img-Tag....
I would replace the space from the Name with str_replace() in the PHP
and the space in the name of the Pictures with Underscrore "_"
<?php
echo '<table>';
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "|")) !==false) {
$num = count($data);
//print_r($data);
echo "<tr> ";
$row++;
for ($c=0; $c <= $num; $c++) {
if ($c==0){
echo '<td><img src="YOUR/SUBFOLDER/"'.$data[$c]
."/>".$data[$c].'</td>';
}else{
echo '<td>'.$data[$c] .'</td>';
}
}
echo "</tr> \n";
}
fclose($handle);
echo '</table>';
}
?>
Hope It Helps :-).
Sorry for my bad english

phpexcel read 18 digitals long number from cell

I use phpexcel read and import a CSV file one of which cells is a 18 digits long, like 123456789123456789, though I use ini_set("precision", "18"); but the value I get is not correct. How to solve this problem?
ini_set("precision", "20");
$objReader = PHPExcel_IOFactory::createReader('CSV')
->setDelimiter(',')
->setInputEncoding('GBK')
->setEnclosure('"')
->setLineEnding("\r\n")
->setSheetIndex(0);
$objPHPExcel = $objReader->load($file);
$worksheet = $objPHPExcel->getActiveSheet();
foreach ($worksheet->getRowIterator() as $row) {
echo 'Row number: ' . $row->getRowIndex() . "\r\n<br>";
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
foreach ($cellIterator as $cell) {
if (!is_null($cell)) {
echo 'Cell: ' . $cell->getCoordinate() . ' - ' . (string)$cell->getValue() . "\r\n<br>";
}
}
}
In comments you mentioned that the wrong output has two additional zeroes. This is surely caused by a wrong interpretation of a decimal separator, so that it is treated as a thousands separator.
Change your PHP server's regional settings so it uses the point as the decimal separator -- you might need to change your thousands separator as well (if it currently is a point).
Convert the long integer to string you can read the value
$value = 123456789123456789;
$value = (string)$value;
Last Try
$keyCell = $sheet->getCellByColumnAndRow(1,5)->getFormattedValue();
now replace the $cell->getvalue() into $keyCell
and
Here 1,5 is static column and row, In your code you have to use it dynamically

how to create table with dynamic column using php

Suppose there is a number of item in array.which may be odd or even like I have an array which contain item from a to z Now I want to display that item in table . But As you know That There are 23 alphabets I want to display these alphabets in table which contains only 5 column in the last you got only three alphabets I want to display them in table . In the last I want that there should be three column not 5.
Here is my code i could not get that what should i do?
But the problem I faced in the below code is that the second loop is not correct.
<?php
$arr=array('a','b','c','d','e','f','g','h');
$count= sizeof($arr);
$row=ceil($count/5);
echo "<table border='1'>";
for($r=0;$r<$row;$r++){
echo "<tr>";
for($j=0;$j<=5;$j++){
echo "<td>'".$arr[$j]."'</td>";
}
echo "</tr>";
}
echo "</table>";
?>
My approach uses array_slice to take out pieces of the source and build rows:
$arr=array('a','b','c','d','e','f','g','h');
$offset = 0;
$num_columns = 5; //adjust number of columns
$table_html = "<table border='1'>";
while($slice = array_slice($arr,$offset,$num_columns)){
$offset += $num_columns;
$row_html = '';
foreach($slice as $n) $row_html .= "<td>$n</td>";
$table_html .= "<tr>$row_html</tr>";
}
$table_html .= '</table>';
echo $table_html;
Live demo
Try below code. Declaring number of column required in a variable, so which can be changed any time. closing the tr tag when loop count is same as number of columns to be displayed.
<?php
$arr=array('a','b','c','d','e','f','g','h');
$columnLength = 5;
echo "<table border='1'>";
echo "<tr>";
for($r=0;$r<count($arr) ; $r++){
echo "<td>'".$arr[$r]."'</td>";
if($r + 1 == $columnLength ) {
echo "</tr>";
}
}
echo "</table>";
?>

Problem with .csv file and missed comma(s)

Hi all I have a problem with CSV opening through PHP code. My PHP code is:
<?php
header("Content-Type: text/html; charset=windows-1251");
echo "<html>
<head>
<title></title>
</head>
<body>
";
$file = "import.csv";
if(file_exists($file)) {
if (($fopen = fopen($file, "r")) !== FALSE) {
echo "<table>\n";
while (($data = fgetcsv($fopen, 1024, ",")) !== FALSE) {
$max = count($data);
$num++;
echo "<tr>\n<td>".$num."</td>\n";
for ($i=0;$i<$max;$i++) {
echo "<td>".$data[$i]."</td>\n";
}
echo "</tr>\n";
}
echo "</table>";
fclose($fopen);
}
}
else {
echo "File doesn't exists!";
}
echo "
</body>
</html>";
?>
The problem isn't in PHP code, the problem is in .csv file. PHP code must work even if there is missing comma, when it show the information the normal way.
The .csv file:
First name,Family,Sex,Date of birth,City,Phone number
One, Ofamily, Male, 1975, LA,13-25-16
Two, Tfamily, Male, 1955, LV, 555-14345
Three, Thfamily, Male, 1958, NY, 15689
Four, Ffamily, Female, 1974, SF, 5897912
Five, Fifamily, Male, 1991, LA, 123456789
Six, Sfamily, Male, 1967, 9876542
Seven, Sefamily, Female,, SF,
<?php
header("Content-Type: text/html; charset=windows-1251");
echo "<html>
<head>
<title></title>
</head>
<body>
";
$file = "import.csv";
if(file_exists($file)) {
if (($fopen = fopen($file, "r")) !== FALSE) {
echo "<table>\n";
while (($data = fgetcsv($fopen, 1024, ",")) !== FALSE) {
$num++;
echo "<tr>\n<td>".$num."</td>\n";
foreach($data as $k => $v) {
switch ($k) {
case 0 : // first name
case 1 : // family
case 2 : // sex
case 4 : // city
if (is_numeric($v)) {
array_splice($data,$k,0,'');
}
break;
case 3 : // date of birth
case 5 : // phone number
if (!is_numeric($v)) {
array_splice($data,$k,0,'');
}
break;
}
}
foreach($data as $v) {
echo "<td>".$v."</td>\n";
}
echo "</tr>\n";
}
echo "</table>";
fclose($fopen);
}
}
else {
echo "File doesn't exists!";
}
echo "
</body>
</html>";
?>
If you don't have control of the incoming CSV, you're not going to be able to use fgetcsv. How is it supposed to know if there's a missing ,?
Unfortunately, you're going to have to write your own function to handle this. I would start by reading each line into an array. Then looping through the line and explodeing them by a comma. Then, you'll have to check each value and try to determine if somethings missing from the resulting array.
Let's look at the problematic line in your example.
Six, Sfamily, Male, 1967, 9876542
Here's what we know about it:
It contains one less value then all the rest, so we should run some data consistency checks on it.
We know the first and second values are going to be strings that do not equal "Male" or "Female".
We know the third value should always equal either "Male" or "Female".
We know the fourth value is going to be a year and should always be a numerical value.
We know the fifth value is missing and it should be a city code and will always be two letters in length.
Based on that information, you should be able to write some checks to determine if one of those values doesn't equal what you'd expect, and then fix it.
The problem is most likely to do with lines like:
Six, Sfamily, Male, 1967, 9876542
Where there is no city information. In this case, you'll never get "9876542" to show up in the phone column unless you apply some logic to determine that this isn't the city, and to skip to the next column. What you should do though, so that you have 6 columns in each row, is that instead of resetting $max every time, you should just set it once after reading the header. Then display that number of columns from each row you read.

Categories