9

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.

Alien Technology
  • 1,760
  • 1
  • 20
  • 30

1 Answers1

14

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

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • 1
    Thanks Mark - the patches worked perfectly. Insane support for a fantastic product. – Alien Technology Aug 15 '13 at 22:48
  • I found the getXfIndex() and setXfIndex() methods extremely useful. It's a pity PHPExcel's doc is so sparse because without this response I would have never guessed what an Xf is. – soger Jun 07 '16 at 12:37
  • 1
    @soger - It's just as much fun figuring out what `xf` is from the Microsoft documentation as well – Mark Baker Jun 07 '16 at 12:39
  • 1
    Actually it was my fault too because I completely forgot about the file PHPExcel developer documentation.doc that is included when you download the library. Although not complete (for example getXfIndex() and setXfIndex() is not in it) and a big word doc is not my favorite kind of documentation, it's still useful. – soger Jun 08 '16 at 13:10