Dynamic mysql -> excel export - php

First off all - a "normal" export and writing an Excel file using phpspreadsheet works like a charm.
What I can't find out is how to do this in a dynamic way.
"Dynamic" means not manually defining the headlines in row1 and not defining manually the data columns from mysql.
What I've done (tried):
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('test');
if ($result = $mysqli -> query($sql)) {
$co = 'A';
$ro = '1';
while ($fieldinfo = $result -> fetch_field()) {
// printf("$col.$row %s\n", $fieldinfo -> name);
$sheet->setCellValue($co.$ro, $fieldinfo -> name);
$$co = $fieldinfo -> name;
$co++;
}
$result -> free_result();
}
This creates an excel file with all field names like defined in the mysql view/statement.
The challenge is to put date in column by column without creating them by code.
What I've done is to generate a variable for each column. So $A = firstname, $B = name, etc.
My idea was to address this variable by something like "first column is 'A' then I've to address the variable $A. But dynamically call variables doesn't work somehow
$sheet->setCellValue($co.$ro, $row[$cuco]);
$cuco (current column) should be $cuco = '$'.$A, but then the value of $cuco will be $A and the resolved variable $A which should be "firstname" i.e.

What I've done is add a comment to each column in the database that corresponds to the heading I want for that column. An additional query will give you that data which you may then use to populate the header row.
Here's the function I use FWIW:
//
// Returns an array indexed by column names with the column comment,
// if any, as the value from the table name that is passed - columns
// that do not have a comment are not included in the returned array
//
public function get_column_comments($table) {
$ColsQ = $this->database->prepare('SHOW FULL COLUMNS FROM `' . $table . '`');
$ColsQ->execute();
$ColsD = $ColsQ->fetchAll(PDO::FETCH_ASSOC);
foreach ($ColsD as $col) {
if (empty($col['Comment'])) {continue;} // ignore columns without a comment
$cols[$col['Field']] = $col['Comment'];
}
return $cols;
} // end of get_column_comments function

Related

How to create variables using rows from mysql?

I would like to create a file like this:
<?php
$cssMainVersion = "1.0.3";
$cssBootStrapVersion = "1.0.1";
$cssElseVersion = "1.0.4";
$jpgVersion = "1.0.1";
$jsMainVersion = "1.0.1";
$jsElseVersion = "1.0.1";
?>
I have created a mySQL table that holds the variable name, and the variable data. For example, the first row contains "cssMainVersion" and the second row contains "1.0.3".
How would I loop thorugh each row and print that data in a new file according to the format above?
You can create variables dynamically with php
$query = mysqli_query($conn, 'SELECT id, cachename, cacheversion FROM cache');
while($row = mysqli_fetch_assoc($query)) {
$$row['cachename'] = $row['cacheversion'];
}
the $$ will be evaluted from right to left, so, first $row['field'] will be replaced with this value, let say cssMainVersion, then we have $cssMainVersion

Excel Blank Column reading in php

I am uploading excel in PHP using PHPExcel_IOFactory, In excel there are some columns which should be compulsory filled like B,D,I,J and more.
My need is to first change Column B, if its blank an error should occur else check column D, if blank error else check further columns.
I have written below code, but i didn't got to check one column at a time:
$allDataInSheet = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
$arrayCount = count($allDataInSheet);
for($i=2;$i<=$arrayCount;$i++){
$b = $allDataInSheet[$i]["B"];
$d = $allDataInSheet[$i]["D"];
$i = $allDataInSheet[$i]["I"];
}
There are almost 20 columns compulsory, how can i check each column at a time.
Be careful. You're using $i in the for($i=2... line, but you set it to something else inside the loop with $i = $allData....
To meet your requirements (including starting with 2nd row), this is what I would do
$firstK = key($allDataInSheet); //save the first key
foreach($allDataInSheet as $k => $row){
if($k===$firstK) continue; //skip the first row
if(empty($b = $row['B'])){
// Error. column B is empty
}elseif(empty($c = $row['C'])){
// B is not empty. $b has its contents
// however, Error: column C is empty
}elseif(empty($i = $row['I'])){
// B and C are not empty. $b and $c have their contents
// however, Error: column I is empty
...
}else{
// All required columns have data
// $b, $c ... $i ... hold the contents
}
//...continue processing the row. You can use variables $b, $c...
}

Conditionally renaming sub variables after exploding a main associative array - PHP

