I'm trying to export data to Excel file using PHPExcel in yii. But I'm getting blank cells when I try to export data to excel file.
I'm able to add static values in the file such as column names.
$rowCount = 2;
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount, "Sr. No");
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount, "Suite Name");
this is the code in my controller action. I can see array values with that echo statement.
$i = 1;
$rowCount = 3;
foreach ($result as $row) {
$value = $row['suite_name'];
echo "<javascript type='text/javascript'>alert('$i, $rowCount, C$rowCount, D$rowCount ".$value."')</script>";
$objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount, $i);
$objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount, $value);
// Increment the Excel row counter
$rowCount++;
$i++;
}
instead of $value I tried directly with $row['suite_name'], that didn't worked either. Please, Any help will appreciated.
Try PHPExcel fromArray() method for saving array values to excel sheet.
Example
single dimensional array
$rowArray = array('Value1', 'Value2', 'Value3', 'Value4');
$objPHPExcel->getActiveSheet()
->fromArray(
$rowArray, // The data to set
NULL, // Array values with this value will not be set
'C3' // Top left coordinate of the worksheet range where
// we want to set these values (default is A1)
);
Multi dimensional array
$arrayData = array(
array(NULL, 2010, 2011, 2012),
array('Q1', 12, 15, 21),
array('Q2', 56, 73, 86),
array('Q3', 52, 61, 69),
array('Q4', 30, 32, 0),
);
$objPHPExcel->getActiveSheet()
->fromArray(
$arrayData, // The data to set
NULL, // Array values with this value will not be set
'C3' // Top left coordinate of the worksheet range where
// we want to set these values (default is A1)
);
Related
I'm trying to write 18000 rows x 42 cols. The values from col 'E' to 'DD' must set with value 0. I'm trying to use increment but I found that is caused memory exhausted.
My Code is like this :
$col = $lastcol;
foreach ($diag0 as $key) {
$sheet->setCellValue('A'.(string)($col + 1), '0');
$sheet->setCellValue('B'.(string)($col + 1), $key->cdDiag);
$sheet->setCellValue('D'.(string)($col + 1), $key->nmDiag);
for ($char='E'; $char <= 'J' ; $char++) {
$sheet->setCellValue($char.(string)($col + 1), '0');
}
$col++;
}
I'd trying the PHPExcel cached config, but it still give the same result. I think since the col 'E' to 'DD' is have the same value, can I make it like set 'E' to 'DD' with 0 at one loop?
You can set the format for a range of cells:
$objPHPExcel->getActiveSheet() // THIS SHOULD BE THE SAME AS $sheet
->getStyle('E2:DD18000')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER);
A list with the available formats:
http://apigen.juzna.cz/doc/ouardisoft/PHPExcel/class-PHPExcel_Style_NumberFormat.html
Also, maybe this way of inserting rows works better:
$objPHPExcel->getActiveSheet()->fromArray(array(
0, //COL A
$key->cdDiag, //COL B
'',
$key->nmDiag,
0,0,0,0,0, ... 0,0,0,0 // your 26 COLUMNS E to DD,
),NULL,'A' . $row + 1);
You could also set the columns as empty string '' since you added the setColumnsFormat. And your $col variable, not that it matters, but it should be called $row... you are moving through rows not cols...
I never tried this but:
you can use $objPHPExcel->garbageCollect(); after inserting each row to solve your memory allocation problem, if this doesn't fix the problem try giving a little more memory with:
ini_set('memory_limit', '256M');
default is 128, just be sure you don't consume too much resources...
Ok, so the question is kind of awkwardly phrased, but I hope this will clear things up.
I have this sample 2d array.
$array = array(
array(1, 0, 0, 0, 1, 0, 0, 1),
array(0, 0, 1, 1, 1, 1, 0, 1),
array(0, 1, 1, 0, 1, 0, 0, 0),
array(0, 1, 1, 0, 0, 0, 1, 0),
array(1, 0, 0, 0, 1, 1, 1, 1),
array(0, 1, 1, 0, 1, 0, 1, 0),
array(0, 0, 0, 0, 0, 0, 0, 1)
);
When iterated by rows (and terminating each row with \n), and for every row then iterated by column, it will echo something like this: (░░ = 0, ▓▓ = 1)
▓▓░░░░░░▓▓░░░░▓▓
░░░░▓▓▓▓▓▓▓▓░░▓▓
░░▓▓▓▓░░▓▓░░░░░░
░░▓▓▓▓░░░░░░▓▓░░
▓▓░░░░░░▓▓▓▓▓▓▓▓
░░▓▓▓▓░░▓▓░░▓▓░░
░░░░░░░░░░░░░░▓▓
But what I'd like to do is to "analyse" the array and only leave 1 contiguous shape (the one with the most "cells"), in this example, the result would be:
░░░░░░░░▓▓░░░░░░
░░░░▓▓▓▓▓▓▓▓░░░░
░░▓▓▓▓░░▓▓░░░░░░
░░▓▓▓▓░░░░░░░░░░
▓▓░░░░░░░░░░░░░░
░░▓▓▓▓░░░░░░░░░░
░░░░░░░░░░░░░░░░
My initial approach was to:
Assign each ▓▓ cell a unique number (be it completely random, or the current iteration number):
01 02 03
04050607 08
0910 11
1213 14
15 16171819
2021 22 23
24
Iterate through the array many, MANY times: every iteration, each ▓▓ cell assumes the largest unique number among his neighbours. The loop would go on indefinitely until there's no change detected between the current state and the previous state. After the last iteration, the result would be this:
01 21 08
21212121 08
2121 21
2121 24
21 24242424
2121 24 24
24
Now it all comes down to counting the value that occurs the most. Then, iterating once again, to turn all the cells whose value is not the most popular one, to 0, giving me the desired result.
However, I feel it's quite a roundabout and computationally heavy approach for such a simple task and there has to be a better way. Any ideas would be greatly appreciated, cheers!
BONUS POINTS: Divide all the blobs into an array of 2D arrays, ordered by number of cells, so we can do something with the smallest blob, too
Always fun, these problems. And done before, so I'll dump my code here, maybe you can use some of it. This basically follows every shape by looking at a cell and its surrounding 8 cells, and if they connect go to the connecting cell, look again and so on...
<?php
$shape_nr=1;
$ln_max=count($array);
$cl_max=count($array[0]);
$done=[];
//LOOP ALL CELLS, GIVE 1's unique number
for($ln=0;$ln<$ln_max;++$ln){
for($cl=0;$cl<$cl_max;++$cl){
if($array[$ln][$cl]===0)continue;
$array[$ln][$cl] = ++$shape_nr;
}}
//DETECT SHAPES
for($ln=0;$ln<$ln_max;++$ln){
for($cl=0;$cl<$cl_max;++$cl){
if($array[$ln][$cl]===0)continue;
$shape_nr=$array[$ln][$cl];
if(in_array($shape_nr,$done))continue;
look_around($ln,$cl,$ln_max,$cl_max,$shape_nr,$array);
//SET SHAPE_NR to DONE, no need to look at that number again
$done[]=$shape_nr;
}}
//LOOP THE ARRAY and COUNT SHAPENUMBERS
$res=array();
for($ln=0;$ln<$ln_max;++$ln){
for($cl=0;$cl<$cl_max;++$cl){
if($array[$ln][$cl]===0)continue;
if(!isset($res[$array[$ln][$cl]]))$res[$array[$ln][$cl]]=1;
else $res[$array[$ln][$cl]]++;
}}
//get largest shape
$max = max($res);
$shape_value_max = array_search ($max, $res);
//get smallest shape
$min = min($res);
$shape_value_min = array_search ($min, $res);
// recursive function: detect connecting cells
function look_around($ln,$cl,$ln_max,$cl_max,$nr,&$array){
//create mini array
$mini=mini($ln,$cl,$ln_max,$cl_max);
if($mini===false)return false;
//loop surrounding cells
foreach($mini as $v){
if($array[$v[0]][$v[1]]===0){continue;}
if($array[$v[0]][$v[1]]!==$nr){
// set shape_nr of connecting cell
$array[$v[0]][$v[1]]=$nr;
// follow the shape
look_around($v[0],$v[1],$ln_max,$cl_max,$nr,$array);
}
}
return $nr;
}
// CREATE ARRAY WITH THE 9 SURROUNDING CELLS
function mini($ln,$cl,$ln_max,$cl_max){
$look=[];
$mini=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
foreach($mini as $v){
if( $ln + $v[0] >= 0 &&
$ln + $v[0] < $ln_max &&
$cl + $v[1] >= 0 &&
$cl + $v[1] < $cl_max
){
$look[]=[$ln + $v[0], $cl + $v[1]];
}
}
if(count($look)===0){return false;}
return $look;
}
Here's a fiddle
I can only think of a few minor improvements:
Keep a linked list of the not empty fields. In step 2 you do not need to touch n² matrix-elements, you only need to touch the ones in your linked list. Which might be much less depending how sparse your matrix is.
You only need to compare to the right, right-down, left-down and down directions. Otherwise The other directions are already checked from the former row/column. What I mean: When I am greater that my right neighbour, I can already change the number of the right neighbour. (same for down and right-down). This halfs the number of compairs.
If your array size isn't huge and memory won't be a problem maybe a recursive solution would be faster. I found a c++ algorithm that does this here:
https://www.geeksforgeeks.org/find-length-largest-region-boolean-matrix/
I understand basic arrays but when they get more advanced I get a little lost. Can someone help me with the following code and array?
I am storing my DB query into an array. If all 12 months are not in the DB then that is all that is stored (as it should). However, my problem is that I need the array to have all 12 keys so I can print this out.
// Example amounts
0, 0, 0, 0, 5.23, 0, 0, 158.35, 0, 0, 0, 0
Basically if it does not exist I should still be able to print out zero for that month.
Here is my code:
$closedsales = mysqli_query($mysqli, "SELECT MONTH(date) as month, sum(amount) as total FROM sales WHERE user_id = '".$userid."' AND status = 'S' GROUP BY MONTH(date)");
while ( $row = mysqli_fetch_assoc($closedsales) ) {
$monthlysales[$row['month']] = $row['total'];
}
foreach($monthlysales as $key => $amount) {
echo "$amount <br />";
}
Prefill your result array:
$monthlysales = array_fill_keys(range(1, 12), 0);
Then run your loop, which will replace the elements with the rows from the table. If a row is missing from the table, it will have the initial 0 value.
$allmonthlysales = array_fill_keys(range(1, 12), 0);
foreach($monthlysales as $month => $sales){
$allmonthlysales[$month] = $sales;
}
var_dump($allmonthlysales);
Prepare and array with keys 1-12 and 0 as value meaning months with no sales.
Merge the array with months that have sales with the empty one built above.
And you got what you need...
I've got an array per default:
array( 1=>1,2 =>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9 )
Now an operation is possible to change the numbers for example into:
array( 1=>1, 2=>1, 3=>3, 4=>1, 5=>1, 6=>6, 7=>7, 8=>8, 9=>9 )
--> changed the value of key 1, 2, 4 and 5
After this I need the following result
array( 1=>1, 2=1, 3=>2, 4=>1, 5=>1, 6=>3, 7=>4, 8=>5, 9=>6 )
--> changed the value of key 3, 6, 7, 8, 9 in the right order that no number is missing like the operation has done above.
Its a grid 3x3. Position 1 is 1, Position 2 is 2 and so on. Now a database could set that Position 1, 2, 4, 5 are the same and threated as 1. So the database sends: 1, 1, 3, 1, 1, 6, 7, 8, 9. Now the field from place 3 is 3, but should be the field from 2. Also the field from 6 must now be field 3 and so on.
Note: The operation is able to change every value in the array. for example the value of the
keys 4, 5, 7, 8
How can I do this?
Create a variable, in which you will store the max number. If you then iterate, check if the number from the array is lower then max, and if it is, then you do nothing, and if it is larger than max, so you put it in the third array and increase max.
$max = 0; // maximum value
$array3 = array(); // output array
foreach($array2 as $key=>$element){ // iterate for all elements
if($array2[$key] > $max){
$max++;
$array3[$key] = $max;
}
else
$array3[$key]=1; // *
} // end foreach
In the line marked with // * it puts 1 everytime. You may need to search if the value was once before, because it does not need to be always 1. You may use for example something like array_search.
I'm writing a script that works out the mode, median and mean of a set of data. I have ten records which are stored in a MySQL database and in a PHP array. When the script is finished, the script will only use the data stored in the database and not the PHP array, the PHP array is there to test the code.
What I have found though is that the results are different when using the PHP array compared to the MySQL array. In the PHP array, I have the following data:
$arr = array(60, 70, 71, 76, 144, 151, 197, 229, 233, 233);
In my MySQL database, I have this code:
$data = mysql_query("SELECT amount FROM example") or die(mysql_error());
$arr = mysql_fetch_array($data);
The data is the same, the exception being that the MySQL data contains .00 after each record. During the time spent trying to find out why it was giving the wrong results, I removed the .00 from each record in the database. The data is still wrong though.
The results, when using the PHP array gives me the following (correct) results:
Average (mean) value of payments £146.4 Payments values that
occur most often £233 Median value of payments £151
The results, when using the MySQL array gives me the following (wrong) results:
Average (mean) value of payments £144 Payments values that occur
most often £144 Median value of payments £144
I'm at a loss to explain why this is happening. Below is the PHP code I'm using to generate these results:
<?php
function arithmetic($array, $output = 'mean'){
switch($output){
// This case works out the mean
case 'mean':
$count = count($array);
$sum = array_sum($array);
$total = $sum / $count;
break;
// This case works out the median
case 'median':
rsort($array);
$middle = round(count($array) / 2);
$total = $array[$middle-1];
break;
// This case works out the mode
case 'mode':
$v = array_count_values($array);
arsort($v);
foreach($v as $k => $v){$total = $k; break;}
break;
}
return $total;
}
// PHP Array with data
//$arr = array(60, 70, 71, 76, 144, 151, 197, 229, 233, 233);
// MySQL Connection & Retrieval of data
$data = mysql_query("SELECT amount FROM example") or die(mysql_error());
$arr = mysql_fetch_array($data);
?>
Anyone have any ideas?
UPDATE:
I've been playing the MySQL query, and using the following code:
$data = mysql_query("SELECT * FROM example") or die(mysql_error());
$arr = mysql_fetch_assoc($data);
print_r ($arr);
It displays the following, only result:
Array ( [id] => 1 [amount] => 144 )
So really, the query is bringing all of the records and not just the one.
Well, the reason is because you're only fetching one row, and thus one number...
$arr = array();
while ($result_array = mysql_fetch_row($data)) {
$arr[] = $result_array[0];
}
After this code, you should be able to calculate the correct values.
I don't know if that helps but you might want to dig in mysql-fetch array() and follow there recommendations there,
http://php.net/manual/en/function.mysql-fetch-array.php
especially checking if the data that you are fetching is set correctly.
function db_result_single($result) {
return ($row = mysql_fetch_row($result)) && isset($row[0]) ? $row[0] : false;
}