I am trying to use phpexcel to set the template purchase order .
I have set column 25 to 43 is for details of purchase item. It mean it will retrieve data from database and set all the value in column 25 to 43 .As addition ,these column only can fit for 6 item. I am facing problem when the purchase item is too many and cannot fit into the column that i had set.
My code is work,but it is too long. Anyone have a better solution?
after create both sheet,i have to set the other cellvalue one by one in both sheet.It make the code become very long.Appreciate for who can help.
$objPHPExcel->setActiveSheetIndex(0);
$result = mysql_query("SELECT purchasematerial.PONum,purchasematerial.QuoNum,purchasematerial.date, material.product,purchasematerial.description,purchasematerial.unit_price,purchasematerial.UOM,purchasematerial.qua ntity ,purchasematerial.amount FROM purchasematerial INNER JOIN material ON purchasematerial.product=material.id where PONum='$PONum'");
$col=25;
$num=1;
while($row = mysql_fetch_array($result)){
if($col<43){
$objPHPExcel->getActiveSheet()->setCellValue('AA11', $row['PONum']);
$date = new DateTime($row['date']);
$objPHPExcel->getActiveSheet()->setCellValue('AA12', $date->format('d-M-y'));
$objPHPExcel->getActiveSheet()->setCellValue('I45', '=AA12+7');
$QuoNum=$row['QuoNum'];
if ($QuoNum=='' || $QuoNum== null)
$objPHPExcel->getActiveSheet()->setCellValue('I47', "N/A");
else
$objPHPExcel->getActiveSheet()->setCellValue('I47', $row['QuoNum']);
$objPHPExcel->getActiveSheet()->setCellValue('A'.$col, $num);
$objPHPExcel->getActiveSheet()->setCellValue('B'.$col, $row['product']);
$objPHPExcel->getActiveSheet()->SetCellValue('J'.$col, $row['description']);
$objPHPExcel->getActiveSheet()->SetCellValue('S'.$col, $row['unit_price']);
$objPHPExcel->getActiveSheet()->setCellValue('V'.$col, $row['UOM']);
$objPHPExcel->getActiveSheet()->SetCellValue('Y'.$col, $row['quantity']);
$objPHPExcel->getActiveSheet()->SetCellValue('AB'.$col, $row['amount']);
$col=$col+3;
$num++;
}
else{
$objPHPExcel->createSheet();
$objPHPExcel->setActiveSheetIndex(1);
$col=25;
$objPHPExcel->getActiveSheet()->setCellValue('AA11', $row['PONum']);
$date = new DateTime($row['date']);
$objPHPExcel->getActiveSheet()->setCellValue('AA12', $date->format('d-M-y'));
$objPHPExcel->getActiveSheet()->setCellValue('I45', '=AA12+7');
$QuoNum=$row['QuoNum'];
if ($QuoNum=='' || $QuoNum== null)
$objPHPExcel->getActiveSheet()->setCellValue('I47', "N/A");
else
$objPHPExcel->getActiveSheet()->setCellValue('I47', $row['QuoNum']);
$objPHPExcel->getActiveSheet()->setCellValue('A'.$col, $num);
$objPHPExcel->getActiveSheet()->setCellValue('B'.$col, $row['product']);
$objPHPExcel->getActiveSheet()->SetCellValue('J'.$col, $row['description']);
$objPHPExcel->getActiveSheet()->SetCellValue('S'.$col, $row['unit_price']);
$objPHPExcel->getActiveSheet()->setCellValue('V'.$col, $row['UOM']);
$objPHPExcel->getActiveSheet()->SetCellValue('Y'.$col, $row['quantity']);
$objPHPExcel->getActiveSheet()->SetCellValue('AB'.$col, $row['amount']);
$col=$col+3;
$num++;
}
}
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->getStyle('I45')->getNumberFormat()- >setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15);
$objPHPExcel->getActiveSheet()->setCellValue('AC1', 'WEEKNUM(I45)');
$objPHPExcel->getActiveSheet()->setCellValue('Q44', 'TOTAL');
$objPHPExcel->getActiveSheet()->SetCellValue('Y44','RM');
$objPHPExcel->getActiveSheet()->SetCellValue('AB44', '=SUM(AB25:AB43)');
$objPHPExcel->getActiveSheet()->getStyle('Q44')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('Y44')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('AA44')->getFont()->setBold(true);
$objPHPExcel->setActiveSheetIndex(1);
$objPHPExcel->getActiveSheet()->getStyle('I45')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15);
$objPHPExcel->getActiveSheet()->setCellValue('AC1', 'WEEKNUM(I45)');
$objPHPExcel->getActiveSheet()->setCellValue('Q44', 'TOTAL');
$objPHPExcel->getActiveSheet()->SetCellValue('Y44','RM');
$objPHPExcel->getActiveSheet()->SetCellValue('AB44', '=SUM(AB25:AB43)');
$objPHPExcel->getActiveSheet()->getStyle('Q44')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('Y44')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('AA44')->getFont()->setBold(true);
One way might be to use the fluent interface.
Instead of
$objPHPExcel->getActiveSheet()->setCellValue('I47', $row['QuoNum']);
$objPHPExcel->getActiveSheet()->setCellValue('A'.$col, $num);
$objPHPExcel->getActiveSheet()->setCellValue('B'.$col, $row['product']);
$objPHPExcel->getActiveSheet()->SetCellValue('J'.$col, $row['description']);
$objPHPExcel->getActiveSheet()->SetCellValue('S'.$col, $row['unit_price']);
$objPHPExcel->getActiveSheet()->setCellValue('V'.$col, $row['UOM']);
$objPHPExcel->getActiveSheet()->SetCellValue('Y'.$col, $row['quantity']);
$objPHPExcel->getActiveSheet()->SetCellValue('AB'.$col, $row['amount']);
do
$objPHPExcel->getActiveSheet()->setCellValue('I47', $row['QuoNum'])
->setCellValue('A'.$col, $num)
->setCellValue('B'.$col, $row['product'])
->SetCellValue('J'.$col, $row['description'])
->SetCellValue('S'.$col, $row['unit_price'])
->setCellValue('V'.$col, $row['UOM'])
->SetCellValue('Y'.$col, $row['quantity'])
->SetCellValue('AB'.$col, $row['amount']);
so that you're not constantly calling $objPHPExcel->getActiveSheet()
For setting the second sheet, as the cells are identical to the first; you could create a function to set the cell values and just call that function twice (basic PHP 101). Alternatively, you could set the cells for the first sheet, then clone that sheet and set the clone as the second sheet.
Related
I've to avoid duplicate search result in a view, so what I am trying to alter the view using pre render hook. and removing the duplicates it's working fine but the problem is in the count of result. it shows the count from the query executed and this include the duplicated item too. also, I enabled the pagination with limit of 5 in a page. then the count seems to be strange it's taking the count of the elements showing in each page
function search_helper_views_pre_render(\Drupal\views\ViewExecutable $view) {
if ($view->id() == "all_news" || $view->id() == "all_publications" || $view->id() == "all_events" || $view->id() == "global_search") {
$unique_nids = $d_nids = $new_results = array();
// Loop through results and filter out duplicate results.
foreach($view->result as $key => $result) {
if(!in_array($result->nid, $unique_nids)) {
$unique_nids[] = $result->nid;
}
else {
unset($view->result[$key]);
}
}
$view->total_rows = count($view->result);
//$view->pager->total_items = count($view->result);
$view->pager->updatePageInfo();
}
}
the expected output of the $view->total_rows must be the total count of result instead of count of elements shown in the page.
You totaly done it in wrong way. as you see ( and it's clear from its name ), it's hook__views_pre_render it runs before the rendering. So its really hard to manipulate the views results and counter, pagination there.
As I see in your query you just remove duplicate Nids , so you can easily do it by Distinct drupal views feature.
Under Advanced, query settings, click on settings.
You will get this popup, now checkmark Distinct
Could do
$difference = count($view->result) - count($new_result);
$view->total_rows = $view->total_rows - $difference;
BTW Distinct setting doesn't always work, see https://www.drupal.org/project/drupal/issues/2993688
Need some help...
So, i'm trying to export data from database to excel file.
I'm able to fetch data to database,but when i'm exporting it to excel inside the while loop I only got one record.
Please help.I'm using PHPExcel 1.8.0 libray
Here is my code:
<?php
include('config/config_msdb.php');
/** Set default timezone (will throw a notice otherwise) */
date_default_timezone_set('Asia/Manila');
// include PHPExcel
require('lib/PHPExcel.php');
// create new PHPExcel object
$objPHPExcel = new PHPExcel;
// set default font
$objPHPExcel->getDefaultStyle()->getFont()->setName('Calibri');
// set default font size
$objPHPExcel->getDefaultStyle()->getFont()->setSize(10);
// create the writer
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, "Excel2007");
/**
* Define currency and number format.
*/
// currency format, € with < 0 being in red color
$currencyFormat = '#,#0.## \€;[Red]-#,#0.## \€';
// number format, with thousands separator and two decimal points.
$numberFormat = '#,#0.##;[Red]-#,#0.##';
// writer already created the first sheet for us, let's get it
$objSheet = $objPHPExcel->getActiveSheet();
// rename the sheet
$objSheet->setTitle('YellowCab');
// let's bold and size the header font and write the header
// as you can see, we can specify a range of cells, like here: cells from A1 to A4
$objSheet->getStyle('A2:P2')->getFont()->setBold(true)->setSize(12);
// write header
$objSheet->getCell('A2')->setValue('Date');
$objSheet->getCell('B2')->setValue('TC Within 30 mins');
$objSheet->getCell('C2')->setValue('Total TC');
$objSheet->getCell('D2')->setValue('%');
$objSheet->getCell('E2')->setValue("Within 15 mins");
$objSheet->getCell('F2')->setValue("Total TC");
$objSheet->getCell('G2')->setValue("%");
$objSheet->getCell('H2')->setValue("Excellent TC");
$objSheet->getCell('I2')->setValue("Total TC");
$objSheet->getCell('J2')->setValue("%");
$objSheet->getCell('K2')->setValue('Good TC');
$objSheet->getCell('L2')->setValue('Total TC');
$objSheet->getCell('M2')->setValue('%');
$objSheet->getCell('N2')->setValue('Poor TC');
$objSheet->getCell('O2')->setValue('Total TC');
$objSheet->getCell('P2')->setValue('%');
//get record
$query="SELECT pr.TransDate,pr.TC30,pr.Total_TRX1,cast(round(pr.Hitrate,0) as nvarchar (10))+'%' AS Hitrate ,pr.PDT15,pr.Total_TRX2,cast(round(pr.ProdTime,0) as nvarchar(10))+'%' AS ProdTime,pr.Excellence,pr.Total_TRX4,
cast(round(pr.ExcelPercent,0) as nvarchar(10))+'' AS ExcelPercent,pr.Good,pr.Total_TRX5,cast(round(pr.GoodPercent,0) as nvarchar(10))+'%' AS GoodPercent,
pr.Poor,pr.Total_TRX6,cast(round(pr.PoorPercent,0) as nvarchar(10))+'%' AS PoorPercent,lp.area_name FROM part_view AS pr
LEFT JOIN lp_areas AS lp ON lp.id = pr.StoreID
WHERE lp.is_delete=0 AND lp.area_status=1 AND lp.id!='43' ORDER BY pr.TransDate DESC";
$que = mssql_query($query);
$i = '3';
while($row=mssql_fetch_array($que)){
$transdate=date('Y-m-d',strtotime($row["TransDate"]));
$tc30=$row["TC30"];
$totaltrx1=$row["Total_TRX1"];
$hitrate=$row["Hitrate"];
$pdt15=$row["PDT15"];
$totaltrx2=$row["Total_TRX2"];
$prodtime=$row["ProdTime"];
$excellence=$row["Excellence"];
$totaltrx4=$row["Total_TRX4"];
$excelpercent=$row["ExcelPercent"];
$good=$row["Good"];
$totaltrx5=$row["Total_TRX5"];
$goodpercent=$row["GoodPercent"];
$poor=$row["Poor"];
$totaltrx6=$row["Total_TRX6"];
$poorpercent=$row["PoorPercent"];
$storename=$row["area_name"];
// we could get this data from database, but here we are writing for simplicity
$objSheet->getCell('A'.$i.'')->setValue($transdate);
$objSheet->getCell('B'.$i.'')->setValue($tc30);
$objSheet->getCell('C'.$i.'')->setValue($totaltrx1);
$objSheet->getCell('D'.$i.'')->setValue($hitrate);
$objSheet->getCell('E'.$i.'')->setValue($pdt15);
$objSheet->getCell('F'.$i.'')->setValue($totaltrx2);
$objSheet->getCell('G'.$i.'')->setValue($prodtime);
$objSheet->getCell('H'.$i.'')->setValue($excellence);
$objSheet->getCell('I'.$i.'')->setValue($totaltrx4);
$objSheet->getCell('J'.$i.'')->setValue($excelpercent);
$objSheet->getCell('K'.$i.'')->setValue($good);
$objSheet->getCell('L'.$i.'')->setValue($totaltrx5);
$objSheet->getCell('M'.$i.'')->setValue($goodpercent);
$objSheet->getCell('N'.$i.'')->setValue($poor);
$objSheet->getCell('O'.$i.'')->setValue($totaltrx6);
$objSheet->getCell('P'.$i.'')->setValue($poorpercent);
$i++;
// autosize the columns
$objSheet->getColumnDimension('A')->setAutoSize(true);
$objSheet->getColumnDimension('B')->setAutoSize(true);
$objSheet->getColumnDimension('C')->setAutoSize(true);
$objSheet->getColumnDimension('D')->setAutoSize(true);
$objSheet->getColumnDimension('E')->setAutoSize(true);
$objSheet->getColumnDimension('F')->setAutoSize(true);
$objSheet->getColumnDimension('G')->setAutoSize(true);
$objSheet->getColumnDimension('H')->setAutoSize(true);
$objSheet->getColumnDimension('I')->setAutoSize(true);
$objSheet->getColumnDimension('J')->setAutoSize(true);
$objSheet->getColumnDimension('K')->setAutoSize(true);
$objSheet->getColumnDimension('L')->setAutoSize(true);
$objSheet->getColumnDimension('M')->setAutoSize(true);
$objSheet->getColumnDimension('N')->setAutoSize(true);
$objSheet->getColumnDimension('O')->setAutoSize(true);
$objSheet->getColumnDimension('P')->setAutoSize(true);
//Setting the header type
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="file.xlsx"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
/* If you want to save the file on the server instead of downloading, replace the last 4 lines by
$objWriter->save('test.xlsx');
*/
}//end get rows
?>
Thanks in advance
Just to update I have successfully exported all data fetched from my database.
So here is my solution:
$i = '3';
while($row=mssql_fetch_array($que)){
$transdate=date('Y-m-d',strtotime($row["TransDate"]));
$tc30=$row["TC30"];
$totaltrx1=$row["Total_TRX1"];
$hitrate=$row["Hitrate"];
$pdt15=$row["PDT15"];
$totaltrx2=$row["Total_TRX2"];
$prodtime=$row["ProdTime"];
$excellence=$row["Excellence"];
$totaltrx4=$row["Total_TRX4"];
$excelpercent=$row["ExcelPercent"];
$good=$row["Good"];
$totaltrx5=$row["Total_TRX5"];
$goodpercent=$row["GoodPercent"];
$poor=$row["Poor"];
$totaltrx6=$row["Total_TRX6"];
$poorpercent=$row["PoorPercent"];
$storename=$row["area_name"];
$data[] = array(
'TransDate'=>$transdate,
'TC30'=>$tc30,
'Total_TRX1'=>$totaltrx1,
'Hitrate'=>$hitrate,
'PDT15'=>$pdt15,
'Total_TRX2'=>$totaltrx2,
'ProdTime'=>$prodtime,
'Excellent'=>$excellent,
'Total_TRX4'=>$totaltrx4,
'ExcelPercent'=>$excelpercent,
'Good'=>$good,
'Total_TRX5'=>$totaltrx5,
'GoodPercent'=>$goodpercent,
'Poor'=>$poor,
'Total_TRX6'=>$totaltrx6,
'PoorPercent'=>$poorpercent
);
}
$array = stripslashes(json_encode($data));
$json = (object)json_decode($array);
foreach($json AS $datas){
$objSheet->getCell('A'.$i.'')->setValue($datas->TransDate);
$objSheet->getCell('B'.$i.'')->setValue($datas->TC30);
$objSheet->getCell('C'.$i.'')->setValue($datas->Total_TRX1);
$objSheet->getCell('D'.$i.'')->setValue($datas->Hitrate);
$objSheet->getCell('E'.$i.'')->setValue($datas->PDT15);
$objSheet->getCell('F'.$i.'')->setValue($datas->Total_TRX2);
$objSheet->getCell('G'.$i.'')->setValue($datas->ProdTime);
$objSheet->getCell('H'.$i.'')->setValue($datas->Excellence);
$objSheet->getCell('I'.$i.'')->setValue($datas->Total_TRX4);
$objSheet->getCell('J'.$i.'')->setValue($datas->ExcelPercent);
$objSheet->getCell('K'.$i.'')->setValue($datas->Good);
$objSheet->getCell('L'.$i.'')->setValue($datas->Total_TRX5);
$objSheet->getCell('M'.$i.'')->setValue($datas->GoodPercent);
$objSheet->getCell('N'.$i.'')->setValue($datas->Poor);
$objSheet->getCell('O'.$i.'')->setValue($datas->Total_TRX6);
$objSheet->getCell('P'.$i.'')->setValue($datas->PoorPercent);
$i++;
}
Thanks!
i am new to PHPExcel learning from last two days and i am generating one report for the form input data. I have generated dynamically columns in the excel report but not able to set the first column as Index & last column as Date.
My code is:
// setting column names begin
$col = 1;
$row = 0;
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(0, $row, "Index No.");
foreach ($formInfo['fields'] as $fields) {
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $fields['grid-name']);
$col++;
}
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow($col, $row, 'Date & Time of Input');
// setting column names ends!
Thanks in advance for response.
You have achieved the most. I just updated your code. Now it will work like as per you wish.
// Initializing last col variable
$endcolval = 0;
// Storing the value to First Column
$objPHPExcel->setActiveSheetIndex(0)
->setCellValueByColumnAndRow(0, 1, "Index");
// Storing the rest of the values from array to the respect indexes
foreach ($formInfo['fields'] as $col=>$fields)
{
$objPHPExcel->setActiveSheetIndex(0)
->setCellValueByColumnAndRow($col+1, 1, $fields['grid-name']);
// Using the above function you can able dynamically store the values to the cell.
// setCellValueByColumnAndRow(Column_Number, Row_Number, Value_To_Save);
$endcolval = $col+1;// Getting the last column number
}
// Assigning the Date to the Last Column.
$objPHPExcel->setActiveSheetIndex(0)
->setCellValueByColumnAndRow($endcolval+1, 1, "Date");
Searched for quite a while now, but I'm stuck at the following problem.
I am using PHPexcel 1.8.0
The spreadsheet is read using the following code:
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, TRUE);
So far ok and it works well.
But some spreadsheets contain external referenced data.
And for that I want to use "getOldCalculatedValue".
How do I combine "getOldCalculatedValue" with "rangeToArray" ?
Or is "rangeToArray" inappropriate for this ?
Thanks for any help or hints !
Simple answer, you can't combine the two
rangeToArray() is a simple method for a simple purpose, it doesn't try to do anything clever, simply to return the data from the worksheet as efficiently and quickly as possible
getOldCalculatedValue() is used for a very specific circumstance, and isn't guaranteed to be correct even then, because it retrieves the last value calculated for the cell in MS EXcel itself, which ,ay not be correct if the external workbook wasn't available to MS Excel in that circumstance, or MS Excel formula evaluation was disable.
When calculating cells values from a formula, the PHPExcel calculation engine should use the getOldCalculatedValue() as a fallback if it finds an external reference, and rangeToArray() will try to use this method, but it isn't perfect, especially when that reference in nested deep inside other formulae referenced in other cells.
If you know that a formula in a cell contains an external reference, you should use getOldCalculatedValue() directly for that cell
I came up with the following solution.
Maybe not perfect, but it currently does the job. Thanks for any improvements!
With PHPExcel included and the excel file uploaded and ready, I continue with:
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
Create a new array to store the cell values of a row
$arr_row = array();
Loop through the rows
for ($rownumber = 2; $rownumber <= $highestRow; $rownumber++){
$row = $sheet->getRowIterator($rownumber)->current();
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);
Then loop through the cells of the current row
foreach ($cellIterator as $cell) {
Find cells with a formula
$cellcheck = substr($cell->getValue(),0,1);
if($cellcheck == '='){
$cell_content = $cell->getOldCalculatedValue();
}
else{
$cell_content = $cell->getValue();
}
Add the cell values to the array
array_push($arr_row,$cell_content);
Close cell loop
}
At this point I use the $arr_row to do further calculations and string formatting, before finally inserting it into a mysql table.
Close row loop
}
I made some changes in the function rangeToArray() inside Worksheet.php.
Worked fine!
public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {
// Returnvalue
$returnValue = array();
// Identify the range that we need to extract from the worksheet
list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange);
$minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1);
$minRow = $rangeStart[1];
$maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1);
$maxRow = $rangeEnd[1];
$maxCol++;
// Loop through rows
$r = -1;
for ($row = $minRow; $row <= $maxRow; ++$row) {
$rRef = ($returnCellRef) ? $row : ++$r;
$c = -1;
// Loop through columns in the current row
for ($col = $minCol; $col != $maxCol; ++$col) {
$cRef = ($returnCellRef) ? $col : ++$c;
// Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen
// so we test and retrieve directly against _cellCollection
if ($this->_cellCollection->isDataSet($col.$row)) {
// Cell exists
$cell = $this->_cellCollection->getCacheData($col.$row);
if ($cell->getValue() !== null) {
if ($cell->getValue() instanceof PHPExcel_RichText) {
$returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
} else {
if ($calculateFormulas)
{ ##################################### CHANGED LINES
if(!preg_match('/^[=].*/', $cell->getValue()))
{
$returnValue[$rRef][$cRef] = $cell->getCalculatedValue(); # THE ORIGINAL CODE ONLY HAD THIS LINE
}
else
{
$returnValue[$rRef][$cRef] = $cell->getOldCalculatedValue();
}
} ##################################### CHANGED LINES
else
{
$returnValue[$rRef][$cRef] = $cell->getValue();
}
}
if ($formatData) {
$style = $this->_parent->getCellXfByIndex($cell->getXfIndex());
$returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString(
$returnValue[$rRef][$cRef],
($style && $style->getNumberFormat()) ?
$style->getNumberFormat()->getFormatCode() :
PHPExcel_Style_NumberFormat::FORMAT_GENERAL
);
}
} else {
// Cell holds a NULL
$returnValue[$rRef][$cRef] = $nullValue;
}
} else {
// Cell doesn't exist
$returnValue[$rRef][$cRef] = $nullValue;
}
}
}
// Return
return $returnValue;
}
I want to copy the style information from cells to ranges, like Format Painter in Excel. The documentation says to do something like this:
$activeSheet->duplicateStyle($activeSheet->getStyle('A1'), 'D1:D100');
$activeSheet->duplicateStyle($activeSheet->getStyle('B1'), 'E1:E100');
There appears to be a bug because both D1:D100 and E1:E100 get the style from cell B1. If I change the order of the two lines, both ranges get the style from A1. Similarly,
$styleA = $activeSheet->getStyle('A1');
$styleB = $activeSheet->getStyle('B1');
$activeSheet->duplicateStyle($styleA, 'D1:D100');
results in D1:D100 getting style info from cell B1. The last getStyle value is used in all duplicateStyle results.
I'm sure that a future release of PHPExcel will have a fix, I just need to figure out a work-around until then.
One workround for you might be to use the style xf Indexes:
$xfIndex = $activeSheet->getCell('A1')->getXfIndex();
Then to set that value for the xfIndex of all cells in the range
for ($col = 'D'; $col != 'E'; ++$col) {
for ($row = 1; $row <= 100; ++$row) {
$activeSheet->getCell($col . $row)->setXfIndex($xfIndex);
}
}
EDIT
Alternatively, apply fix to the duplicateStyle() method in Classes/PHPExcel/Worksheet.php
lines 1479 to 1486 currently read:
if ($this->_parent->cellXfExists($pCellStyle)) {
// there is already this cell Xf in our collection
$xfIndex = $pCellStyle->getIndex();
} else {
// we don't have such a cell Xf, need to add
$workbook->addCellXf($pCellStyle);
$xfIndex = $pCellStyle->getIndex();
}
change to:
if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) {
// there is already such cell Xf in our collection
$xfIndex = $existingStyle->getIndex();
} else {
// we don't have such a cell Xf, need to add
$workbook->addCellXf($pCellStyle);
$xfIndex = $pCellStyle->getIndex();
}
Similarly in the applyFromArray() method in Classes/PHPExcel/Style.php
lines 425 to 432 currently read:
if ($workbook->cellXfExists($newStyle)) {
// there is already such cell Xf in our collection
$newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
} else {
// we don't have such a cell Xf, need to add
$workbook->addCellXf($newStyle);
$newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
}
change to:
if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
// there is already such cell Xf in our collection
$newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
} else {
// we don't have such a cell Xf, need to add
$workbook->addCellXf($newStyle);
$newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
}
EDIT #2
Fix has now been pushed to the develop branch on github. It does give a slight performance hit, depending on the number of styles in use... I'll try and get a faster version tomorrow night