I want to add to new columns to my existing csv file using php.
Therefore I currently have the following code, but that one use column separator , and my existing csv use ; as column separator.
So how can I extend my current code and change the column separator from , to ;?
<?php
$inFile = fopen('test.csv','r');
$outFile = fopen('output.csv','w');
$line = fgetcsv($inFile);
while ($line !== false) {
$line[] = 'third column';
$line[] = 'fourth column';
fputcsv($outFile, $line);
$line = fgetcsv($inFile);
}
fclose($inFile);
fclose($outFile);
In your code provided above, please change:
fputcsv($outFile, $line);
to
fputcsv($outFile, $line, ';'); // default delimiter is "," and ";" provided
Reference: http://php.net/manual/en/function.fputcsv.php
So, your final code will look like:
<?php
$inFile = fopen('test.csv','r');
$outFile = fopen('output.csv','w');
$line = fgetcsv($inFile);
while ($line !== false) {
$line[] = 'third column';
$line[] = 'fourth column';
fputcsv($outFile, $line, ';');
$line = fgetcsv($inFile);
}
fclose($inFile);
fclose($outFile);
Related
I have a text file where contains 1 line with this setting:
2222;3333
two values splitted by ;.
How i can edit "splitted[0]" or "splitted[1]" and save the new values on file?
Below is what i have until now:
<?php
$file_handle = fopen("mytext.txt", "rw");
while (!feof($file_handle) )
{
$line_of_text = fgets($file_handle);
$parts = explode("\n", $line_of_text);
foreach ($parts as $str)
{
$str_parts = explode(';', $str); // Split string by ; into an array
array_shift($str_parts); // Remove first element
echo current($str_parts)."\n"; // echo current element and newline
// Same as $str_parts[0]
}
}
fclose($file_handle);
?>
<?php
$file = '2222;3333'; // that is your file
$file = explode(';', $file); // This split your file with delimiter ";"
foreach ($file as $newFile) {
// Do whatever you want
var_dump($newFile);
}
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);
I've an existing csv file with following values
column1 column2
Fr-fc Fr-sc
Sr-fc Sr-sc
I want to add 2 new columns in it and achieve the following format
column1 column2 column3 column4
Fr-fc Fr-sc 1 2
Sr-fc Sr-sc 1 2
If I use following code it inserts same column header value in column data for the newly created columns
$a = file('amit.csv');// get array of lines
$new = '';
foreach($a as $line){
$line = trim($line);// remove end of line
$line .=";column3";// append new column
$line .=";column4";// append new column
$new .= $line.PHP_EOL;//append end of line
}
file_put_contents('amit2.csv', $new);// overwrite the same file with new data
How I can achieve the above?
Instead of reinventing the wheel, you can use php's inbuilt csv functions fgetcsv and fputcsv respectively to ease your work. First read in each row with fgetcsv and store the data in a multidimensional array:
$delimiter = "\t"; //your column separator
$csv_data = array();
$row = 1;
if (($handle = fopen('test.csv', 'r')) !== FALSE) {
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
$csv_data[] = $data;
$row++;
}
fclose($handle);
}
Next edit the rows to add the extra columns using array_merge:
$extra_columns = array('column3' => 1, 'column4' => 2);
foreach ($csv_data as $i => $data) {
if ($i == 0) {
$csv_data[$i] = array_merge($data, array_keys($extra_columns));
} else {
$csv_data[$i] = $data = array_merge($data, $extra_columns);
}
}
Finally use fputcsv to enter each row into the csv.
if (($handle = fopen('test.csv', 'w')) !== FALSE) {
foreach ($csv_data as $data) {
fputcsv($handle, $data, $delimiter);
}
fclose($handle);
}
You can combine these steps to make your code more efficient by reducing the number of loops.
This approach is less code
<?php
$inFile = fopen('test.csv','r');
$outFile = fopen('output.csv','w');
$line = fgetcsv($inFile);
while ($line !== false) {
$line[] = 'third column';
$line[] = 'fourth column';
fputcsv($outFile, $line);
$line = fgetcsv($inFile);
}
fclose($inFile);
fclose($outFile);
I have this code that stores each line of a csv file into an array:
$tname = myfile.csv
if ($type == 'text/csv'){
$csvData = file_get_contents($tname);
$lines = explode(PHP_EOL, $csvData);
$array = array();
foreach ($lines as $line){
$array[] = str_getcsv($line);
echo $line."<br>";
}
}
How can I store only the entire rows who contains "John is great!" string and discard the others?
You should use strpos() OR preg_match() function.
if (strpos($line, 'John is great!') !== false) {
echo 'true';
}
OR
if (preg_match('/John is great!/i',$line)) // i for case insensitive
echo 'true';
$tname = myfile.csv
if ($type == 'text/csv'){
$csvData = file_get_contents($tname);
$lines = explode(PHP_EOL, $csvData);
$array = array();
foreach ($lines as $line){
if (stripos($line, 'John is great!') !== false) {
$array[] = str_getcsv($line);
echo $line."<br>";
}
}
}
I am assuming that you want a case insensitive match
I have text database
0,Apple,Green
1,Banana,Yellow
2,Cherry,Red
and when I call getdata.php?row=2 I need get data which is 2,cherry,red
I am a bachelor in PHP and I have only one example ,
please help me for this problem.
thanks
$file_handle = fopen("./news.txt", "rb");
while (!feof($file_handle) ) {
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
print $parts[0] . $parts[1] . $parts[2];
}
fclose($file_handle);
This would work and would also stop reading as soon as it found the right line (unlike the other answers who read the whole no file matter what)
if (isset($_GET['row']))
{
$file_handle = fopen("./news.txt", "rb");
$i = 0;
while (!feof($file_handle))
{
if ($i == $_GET['row'])
{
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
print $parts[0] . $parts[1] . $parts[2];
break;
}
$i++;
}
fclose($file_handle);
}
You first have to explode by rule with explode("/n", $txt) than you've an array of each rule. After you stored this explode in to a variable than you should explode a specific value again by ,.
A straightforward way to do this: if record number 2 is always on line number 3.
if (!isset($_GET['row']) || !is_int($_GET['row'])) {
echo "please supply a row number";
die;
}
$lines = file('news.txt');
// assumes record number 2 is on line 3
$row = $_GET['row'] + 1;
$parts = explode(',', $lines[$row]);
print $parts[0] . $parts[1] . $parts[2];
If record number 2 is not guaranteed to be on line 3
$row = $_GET['row'];
foreach ($lines as $line) {
if (strpos($line, $row) === 0) {
$parts = explode(',', $lines[$row]);
print $parts[0] . $parts[1] . $parts[2];
break;
}
}
If the file is extremely large you will want to read line by line from a buffer.
$row = $_GET['row'];
if ($fp = fopen('news.txt', 'r')) {
while ($line = fgets($fp)) {
if (strpos($line, $row) === 0) {
$parts = explode(',', $line);
print $parts[0] . $parts[1] . $parts[2];
break;
}
}
fclose($fp);
}