PHP Export to CSV is putting all in 1 column - php

First a disclaimer, I am a noob here. I am trying to output my results into an excel file, however for some reason I can't seem to figure it, all the results are entering into the same column
Here is the function that I am using to convert it to the file:
function createCSVFile($filename,$headings,$data) {
// Set Output Headers
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}.csv");
$fp = fopen('php://output', 'w');
$head = array();
foreach ($headings as $heading) {
$head[] = $heading;
}
fputcsv($fp, $head);
$rowData = array();
// Put the data into the csv
foreach ($data as $row) {
foreach ($row as $item) {
$rowData[] = $item;
}
fputcsv($fp, $rowData);
unset($rowData);
}
}
Here is some sample data and the structure of what I am passing:
$filename
$filename = "Staff-list";
$headings
$headings = array("Username","First Name","Last Name","Start Date", "End Date");
$data
$data = getStaffDetails();
Which returns:
array(6) {
[0]=>
array(5) {
[0]=>
string(12) "James21"
[1]=>
string(3) "James"
[2]=>
string(9) "Michael"
[3]=>
string(10) "2016-06-01"
[4]=>
string(10) "0000-00-00"
}
[1]=>
array(5) {
[0]=>
string(14) "thombommom"
[1]=>
string(5) "Thomas"
[2]=>
string(7) "Bomarius"
[3]=>
string(10) "2016-12-01"
[4]=>
string(10) "0000-00-00"
}
}
And here is what it looks like in the ouput:
Update 1:
As per Marks solution below, I tried setting the deliminator in the PHP func to ; like so:
fputcsv($fp, $head,';');
However, now the output just has semi colons instead of commas

One of the reasons I hate windows so much is that with every version, something is different making it harder for devs. Argh.... Anyway, what you need to do is override system setting ("list separator character") with: 'sep=;'.
The first thing you should pass to fputcsv is:
$seperator = "sep=;";
fputcsv($fp, $seperator, ';', ' ');
Then Make your data an array of arrays with the first array being your headings like so:
$data = array(array("One","Two", "Three"), array('1','2','3'),array('1','2','3'),array('1','2','3'));
Just because you said you're a noob I'll give ya the whole function:
function createCSVFile($filename,$data) {
// Set Output Headers
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}.csv");
$fp = fopen('php://output', 'w');
// This will override system setting ("list separator character") and Excel will open the file correctly.
$seperator = "sep=;";
fputcsv($fp, $seperator, ';', ' ');
// Get the array initialised.
$rowData = array();
// put the data into the csv
foreach ($data as $row) {
foreach ($row as $item) {
$rowData[] = $item;
}
fputcsv($fp, $rowData);
unset($rowData);
}
}
Keep me posted!

Related

How to convert Array to Array list for CSV export using FputCSV?

I need to convert an array with multiple results to a CSV file but am struggling to get a valid output .
After some debugging I realized I am not generating a valid array list for fputcsv to iterate through .
First of all, here is an illustrative example of a var_dump of my array :
object(stdClass)#83 (3) {
["Username"]=>
string(8) "username"
["FullName"]=>
bool(false)
["ContactPhoneNumber"]=>
bool(false)
object(stdClass)#84 (3) {
["Username"]=>
string(8) "username2"
["FullName"]=>
bool(false)
["ContactPhoneNumber"]=>
bool(false)
object(stdClass)#85 (3) {
["Username"]=>
string(8) "username3"
["FullName"]=>
bool(false)
["ContactPhoneNumber"]=>
bool(false)
And this is the code I have tried after some researching on how to convert an array to CSV :
$file = fopen($CsvFile, 'w');
fputcsv($file, array_keys($HeaderFields)); // Headers
$data = array($DataRecord);
foreach ($data as $row) {
$row = [];
array_walk_recursive($row, function ($item) use (&$row) {
$row[] = $item;
});
fputcsv($file, $row);
}
fclose($file);
I also tried to use the standard example from fputcsv :
$file = fopen($CsvFile, 'w');
$data = array($DataRecord)
foreach ($data as $row) {
fputcsv($file, $row);
}
fclose($file);
Obviously I am doing something very wrong and failing to produce the proper format for inserting multiple array lines in the csv file .
If I replace my $data array with this :
$data = array(array('Data 11', 'Data 12', 'Data 13', 'Data 14', 'Data 15'));
Then fputcsv works as expected .
So what I need is to convert my array into this format so fputcsv can iterate through it and save each line .
How could I achieve this ?
Thanks
Just cast the objects to arrays with (array):
$file = fopen($CsvFile, 'w');
fputcsv($file, get_object_vars(reset($data)));
foreach ($data as $row) {
fputcsv($file, (array)$row);
}
fclose($file);
If the object properties and $HeaderFields are not the same then use $HeaderFields instead.

