I'm trying to write some php-code that takes $_GET-data as an input and saves it into a csv-file.
When running the code more than once my csv-file looks like this:
Date,Time,Temperature,"Air Humidity","Soil Humidity",Light,"Wind Direction","Wind Speed",Rain
2013-03-16,16:24:27,12,80,40,82,255,10,0
"2013-03-16,16:24:26,12,80,40,82,255,10,0
","""2013-03-16,16:24:26,12,80,40,82,255,10,0
",""",""""""2013-03-16,16:24:25,12,80,40,82,255,10,0
",""","""""",""""
",""",""""""
","""
"
As you can see, the program adds quotation marks and commas into my data that I don't want. This is apparently done by 'file("weather_data.csv")' but I don't know how to disable or work around this.
This is my code for now:
<?php
// Save received data into variables:
$temperature = $_GET["t"];
$airHumidity = $_GET["ha"];
$soilHumidity = $_GET["hs"];
$light = $_GET["l"];
$windDir = $_GET["wd"];
$windSpeed = $_GET["ws"];
$rain = $_GET["r"];
// Arrays for the column descriptor (first line in the csv-file) and the recent data:
$columnDescriptor = array("Date","Time","Temperature","Air Humidity","Soil Humidity","Light","Wind Direction","Wind Speed","Rain");
$recentData = array(date("Y-m-d"),date("H:i:s"),$temperature,$airHumidity,$soilHumidity,$light,$windDir,$windSpeed,$rain);
$fileContents = file("weather_data.csv");
array_shift($fileContents); // removes first field of $fileContents
$file = fopen("weather_data.csv","w");
fputcsv($file,$columnDescriptor);
fputcsv($file,$recentData);
fputcsv($file,$fileContents);
fclose($file);
?>
$fileContents is read as an array of strings, one entry per line of the CSV file but the actual CSV data is not parsed. The last fputcsv tries to write this data as CSV and escapes it (adding quotes and stuff). You need to add the old file contents ($fileContents) to your file with fwrite instead of fputcsv:
fwrite($file, implode("\n", $fileContents));
Related
I have a csv file that have data like this:
Sub District District
A Hi อาฮี Tha Li District ท่าลี่
A Phon อาโพน Buachet District บัวเชด
when I tried to read it using php code by following this SO question:
<?php
//set internal encoding to utf8
mb_internal_encoding('utf8');
$fileContent = file_get_contents('thai_unicode.csv');
//convert content from unicode to utf
$fileContentUtf = mb_convert_encoding($fileContent, 'utf8', 'unicode');
echo "parse utf8 string:\n";
var_dump(str_getcsv($fileContentUtf, ';'));
But it didn't work at all. Someone please let me know what I am doing wrong here.
Thanks in advance.
There are 2 issues with your code:
Your code applies str_getcsv to whole file contents (instead of individual line)
Your code example is using delimiter ";" but there is no such symbol in your input file.
Your data is in either fixed field length format (which is actually not a csv file) or in tab delimited csv file format.
If it is tab delimited file format then you can use 2 ways to read your file:
$lines = file('thai_unicode.csv');
foreach($lines as $line){
$data = str_getcsv($line,"\t");
echo "sub_district: ". $data[0].", district: ".$data[1]."\n";
}
or
$f = fopen('thai_unicode.csv',"r");
while($data = fgetcsv($f,0,"\t")){
echo "sub_district: ". $data[0].", district: ".$data[1]."\n";
}
fclose($f);
And in case you have fixed length fields data format you need to split each line yourself because csv related php function are not suitable for this purpose.
So you will end up with something like this:
$f = fopen('thai_unicode.csv',"r");
while($line = fgets($f)){
$sub_district = mb_substr($line,0,20);
$district = mb_substr($line,20);
echo "sub_district: $sub_district, district: $district\n";
}
fclose($f);
I am taking data from a form and saving it in a CSV file using PHP. My one field in the form contain the comma in it, i.e., between two words a comma is there and I need to store that in the CSV file with a comma. But when I an saving it the values left and right to comma are stored in different rows. How can I do it?
My code is:
enter code here
<?php
//read data from form
$food = filter_input(INPUT_POST, "food");
$output = $food . "\n";
$fp="input.csv";
if (file_exists($fp)) {
file_put_contents($fp, $output, FILE_APPEND);
}
else {
file_put_contents($fp, $output);
}
?>
By default, CSV files use the comma as the field separater, so if the value contains any commas, it needs to be quoted in the same way it should be if it contains spaces. If using "file_put_contents", you need to do that manually with something like this:
<?php
//read data from form
$food = filter_input(INPUT_POST, "food");
$output = preg_match('/[, ]/', $food) ? "\"$food\"\n" : "$food\n";
file_put_contents('input.csv', $output, FILE_APPEND);
?>
The "preg_match" function checks $food for commas or spaces and if any are found, $food is double quoted and the linefeed is added, otherwise only the linefeed is added.
Note also that you don't need to check if the file already exists, because if it doesn't, the file_put_contents function automatically creates it whether or not you use the FILE_APPEND flag.
But a much better solution would be to use the CSV specific functions which do any necessary quoting or escaping for you automatically:
<?php
//read data from form
$food = filter_input(INPUT_POST, "food");
$fields = array($food);
$fp = fopen('input.csv', 'a+');
fputcsv($fp, $fields);
fclose($fp);
?>
Using fopen in "a+" mode causes it to act the same as file_put_contents does with the FILE_APPEND flag. So there's no need to check if the file exists beforehand here either.
I have created a form and able to add data to CSV on submit. But my code is such that the csv file is delimited by commas and so when I add comma in the form data, the php code separates it as another entry (column).
Here is my php code:
<?php
$filename = "data.csv";
$string = $_POST['element_1'].",".$_POST['element_2'].",".$_POST['element_3'].",".$_POST['element_4_1']."-".$_POST['element_4_2']."-".$_POST['element_4_3'].",".$_POST['element_5']."\n";
if (file_exists($filename)) {
$file = fopen($filename, "a");
fwrite($file, $string);
} else {
$file = fopen($filename, "a");
fwrite($file, '"Name","Phone","No. of persons","Date","Venue"\n');
fwrite($file, $string);
}
fclose($file);
?>
In the above code, Venue sometimes, takes 'commas'. But the code separates the Venue data into new columns.
So, is there any other way to enter data into excel sheet other that CSV or any code gimmick.
You can make your life easier by using fputcsv and fgetcsv.
fputcsv lets you specify the delimiter and enclosure you need. The big difference is that you must pass the fields as an array: each value of the array is a column value in the csv line.
So given a $fields array that contains your CSV line values:
$file = fopen( 'data.csv', 'a' );
fputcsv( $file, $fields, ',', '"' );
fclose( $file );
Important: the flag on fopen must be a in order to append to the file. If you use w you will overwrite the previous content.
I use the following code to get data from a form and save it as csv.
$cvsData = $name . "," . $address . "\n";
$fp = fopen("file.csv", "a");
if ($fp) {
fwrite($fp, $cvsData); // Write information to the file
fclose($fp); // Close the file
}
When someone enters a comma or line break in address field it breaks the formatting. So how can i escape it so that the whole address stays in the same field ?
Put each data item inside quotation marks. A pair of quotation marks inside a quoted value signifies a single quotation mark. e.g.
"Daniel Norton","Congress Ave.
Austin (""Keeping it weird""), TX"
Referring to your example:
$data = str_replace('"','""',$data);
$address = str_replace('"','""',$address);
$cvsData = "\"$data\",\"$address\"\n";
Better still, just use the PHP function fputcsv.
fputcsv($fp,array($data,$address));
CSV is totally dependent on the software used to read it.
Have a look at http://www.csvreader.com/csv_format.php for some details on how certain programs expect CSV data.
I have created a CSV class that can handle most of these situations. You might want to have a look at it.
https://gist.github.com/1786683
And to answer your question, using that class you could
$csv = CSV::newExcel();
$cvsData = $csv->row($name, $address);
// etc...
I'm creating a script that will read a csv file and display it on a textarea using fgetcsv.
$handle = #fopen($filePath, "r");
if ($handle)
{
while (($buffer = fgetcsv($handle, 1000,",")) !== false)
{
foreach($buffer as $buff){
echo $buff."\n";
}
}
}
The format of the csv is
"line1-content1","line1-content2"
"line2-content1","line2-content2"
Using fgetcsv, the content will display inside the textarea without double-quote and comma. Can I format it so that it will also display the duoble quotes and comma?
Then upon saving it using fputcsv
$file_to_load = $_GET['filepath'];
$filePath = $dir.$file_to_load;
$trans = trim($_POST['txtarea']);
$keyarr = split("\n",$trans);
$fp = fopen($filePath, 'w');
foreach (array ($keyarr) as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
Looking on the csv file, it saved the csv but displays it like this
"line1-content1
","line1-content2
","line2-content1
","line2-content2"
It separates the "line1-content1" and "line1-content2" into two lines and put a comma after the end of every line.
Now I want to keep the formatting of #2. How will I code it?
Can you guide me into the right direction? Thanks!
Sounds like you want to display the actual raw CSV text, not the parsed data within the CSV. Instead of using fgetcsv(), just use fgets() and you'll get the text line without any parsing, preserving the quotes and commas.
As for fputcsv, it's going to write out what you pass into it, so make sure that whatever's coming back from the form is cleaned up (e.g. extra line breaks stripped out).