1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; |
4
|
|
|
|
5
|
|
|
use PhpOffice\PhpSpreadsheet\Style\Conditional; |
6
|
|
|
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar; |
7
|
|
|
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension; |
8
|
|
|
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueObject; |
9
|
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; |
10
|
|
|
use SimpleXMLElement; |
11
|
|
|
|
12
|
|
|
class ConditionalStyles |
13
|
|
|
{ |
14
|
|
|
private $worksheet; |
15
|
|
|
|
16
|
|
|
private $worksheetXml; |
17
|
|
|
|
18
|
|
|
private $dxfs; |
19
|
|
|
|
20
|
|
|
public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml, array $dxfs = []) |
21
|
13 |
|
{ |
22
|
|
|
$this->worksheet = $workSheet; |
23
|
13 |
|
$this->worksheetXml = $worksheetXml; |
24
|
13 |
|
$this->dxfs = $dxfs; |
25
|
13 |
|
} |
26
|
13 |
|
|
27
|
|
|
public function load(): void |
28
|
13 |
|
{ |
29
|
|
|
$this->setConditionalStyles( |
30
|
13 |
|
$this->worksheet, |
31
|
13 |
|
$this->readConditionalStyles($this->worksheetXml), |
32
|
13 |
|
$this->worksheetXml->extLst |
33
|
13 |
|
); |
34
|
|
|
} |
35
|
13 |
|
|
36
|
|
|
private function readConditionalStyles($xmlSheet) |
37
|
13 |
|
{ |
38
|
|
|
$conditionals = []; |
39
|
13 |
|
foreach ($xmlSheet->conditionalFormatting as $conditional) { |
40
|
13 |
|
foreach ($conditional->cfRule as $cfRule) { |
41
|
13 |
|
if (Conditional::isValidConditionType((string) $cfRule['type']) && isset($this->dxfs[(int) ($cfRule['dxfId'])])) { |
42
|
|
|
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule; |
43
|
13 |
|
} elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) { |
44
|
13 |
|
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule; |
45
|
13 |
|
} |
46
|
13 |
|
} |
47
|
13 |
|
} |
48
|
13 |
|
|
49
|
13 |
|
return $conditionals; |
50
|
|
|
} |
51
|
10 |
|
|
52
|
3 |
|
private function setConditionalStyles(Worksheet $worksheet, array $conditionals, $xmlExtLst): void |
53
|
3 |
|
{ |
54
|
|
|
foreach ($conditionals as $ref => $cfRules) { |
55
|
|
|
ksort($cfRules); |
56
|
|
|
$conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst); |
57
|
|
|
|
58
|
13 |
|
// Extract all cell references in $ref |
59
|
|
|
$cellBlocks = explode(' ', str_replace('$', '', strtoupper($ref))); |
60
|
|
|
foreach ($cellBlocks as $cellBlock) { |
61
|
13 |
|
$worksheet->getStyle($cellBlock)->setConditionalStyles($conditionalStyles); |
62
|
|
|
} |
63
|
13 |
|
} |
64
|
13 |
|
} |
65
|
13 |
|
|
66
|
|
|
private function readStyleRules($cfRules, $extLst) |
67
|
|
|
{ |
68
|
13 |
|
$conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst); |
69
|
13 |
|
$conditionalStyles = []; |
70
|
13 |
|
foreach ($cfRules as $cfRule) { |
71
|
|
|
$objConditional = new Conditional(); |
72
|
|
|
$objConditional->setConditionType((string) $cfRule['type']); |
73
|
13 |
|
$objConditional->setOperatorType((string) $cfRule['operator']); |
74
|
|
|
|
75
|
13 |
|
if ((string) $cfRule['text'] != '') { |
76
|
|
|
$objConditional->setText((string) $cfRule['text']); |
77
|
13 |
|
} |
78
|
13 |
|
|
79
|
13 |
|
if (isset($cfRule['stopIfTrue']) && (int) $cfRule['stopIfTrue'] === 1) { |
80
|
13 |
|
$objConditional->setStopIfTrue(true); |
81
|
13 |
|
} |
82
|
13 |
|
|
83
|
|
|
if (count($cfRule->formula) > 1) { |
84
|
13 |
|
foreach ($cfRule->formula as $formula) { |
85
|
1 |
|
$objConditional->addCondition((string) $formula); |
86
|
|
|
} |
87
|
|
|
} else { |
88
|
13 |
|
$objConditional->addCondition((string) $cfRule->formula); |
89
|
1 |
|
} |
90
|
|
|
|
91
|
|
|
if (isset($cfRule->dataBar)) { |
92
|
13 |
|
$objConditional->setDataBar( |
93
|
1 |
|
$this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions) |
94
|
1 |
|
); |
95
|
|
|
} else { |
96
|
|
|
$objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]); |
97
|
13 |
|
} |
98
|
|
|
|
99
|
|
|
$conditionalStyles[] = $objConditional; |
100
|
13 |
|
} |
101
|
3 |
|
|
102
|
3 |
|
return $conditionalStyles; |
103
|
|
|
} |
104
|
|
|
|
105
|
10 |
|
private function readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions): ConditionalDataBar |
106
|
|
|
{ |
107
|
|
|
$dataBar = new ConditionalDataBar(); |
108
|
13 |
|
//dataBar attribute |
109
|
|
|
if (isset($cfRule->dataBar['showValue'])) { |
110
|
|
|
$dataBar->setShowValue((bool) $cfRule->dataBar['showValue']); |
111
|
13 |
|
} |
112
|
|
|
|
113
|
|
|
//dataBar children |
114
|
3 |
|
//conditionalFormatValueObjects |
115
|
|
|
$cfvoXml = $cfRule->dataBar->cfvo; |
116
|
3 |
|
$cfvoIndex = 0; |
117
|
|
|
foreach ((count($cfvoXml) > 1 ? $cfvoXml : [$cfvoXml]) as $cfvo) { |
118
|
3 |
|
if ($cfvoIndex === 0) { |
119
|
2 |
|
$dataBar->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val'])); |
120
|
|
|
} |
121
|
|
|
if ($cfvoIndex === 1) { |
122
|
|
|
$dataBar->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val'])); |
123
|
|
|
} |
124
|
3 |
|
++$cfvoIndex; |
125
|
3 |
|
} |
126
|
3 |
|
|
127
|
3 |
|
//color |
128
|
3 |
|
if (isset($cfRule->dataBar->color)) { |
129
|
|
|
$dataBar->setColor((string) $cfRule->dataBar->color['rgb']); |
130
|
3 |
|
} |
131
|
3 |
|
//extLst |
132
|
|
|
$this->readDataBarExtLstOfConditionalRule($dataBar, $cfRule, $conditionalFormattingRuleExtensions); |
133
|
3 |
|
|
134
|
|
|
return $dataBar; |
135
|
|
|
} |
136
|
|
|
|
137
|
3 |
|
private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, $cfRule, $conditionalFormattingRuleExtensions): void |
138
|
3 |
|
{ |
139
|
|
|
if (isset($cfRule->extLst)) { |
140
|
|
|
$ns = $cfRule->extLst->getNamespaces(true); |
141
|
3 |
|
foreach ((count($cfRule->extLst) > 0 ? $cfRule->extLst->ext : [$cfRule->extLst->ext]) as $ext) { |
142
|
|
|
$extId = (string) $ext->children($ns['x14'])->id; |
143
|
3 |
|
if (isset($conditionalFormattingRuleExtensions[$extId]) && (string) $ext['uri'] === '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') { |
144
|
|
|
$dataBar->setConditionalFormattingRuleExt($conditionalFormattingRuleExtensions[$extId]); |
145
|
|
|
} |
146
|
3 |
|
} |
147
|
|
|
} |
148
|
3 |
|
} |
149
|
|
|
} |
150
|
|
|
|