how to format a json file?

I am new to JSON and I am wondering how i could format my JSON file so I will be able to render it in a barchart.
I've got the following PHP code:
<?php
$search_value=$_POST["search"];
$mysqli = new mysqli('localhost','root','password','mydb');
$myArray = array();
if ($result = $mysqli->query("SELECT * FROM transcriptome WHERE genename LIKE '%$search_value%'")) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
$myArray = $row;
}
file_put_contents('jsonoutput.json', json_encode($myArray));
echo json_encode($myArray);
}
$result->close();
$mysqli->close();
?>
My actual output:
(given a gene (xkr4) as input)
{"genename":"xkr4","TA11MEAN":"974.25","TA11STD":"99.0085223605","TA21MEAN":"710.75","TA21STD":"115.79831605","TA22MEAN":"736.5","TA22STD":"115.79831605","TA23MEAN":"903.75","TA23STD":"107.283211641","TB11MEAN":"799.25","TB11STD":"97.2660655111","TB21MEAN":"658","TB21STD":"91.7959694104","TB22MEAN":"592.75","TB22STD":"70.9379129944","TB23MEAN":"864","TB23STD":"92.7280971443"}
How I'd like to get my output:
{"genename":"xkr4",{"TA11MEAN":"974.25"},{"TA11STD":"99.0085223605"},{"TA21MEAN":"710.75"},{"TA21STD":"115.79831605"},{"TA22MEAN":"736.5"},{"TA22STD":"115.79831605"},{"TA23MEAN":"903.75"},{"TA23STD":"107.283211641"},{"TB11MEAN":"799.25"},{"TB11STD":"97.2660655111"},{"TB21MEAN":"658"},{"TB21STD":"91.7959694104"},{"TB22MEAN":"592.75"},{"TB22STD":"70.9379129944"},{"TB23MEAN":"864"},{"TB23STD":"92.7280971443"}}
If someone could give me direction on this (or solve it) That would be great!
Thanks in advance :)
I would suggest you to first check how are you getting back your data in array.
$myArray[] should have the data populated as shown below. Then use JSON_PRETTY_PRINT.
/*USED TO SHOW FULL ARRAY SIZE*/
ini_set('xdebug.var_display_max_depth', -1);
ini_set('xdebug.var_display_max_children', -1);
ini_set('xdebug.var_display_max_data', -1);
$myArray=array("genename"=>array(array("xkr4"=>array(
array("TA11MEAN"=>"974.25","TA11STD"=>"99.0085223605"),
array("TA21MEAN"=>"710.75","TA21STD"=>"115.79831605"),
array("TA22MEAN"=>"736.5","TA22STD"=>"115.79831605"),
array("TA23MEAN"=>"903.75","TA23STD"=>"107.283211641"),
array("TB11MEAN"=>"799.25","TB11STD"=>"97.2660655111"),
array("TB21MEAN"=>"658","TB21STD"=>"91.7959694104"),
array("TB22MEAN"=>"592.75","TB22STD"=>"70.9379129944"),
array("TB23MEAN"=>"864","TB23STD"=>"92.7280971443"),
))));
$jsonData=json_encode($myArray,JSON_PRETTY_PRINT);
var_dump($jsonData);
$json_from_database='[{"genename":"xkr4","TA11MEAN":"974.25","TA11STD":"99.0085223605","TA21MEAN":"710.75","TA21STD":"115.79831605","TA22MEAN":"736.5","TA22STD":"115.79831605","TA23MEAN":"903.75","TA23STD":"107.283211641","TB11MEAN":"799.25","TB11STD":"97.2660655111","TB21MEAN":"658","TB21STD":"91.7959694104","TB22MEAN":"592.75","TB22STD":"70.9379129944","TB23MEAN":"864","TB23STD":"92.7280971443"}]';
//print decode array from databse
$decoded=json_decode($json_from_database);
var_dump($decoded);
foreach ($decoded[0] as $key => $value) {
echo "\n ";
print $key;
print " " .$decoded[0]->$key;
}
array(1) {
[0]=>
object(stdClass)#1 (17) {
["genename"]=>
string(4) "xkr4"
["TA11MEAN"]=>
string(6) "974.25"
["TA11STD"]=>
string(13) "99.0085223605"
["TA21MEAN"]=>
string(6) "710.75"
["TA21STD"]=>
string(12) "115.79831605"
["TA22MEAN"]=>
string(5) "736.5"
["TA22STD"]=>
string(12) "115.79831605"
["TA23MEAN"]=>
string(6) "903.75"
["TA23STD"]=>
string(13) "107.283211641"
["TB11MEAN"]=>
string(6) "799.25"
["TB11STD"]=>
string(13) "97.2660655111"
["TB21MEAN"]=>
string(3) "658"
["TB21STD"]=>
string(13) "91.7959694104"
["TB22MEAN"]=>
string(6) "592.75"
["TB22STD"]=>
string(13) "70.9379129944"
["TB23MEAN"]=>
string(3) "864"
["TB23STD"]=>
string(13) "92.7280971443"
}
}
genename xkr4
TA11MEAN 974.25
TA11STD 99.0085223605
TA21MEAN 710.75
TA21STD 115.79831605
TA22MEAN 736.5
TA22STD 115.79831605
TA23MEAN 903.75
TA23STD 107.283211641
TB11MEAN 799.25
TB11STD 97.2660655111
TB21MEAN 658
TB21STD 91.7959694104
TB22MEAN 592.75
TB22STD 70.9379129944
TB23MEAN 864
TB23STD 92.7280971443
This is how your data looks like from database it is a array of rows row is a object
I solved it:
<?php
$search_value=$_POST["search"];
$mysqli = new mysqli('localhost','root','password','mydb');
$myArray = array();
if ($result = $mysqli->query("SELECT * FROM transcriptome WHERE genename LIKE '%$search_value%'")) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
$myArray = $row;
}
//file_put_contents('jsonoutput.json', json_encode($myArray));
$json = json_encode($myArray);
$array = json_decode($json, true);
$new_array = array();
foreach( $array as $key => $value ){
$newarray[] = array($key=>$value);
}
echo json_encode($newarray);
file_put_contents('jsonoutput.json', json_encode($newarray));
}
$result->close();
$mysqli->close();
?>

Reading from a file into an associative array

I have to create a page, where the user is able to search a suburb and the page will print the postcode of that suburb.
I am having a little difficulty with putting the data from the .txt document into the variables for the associative array.
Thanks for your help.
This is what I have so far.
<?php
$file = "postcode.txt";
$handle = fopen($file, 'r');
$postcodearray = file($file);
$suburb = explode(",", );
$postcodearray[$suburb] = $postcode;
fclose($handle)
?>
and this is the format of the .txt document...
3000,MELBOURNE
3001,MELBOURNE
3002,EAST MELBOURNE
3003,WEST MELBOURNE
etc.
$postcodearray = file($file);
foreach($postcodearray as $pca){
$p_codes=explode(',',$pca);
$postcodearray2[$p_codes[1]] = $p_codes[0];
}
print_r($postcodearray2);
I prefer file_get_contents when working with files
<?php
$content = file_get_contents('postcode.txt');
$rows = explode("\n", $content);
$data = [];
foreach ($rows as $row) {
$columns = explode(',', $row);
$data[$columns[0]] = $columns[1];
}
An alternative array would group MELBOURNE EAST and WEST in one array with subarrays. (Look at the output, I don't know how to explain it)
I explode MELBOURNE EAST on space and use EAST as a key in the array.
// Replace this line with file_get_contents("postcode.txt");
$txt = "3000,MELBOURNE
3001,MELBOURNE
3002,EAST MELBOURNE
3003,WEST MELBOURNE
3603,WEST SYDNEY
3103,NORTH PERTH";
$rows = explode(PHP_EOL, $txt);
$arr= [];
foreach($rows as $row){
List($postcode, $suburb) = explode(",", $row);
If(in_array(substr($suburb,0,4), array("EAST", "WEST")) || in_array(substr($suburb,0,5), array("SOUTH", "NORTH"))){
// If the suburb includes a direction explode it to temp.
$temp = explode(" ", $suburb);
$arr[$temp[1]][$temp[0]][] = $postcode;
}else{
// If there is no direction just save it as suburb "main"
$arr[$suburb][] = $postcode;
}
}
Var_dump($arr);
https://3v4l.org/RXgSR
Output:
array(3) {
["MELBOURNE"]=>
array(4) {
[0]=>
string(4) "3000"
[1]=>
string(4) "3001"
["EAST"]=>
array(1) {
[0]=>
string(4) "3002"
}
["WEST"]=>
array(1) {
[0]=>
string(4) "3003"
}
}
["SYDNEY"]=>
array(1) {
["WEST"]=>
array(1) {
[0]=>
string(4) "3603"
}
}
["PERTH"]=>
array(1) {
["NORTH"]=>
array(1) {
[0]=>
string(4) "3103"
}
}
}

php arrays to CSV

I have an array of arrays
$numbers= array(3) {
[months]=>
array(3) {
["1"]=>
string(7) "Jan"
["2"]=>
string(7) "Feb"
["3"]=>
string(7) "Mar"
}
[dates]=>
array(3) {
["1"]=>
string(7) "12th"
["2"]=>
string(7) "19th"
["3"]=>
string(7) "22nd"
}
[people]=>
array(3) {
["1"]=>
string(7) "Bill"
["2"]=>
string(7) "Ted"
["3"]=>
string(7) "Gary"
}
}
I want to write the contents of these arrays into a CSV file in the form of a table
so I get an output like:
months, dates, people
Jan, 12th, Bill
Feb, 19th, Ted
Mar, 22nd, Gary
I want to try and put it directly from the array into the CSV in one move it it's possible but I can't find a way to do it without cutting it up.
<?php
// transform the array
$keys = array_keys($numbers);
array_unshift($numbers, null);
$output = call_user_func_array('array_map', $numbers);
array_unshift($output, $keys);
// from php.net
$fp = fopen('file.csv', 'w');
foreach ($output as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
$mi = new MultipleIterator();
$headers = array();
foreach($numbers as $header => $data) {
$mi->attachIterator(new ArrayIterator($data));
$headers[] = $header;
}
$fh = fopen('myfile.csv', 'w');
fputcsv($fh, $headers);
foreach($mi as $values) {
fputcsv($fh, $values);
}
fclose($fh);

Splitting array if empty value

I am trying to split an array if one of the lines has an empty value. My array is being exported to a csv and has multiple lines of data, if the data is not complete it will be sent to a uncomplete csv and if it is complete it will be sent a complete csv.
This is what my array structure looks like the blank field on the first line is on email (this line should be split out of the array:
array(2) {
[0]=> array(6) {
["Username"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Email"]=> string(0) ""
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Description"]=> string(491) "the Tooth Fairy"
}
[1]=> array(6) {
["Username"]=> string(26) "Maui Nui Botanical Gardens"
["Email"]=> string(18) "info#mnbg.org"
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(26) "Maui Nui Botanical Gardens"
["Description"]=> string(50) "Conserving Hawaiian Plants & Cultural Heritage"
}
}
Writing to my csv:
$fp = fopen('entries.csv', 'w');
foreach ($entries as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
if (!copy("http://www.simonstaton.co.uk/entries.csv", "entries.csv")) {
echo ("failed to copy file");
};
I have no idea where to start with this and as to what function I should use so any advice is greatly appreciated.
Simon
To separate the entries by complete or incomplete you can open two files for writing. One to contain each.
// filenames
$fn_complete = 'entries.csv';
$fn_incomplete = 'incomplete_entries.csv';
// file pointers
$fp_complete = fopen($fn_complete, 'w');
$fp_incomplete = fopen($fn_incomplete, 'w');
// write CSVs
foreach ($entries as $fields) {
if (in_array('', $fields))
fputcsv($fp_incomplete, $fields);
else
fputcsv($fp_complete, $fields);
}
fclose($fp_complete);
fclose($fp_incomplete);
if (!copy('http://www.simonstaton.co.uk/' . $fn_complete, $fn_complete)) {
echo ('failed to copy file ' . $fn_complete);
};
if (!copy('http://www.simonstaton.co.uk/' . $fn_incomplete, $fn_incomplete)) {
echo ('failed to copy file ' . $fn_incomplete);
};
You can check if any of the values in your array is empty like this:
in_array('', $array)
so it then you can do a simple if
if(in_array('', $array)) {
//Do whatever you have to do to slip your array. I don't understand exactly what you want the end result to look like .
}
First pack your CSV data into an array using fgetcsv(). Then use a loop to search for "".
Exemplar:
$row = 1;
if (($resource = fopen("example.csv", "r")) !== false) {
while (($data = fgetcsv($resource, 1000, ",")) !== false) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
if ($data[$c] == "") {
// operate
}
}
}
fclose($handle);
}
By the way, don't use the split() function. Use preg_split().
http://php.net/manual/en/function.fputcsv.php

Categories