The code below works fine, but after running list() on the exploded sub variables ($disc1, $disc2, $disc3) I need to conditionally rename the data that's inside them.
Basically, the field 'discs' is stored in our db as a composite of acronyms (i.e., a user's CD choices are CD-DA-RD), I can separate them out but not rename. I need something like:
'CB' -> 'CLUB'
'DA' -> 'DANCE'
'RD' -> 'RADIO'
I assume I need to get $disc1, $disc2, $disc3 back into an array to do this?
Hope someone can help - thanks!
// create a function to produce the main associative array from mySQL field 'discs'
function get_user_discs($myusername) {
$discs = array();
$query = mysql_query("SELECT `discs`
FROM `members`
WHERE `email` = '{$myusername}'");
if (mysql_num_rows($query)) {
$disc = mysql_fetch_assoc($query);
}
return $discs;
}
// call the function
$temp = $_SESSION['myusername'];
$discs = get_user_discs($temp);
// explode $discs into individual parts using delimiter
list($disc1, $disc2, $disc3) = explode("-", $discs['discs'], 3);
// then rename($disc1, $disc2, $disc3) to full names....?

Ignore order of mysql record in php

I have this piece of code that currently almost does what I need. It needs to select all records from a table and then format them ready for encoding to JSON. However, ONE record will have a "type" field set as "default". This record is placed first in the JSON file and formatted slightly different.
Currently this works prefectly if the record set to default is the last entry in the database table. But, if it isn't, then the formatting breaks when encoding to JSON.
Can anyone help suggest a fix that would force it to ignore where the default entry is, but retain the formatting?
// Get the data from the DB.
$query = 'SELECT type, headline, startDate, text, media, caption, credits FROM #__timeline_entries'.$table.'';
$db->setQuery($query);
// Load it and put it into an array
$list = $db->loadObjectList();
$len = count($list);
$data = array();
for ($i = 0; $i < $len; $i++) {
$temp = (array) $list[$i];
$temp["asset"] = array(
"media" => $temp["media"],
"credit" => $temp["credits"],
"caption" => $temp["caption"]
);
unset($temp["media"]);
unset($temp["credits"]);
unset($temp["caption"]);
if ($temp["type"] == "default") {
$data = $list[$i];
unset($list[$i]);
$list[$i] = $temp;
}
}
// Prep it for JSON
$data->date = &$list;
// Loop it once more!
$dataTwo->timeline = &$data;
// Encode the data to JSON.
$jsondata = json_encode($dataTwo);
This is part of a Joomla component, but it doesn't really use any of the Joomla framework beyond the database connection. I thought I'd mention it just in case it made any difference, though I don't see how.
Add an ORDER BY clause:
ORDER by (type = "default")
This will be 0 for all the records except the default, which is 1, so it will be put last.
Add a WHERE clause to your MySQL statement:
$query = 'SELECT type, headline, startDate, text, media, caption, credits FROM #__timeline_entries'.$table.' WHERE type <> default';

PHP mySQL JOIN with matching column names

Noticed a rather large problem. When I join two tables togeter the fact that there is a column called ID in both of them causes the wrong tables ID to be used in a PHP equasion later on.
The simple solution would be to change the column name, but there are other standards thoughout the database too including columns called name in every table and title in many of them.
Is there a way around this or should I rename the entire database to ensure that there are no duplicate columns.
THE CODE FOR REFERENCE
$criteria = "SELECT *
FROM voting_intention,electors
WHERE voting_intention.elector = electors.ID
AND electors.postal_vote = 1
AND voting_intention.date = (select MAX(date)
from voting_intention vote2
where voting_intention.elector = vote2.elector)
AND electors.telephone > 0"
function get_elector_phone($criteria){
$the_elector = mysql_query("SELECT * $criteria"); while($row = mysql_fetch_array($the_elector)) {
return $row['ID']; }
While "Gunnx" solution is perfectly acceptable, I'd like to present an alternative since you appear to be using only the ID column of the result.
SELECT
electors.ID
FROM
voting_intention,electors
....
I wrote this function to assist in doing this. Basically it prepends the table name to the fields name of an associated array.
while($row = mysql_fetch_array($the_elector))
{
return $row['ID'];
}
would become
while($row = mysql_fetch_table_assoc($the_elector))
{
return $row['voting_intention.ID'];
}
function:
function mysql_fetch_table_assoc($resource)
{
// function to get all data from a query, without over-writing the same field
// by using the table name and the field name as the index
// get data first
$data=mysql_fetch_row($resource);
if(!$data) return $data; // end of data
// get field info
$fields=array();
$index=0;
$num_fields=mysql_num_fields($resource);
while($index<$num_fields)
{
$meta=mysql_fetch_field($resource, $index);
if(!$meta)
{
// if no field info then just use index number by default
$fields[$index]=$index;
}
else
{
$fields[$index]='';
// deal with field aliases - ie no table name ( SELECT T_1.a AS temp, 3 AS bob )
if(!empty($meta->table)) $fields[$index]=$meta->table.'.';
// deal with raw data - ie no field name ( SELECT 1, MAX(index) )
if(!empty($meta->name)) $fields[$index].=$meta->name; else $fields[$index].=$index;
}
$index++;
}
$assoc_data=array_combine($fields, $data);
return $assoc_data;
}
?>
mysql_fetch_row will get the data as a numerical array

Categories