Issue 1967 conditional formatting data bar problems (#2012)
* Only store additional formatting objects for DataBars * - Ensure that Xlsx Reader/Writer can still read DataBar Conditional Formatting, while ignoring IconTypes that are triggering errors - Ensure that Xls Writer only writes CF Headers if there are non-DataBar CF Records that it needs to write - Ensure that Xlsx Reader only reads SheetView data to retrieve currently selected cells after it has read CF Records that can otherwise change the currently selected cell * Try to apply proper support for cell ranges in conditional formatting
This commit is contained in:
parent
55a41e8cae
commit
3b8ef420ac
|
|
@ -630,6 +630,12 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
|
||||
if ($xmlSheet) {
|
||||
// Setting Conditional Styles adjusts selected cells, so we need to execute this
|
||||
// before reading the sheet view data to get the actual selected cells
|
||||
if (!$this->readDataOnly && $xmlSheet->conditionalFormatting) {
|
||||
(new ConditionalStyles($docSheet, $xmlSheet, $dxfs))->load();
|
||||
}
|
||||
|
||||
if (isset($xmlSheet->sheetViews, $xmlSheet->sheetViews->sheetView)) {
|
||||
$sheetViews = new SheetViews($xmlSheet->sheetViews->sheetView, $docSheet);
|
||||
$sheetViews->load();
|
||||
|
|
@ -763,10 +769,6 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
if (!$this->readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {
|
||||
(new ConditionalStyles($docSheet, $xmlSheet, $dxfs))->load();
|
||||
}
|
||||
|
||||
$aKeys = ['sheet', 'objects', 'scenarios', 'formatCells', 'formatColumns', 'formatRows', 'insertColumns', 'insertRows', 'insertHyperlinks', 'deleteColumns', 'deleteRows', 'selectLockedCells', 'sort', 'autoFilter', 'pivotTables', 'selectUnlockedCells'];
|
||||
if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
|
||||
foreach ($aKeys as $key) {
|
||||
|
|
@ -1601,7 +1603,7 @@ class Xlsx extends BaseReader
|
|||
|
||||
// top-level style settings
|
||||
if (isset($style->quotePrefix)) {
|
||||
$docStyle->setQuotePrefix($style->quotePrefix);
|
||||
$docStyle->setQuotePrefix((bool) $style->quotePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,9 @@ class ConditionalStyles
|
|||
}
|
||||
|
||||
if (isset($cfRule->dataBar)) {
|
||||
$objConditional->setDataBar($this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions));
|
||||
$objConditional->setDataBar(
|
||||
$this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions)
|
||||
);
|
||||
} else {
|
||||
$objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class ConditionalFormattingRuleExtension
|
||||
|
|
@ -62,19 +63,23 @@ class ConditionalFormattingRuleExtension
|
|||
$conditionalFormattingRuleExtensionXml = $extLst->ext;
|
||||
}
|
||||
}
|
||||
|
||||
if ($conditionalFormattingRuleExtensionXml) {
|
||||
$ns = $conditionalFormattingRuleExtensionXml->getNamespaces(true);
|
||||
$extFormattingsXml = $conditionalFormattingRuleExtensionXml->children($ns['x14']);
|
||||
|
||||
foreach ($extFormattingsXml->children($ns['x14']) as $extFormattingXml) {
|
||||
$extCfRuleXml = $extFormattingXml->cfRule;
|
||||
if (((string) $extCfRuleXml->attributes()->type) !== Conditional::CONDITION_DATABAR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extFormattingRuleObj = new self((string) $extCfRuleXml->attributes()->id);
|
||||
$extFormattingRuleObj->setSqref((string) $extFormattingXml->children($ns['xm'])->sqref);
|
||||
$conditionalFormattingRuleExtensions[$extFormattingRuleObj->getId()] = $extFormattingRuleObj;
|
||||
|
||||
$extDataBarObj = new ConditionalDataBarExtension();
|
||||
$extFormattingRuleObj->setDataBarExt($extDataBarObj);
|
||||
|
||||
$dataBarXml = $extCfRuleXml->dataBar;
|
||||
self::parseExtDataBarAttributesFromXml($extDataBarObj, $dataBarXml);
|
||||
self::parseExtDataBarElementChildrenFromXml($extDataBarObj, $dataBarXml, $ns);
|
||||
|
|
@ -85,8 +90,10 @@ class ConditionalFormattingRuleExtension
|
|||
return $conditionalFormattingRuleExtensions;
|
||||
}
|
||||
|
||||
private static function parseExtDataBarAttributesFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml): void
|
||||
{
|
||||
private static function parseExtDataBarAttributesFromXml(
|
||||
ConditionalDataBarExtension $extDataBarObj,
|
||||
SimpleXMLElement $dataBarXml
|
||||
): void {
|
||||
$dataBarAttribute = $dataBarXml->attributes();
|
||||
if ($dataBarAttribute->minLength) {
|
||||
$extDataBarObj->setMinLength((int) $dataBarAttribute->minLength);
|
||||
|
|
|
|||
|
|
@ -539,16 +539,21 @@ class Worksheet extends BIFFwriter
|
|||
$arrConditionalStyles = $phpSheet->getConditionalStylesCollection();
|
||||
if (!empty($arrConditionalStyles)) {
|
||||
$arrConditional = [];
|
||||
// @TODO CFRule & CFHeader
|
||||
// Write CFHEADER record
|
||||
$this->writeCFHeader();
|
||||
|
||||
$cfHeaderWritten = false;
|
||||
// Write ConditionalFormattingTable records
|
||||
foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) {
|
||||
foreach ($conditionalStyles as $conditional) {
|
||||
/** @var Conditional $conditional */
|
||||
if (
|
||||
$conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
|
||||
|| $conditional->getConditionType() == Conditional::CONDITION_CELLIS
|
||||
$conditional->getConditionType() == Conditional::CONDITION_EXPRESSION ||
|
||||
$conditional->getConditionType() == Conditional::CONDITION_CELLIS
|
||||
) {
|
||||
// Write CFHEADER record (only if there are Conditional Styles that we are able to write)
|
||||
if ($cfHeaderWritten === false) {
|
||||
$this->writeCFHeader();
|
||||
$cfHeaderWritten = true;
|
||||
}
|
||||
if (!isset($arrConditional[$conditional->getHashCode()])) {
|
||||
// This hash code has been handled
|
||||
$arrConditional[$conditional->getHashCode()] = true;
|
||||
|
|
@ -4352,25 +4357,25 @@ class Worksheet extends BIFFwriter
|
|||
foreach ($this->phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
|
||||
foreach ($conditionalStyles as $conditional) {
|
||||
if (
|
||||
$conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
|
||||
|| $conditional->getConditionType() == Conditional::CONDITION_CELLIS
|
||||
$conditional->getConditionType() == Conditional::CONDITION_EXPRESSION ||
|
||||
$conditional->getConditionType() == Conditional::CONDITION_CELLIS
|
||||
) {
|
||||
if (!in_array($conditional->getHashCode(), $arrConditional)) {
|
||||
$arrConditional[] = $conditional->getHashCode();
|
||||
}
|
||||
// Cells
|
||||
$arrCoord = Coordinate::indexesFromString($cellCoordinate);
|
||||
if ($numColumnMin === null || ($numColumnMin > $arrCoord[0])) {
|
||||
$numColumnMin = $arrCoord[0];
|
||||
$rangeCoordinates = Coordinate::rangeBoundaries($cellCoordinate);
|
||||
if ($numColumnMin === null || ($numColumnMin > $rangeCoordinates[0][0])) {
|
||||
$numColumnMin = $rangeCoordinates[0][0];
|
||||
}
|
||||
if ($numColumnMax === null || ($numColumnMax < $arrCoord[0])) {
|
||||
$numColumnMax = $arrCoord[0];
|
||||
if ($numColumnMax === null || ($numColumnMax < $rangeCoordinates[1][0])) {
|
||||
$numColumnMax = $rangeCoordinates[1][0];
|
||||
}
|
||||
if ($numRowMin === null || ($numRowMin > $arrCoord[1])) {
|
||||
$numRowMin = $arrCoord[1];
|
||||
if ($numRowMin === null || ($numRowMin > $rangeCoordinates[0][1])) {
|
||||
$numRowMin = (int) $rangeCoordinates[0][1];
|
||||
}
|
||||
if ($numRowMax === null || ($numRowMax < $arrCoord[1])) {
|
||||
$numRowMax = $arrCoord[1];
|
||||
if ($numRowMax === null || ($numRowMax < $rangeCoordinates[1][1])) {
|
||||
$numRowMax = (int) $rangeCoordinates[1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue