@@ -33,6 +33,27 @@ class Styles extends BaseParserClass
33
33
/** @var SimpleXMLElement */
34
34
private $ styleXml ;
35
35
36
+ /** @var string */
37
+ private $ namespace = '' ;
38
+
39
+ public function setNamespace (string $ namespace ): void
40
+ {
41
+ $ this ->namespace = $ namespace ;
42
+ }
43
+
44
+ private function getStyleAttributes (SimpleXMLElement $ value ): SimpleXMLElement
45
+ {
46
+ $ attr = null ;
47
+ if ($ value ) {
48
+ $ attr = $ value ->attributes ('' );
49
+ if ($ attr === null || count ($ attr ) === 0 ) {
50
+ $ attr = $ value ->attributes ($ this ->namespace );
51
+ }
52
+ }
53
+
54
+ return Xlsx::testSimpleXml ($ attr );
55
+ }
56
+
36
57
public function setStyleXml (SimpleXmlElement $ styleXml ): void
37
58
{
38
59
$ this ->styleXml = $ styleXml ;
@@ -52,48 +73,62 @@ public function setStyleBaseData(?Theme $theme = null, array $styles = [], array
52
73
53
74
public function readFontStyle (Font $ fontStyle , SimpleXMLElement $ fontStyleXml ): void
54
75
{
55
- if (isset ($ fontStyleXml ->name , $ fontStyleXml ->name ['val ' ])) {
56
- $ fontStyle ->setName ((string ) $ fontStyleXml ->name ['val ' ]);
76
+ if (isset ($ fontStyleXml ->name )) {
77
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->name );
78
+ if (isset ($ attr ['val ' ])) {
79
+ $ fontStyle ->setName ((string ) $ attr ['val ' ]);
80
+ }
57
81
}
58
- if (isset ($ fontStyleXml ->sz , $ fontStyleXml ->sz ['val ' ])) {
59
- $ fontStyle ->setSize ((float ) $ fontStyleXml ->sz ['val ' ]);
82
+ if (isset ($ fontStyleXml ->sz )) {
83
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->sz );
84
+ if (isset ($ attr ['val ' ])) {
85
+ $ fontStyle ->setSize ((float ) $ attr ['val ' ]);
86
+ }
60
87
}
61
88
if (isset ($ fontStyleXml ->b )) {
62
- $ fontStyle ->setBold (!isset ($ fontStyleXml ->b ['val ' ]) || self ::boolean ((string ) $ fontStyleXml ->b ['val ' ]));
89
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->b );
90
+ $ fontStyle ->setBold (!isset ($ attr ['val ' ]) || self ::boolean ((string ) $ attr ['val ' ]));
63
91
}
64
92
if (isset ($ fontStyleXml ->i )) {
65
- $ fontStyle ->setItalic (!isset ($ fontStyleXml ->i ['val ' ]) || self ::boolean ((string ) $ fontStyleXml ->i ['val ' ]));
93
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->i );
94
+ $ fontStyle ->setItalic (!isset ($ attr ['val ' ]) || self ::boolean ((string ) $ attr ['val ' ]));
66
95
}
67
96
if (isset ($ fontStyleXml ->strike )) {
68
- $ fontStyle ->setStrikethrough (
69
- !isset ($ fontStyleXml ->strike ['val ' ]) || self ::boolean ((string ) $ fontStyleXml ->strike ['val ' ])
70
- );
97
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->strike );
98
+ $ fontStyle ->setStrikethrough (!isset ($ attr ['val ' ]) || self ::boolean ((string ) $ attr ['val ' ]));
71
99
}
72
100
$ fontStyle ->getColor ()->setARGB ($ this ->readColor ($ fontStyleXml ->color ));
73
101
74
- if (isset ($ fontStyleXml ->u ) && !isset ($ fontStyleXml ->u ['val ' ])) {
75
- $ fontStyle ->setUnderline (Font::UNDERLINE_SINGLE );
76
- } elseif (isset ($ fontStyleXml ->u , $ fontStyleXml ->u ['val ' ])) {
77
- $ fontStyle ->setUnderline ((string ) $ fontStyleXml ->u ['val ' ]);
102
+ if (isset ($ fontStyleXml ->u )) {
103
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->u );
104
+ if (!isset ($ attr ['val ' ])) {
105
+ $ fontStyle ->setUnderline (Font::UNDERLINE_SINGLE );
106
+ } else {
107
+ $ fontStyle ->setUnderline ((string ) $ attr ['val ' ]);
108
+ }
78
109
}
79
-
80
- if (isset ($ fontStyleXml ->vertAlign , $ fontStyleXml ->vertAlign ['val ' ])) {
81
- $ verticalAlign = strtolower ((string ) $ fontStyleXml ->vertAlign ['val ' ]);
82
- if ($ verticalAlign === 'superscript ' ) {
83
- $ fontStyle ->setSuperscript (true );
84
- } elseif ($ verticalAlign === 'subscript ' ) {
85
- $ fontStyle ->setSubscript (true );
110
+ if (isset ($ fontStyleXml ->vertAlign )) {
111
+ $ attr = $ this ->getStyleAttributes ($ fontStyleXml ->vertAlign );
112
+ if (!isset ($ attr ['val ' ])) {
113
+ $ verticalAlign = strtolower ((string ) $ attr ['val ' ]);
114
+ if ($ verticalAlign === 'superscript ' ) {
115
+ $ fontStyle ->setSuperscript (true );
116
+ } elseif ($ verticalAlign === 'subscript ' ) {
117
+ $ fontStyle ->setSubscript (true );
118
+ }
86
119
}
87
120
}
88
121
}
89
122
90
123
private function readNumberFormat (NumberFormat $ numfmtStyle , SimpleXMLElement $ numfmtStyleXml ): void
91
124
{
92
- if ($ numfmtStyleXml ->count () === 0 ) {
125
+ if ((string ) $ numfmtStyleXml ['formatCode ' ] !== '' ) {
126
+ $ numfmtStyle ->setFormatCode (self ::formatGeneral ((string ) $ numfmtStyleXml ['formatCode ' ]));
127
+
93
128
return ;
94
129
}
95
- $ numfmt = Xlsx:: getAttributes ($ numfmtStyleXml );
96
- if ($ numfmt -> count () > 0 && isset ($ numfmt ['formatCode ' ])) {
130
+ $ numfmt = $ this -> getStyleAttributes ($ numfmtStyleXml );
131
+ if (isset ($ numfmt ['formatCode ' ])) {
97
132
$ numfmtStyle ->setFormatCode (self ::formatGeneral ((string ) $ numfmt ['formatCode ' ]));
98
133
}
99
134
}
@@ -103,10 +138,11 @@ public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml):
103
138
if ($ fillStyleXml ->gradientFill ) {
104
139
/** @var SimpleXMLElement $gradientFill */
105
140
$ gradientFill = $ fillStyleXml ->gradientFill [0 ];
106
- if (!empty ($ gradientFill ['type ' ])) {
107
- $ fillStyle ->setFillType ((string ) $ gradientFill ['type ' ]);
141
+ $ attr = $ this ->getStyleAttributes ($ gradientFill );
142
+ if (!empty ($ attr ['type ' ])) {
143
+ $ fillStyle ->setFillType ((string ) $ attr ['type ' ]);
108
144
}
109
- $ fillStyle ->setRotation ((float ) ($ gradientFill ['degree ' ]));
145
+ $ fillStyle ->setRotation ((float ) ($ attr ['degree ' ]));
110
146
$ gradientFill ->registerXPathNamespace ('sml ' , Namespaces::MAIN );
111
147
$ fillStyle ->getStartColor ()->setARGB ($ this ->readColor (self ::getArrayItem ($ gradientFill ->xpath ('sml:stop[@position=0] ' ))->color ));
112
148
$ fillStyle ->getEndColor ()->setARGB ($ this ->readColor (self ::getArrayItem ($ gradientFill ->xpath ('sml:stop[@position=1] ' ))->color ));
@@ -121,18 +157,25 @@ public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml):
121
157
$ defaultFillStyle = Fill::FILL_SOLID ;
122
158
}
123
159
124
- $ patternType = (string ) $ fillStyleXml ->patternFill ['patternType ' ] != ''
125
- ? (string ) $ fillStyleXml ->patternFill ['patternType ' ]
126
- : $ defaultFillStyle ;
160
+ $ type = '' ;
161
+ if ((string ) $ fillStyleXml ->patternFill ['patternType ' ] !== '' ) {
162
+ $ type = (string ) $ fillStyleXml ->patternFill ['patternType ' ];
163
+ } else {
164
+ $ attr = $ this ->getStyleAttributes ($ fillStyleXml ->patternFill );
165
+ $ type = (string ) $ attr ['patternType ' ];
166
+ }
167
+ $ patternType = ($ type === '' ) ? $ defaultFillStyle : $ type ;
127
168
128
169
$ fillStyle ->setFillType ($ patternType );
129
170
}
130
171
}
131
172
132
173
public function readBorderStyle (Borders $ borderStyle , SimpleXMLElement $ borderStyleXml ): void
133
174
{
134
- $ diagonalUp = self ::boolean ((string ) $ borderStyleXml ['diagonalUp ' ]);
135
- $ diagonalDown = self ::boolean ((string ) $ borderStyleXml ['diagonalDown ' ]);
175
+ $ diagonalUp = $ this ->getAttribute ($ borderStyleXml , 'diagonalUp ' );
176
+ $ diagonalUp = self ::boolean ($ diagonalUp );
177
+ $ diagonalDown = $ this ->getAttribute ($ borderStyleXml , 'diagonalDown ' );
178
+ $ diagonalDown = self ::boolean ($ diagonalDown );
136
179
if (!$ diagonalUp && !$ diagonalDown ) {
137
180
$ borderStyle ->setDiagonalDirection (Borders::DIAGONAL_NONE );
138
181
} elseif ($ diagonalUp && !$ diagonalDown ) {
@@ -150,10 +193,26 @@ public function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderSt
150
193
$ this ->readBorder ($ borderStyle ->getDiagonal (), $ borderStyleXml ->diagonal );
151
194
}
152
195
196
+ private function getAttribute (SimpleXMLElement $ xml , string $ attribute ): string
197
+ {
198
+ $ style = '' ;
199
+ if ((string ) $ xml [$ attribute ] !== '' ) {
200
+ $ style = (string ) $ xml [$ attribute ];
201
+ } else {
202
+ $ attr = $ this ->getStyleAttributes ($ xml );
203
+ if (isset ($ attr [$ attribute ])) {
204
+ $ style = (string ) $ attr [$ attribute ];
205
+ }
206
+ }
207
+
208
+ return $ style ;
209
+ }
210
+
153
211
private function readBorder (Border $ border , SimpleXMLElement $ borderXml ): void
154
212
{
155
- if (isset ($ borderXml ['style ' ])) {
156
- $ border ->setBorderStyle ((string ) $ borderXml ['style ' ]);
213
+ $ style = $ this ->getAttribute ($ borderXml , 'style ' );
214
+ if ($ style !== '' ) {
215
+ $ border ->setBorderStyle ((string ) $ style );
157
216
}
158
217
if (isset ($ borderXml ->color )) {
159
218
$ border ->getColor ()->setARGB ($ this ->readColor ($ borderXml ->color ));
@@ -162,25 +221,25 @@ private function readBorder(Border $border, SimpleXMLElement $borderXml): void
162
221
163
222
public function readAlignmentStyle (Alignment $ alignment , SimpleXMLElement $ alignmentXml ): void
164
223
{
165
- $ alignment -> setHorizontal (( string ) $ alignmentXml[ 'horizontal ' ] );
166
- $ alignment ->setVertical (( string ) $ alignmentXml [ ' vertical ' ] );
167
-
168
- $ textRotation = 0 ;
169
- if (( int ) $ alignmentXml [ ' textRotation ' ] <= 90 ) {
170
- $ textRotation = (int ) $ alignmentXml[ 'textRotation ' ] ;
171
- } elseif (( int ) $ alignmentXml [ ' textRotation ' ] > 90 ) {
172
- $ textRotation = 90 - ( int ) $ alignmentXml [ ' textRotation ' ] ;
173
- }
174
-
175
- $ alignment -> setTextRotation (( int ) $ textRotation );
176
- $ alignment -> setWrapText ( self :: boolean (( string ) $ alignmentXml[ 'wrapText ' ]) );
177
- $ alignment ->setShrinkToFit (self ::boolean ((string ) $ alignmentXml [ ' shrinkToFit ' ] ));
178
- $ alignment -> setIndent (
179
- ( int ) (( string ) $ alignmentXml [ ' indent ' ]) > 0 ? ( int ) ((string ) $ alignmentXml [ ' indent ' ]) : 0
180
- );
181
- $ alignment ->setReadOrder (
182
- (int ) (( string ) $ alignmentXml [ ' readingOrder ' ]) > 0 ? ( int ) (( string ) $ alignmentXml[ 'readingOrder ' ]) : 0
183
- );
224
+ $ horizontal = $ this -> getAttribute ( $ alignmentXml, 'horizontal ' );
225
+ $ alignment ->setHorizontal ( $ horizontal );
226
+ $ vertical = $ this -> getAttribute ( $ alignmentXml , ' vertical ' );
227
+ $ alignment -> setVertical (( string ) $ vertical ) ;
228
+
229
+ $ textRotation = (int ) $ this -> getAttribute ( $ alignmentXml, 'textRotation ' ) ;
230
+ if ( $ textRotation > 90 ) {
231
+ $ textRotation = 90 - $ textRotation ;
232
+ }
233
+ $ alignment -> setTextRotation ( $ textRotation );
234
+
235
+ $ wrapText = $ this -> getAttribute ( $ alignmentXml, 'wrapText ' );
236
+ $ alignment ->setWrapText (self ::boolean ((string ) $ wrapText ));
237
+ $ shrinkToFit = $ this -> getAttribute ( $ alignmentXml , ' shrinkToFit ' );
238
+ $ alignment -> setShrinkToFit ( self :: boolean ((string ) $ shrinkToFit ));
239
+ $ indent = ( int ) $ this -> getAttribute ( $ alignmentXml , ' indent ' );
240
+ $ alignment ->setIndent ( max ( $ indent , 0 ));
241
+ $ readingOrder = (int ) $ this -> getAttribute ( $ alignmentXml, 'readingOrder ' );
242
+ $ alignment -> setReadOrder ( max ( $ readingOrder , 0 ) );
184
243
}
185
244
186
245
private static function formatGeneral (string $ formatString ): string
@@ -223,8 +282,8 @@ public function readStyle(Style $docStyle, $style): void
223
282
224
283
// protection
225
284
if (isset ($ style ->protection )) {
226
- $ this ->readProtectionLocked ($ docStyle , $ style );
227
- $ this ->readProtectionHidden ($ docStyle , $ style );
285
+ $ this ->readProtectionLocked ($ docStyle , $ style-> protection );
286
+ $ this ->readProtectionHidden ($ docStyle , $ style-> protection );
228
287
}
229
288
230
289
// top-level style settings
@@ -235,13 +294,20 @@ public function readStyle(Style $docStyle, $style): void
235
294
236
295
/**
237
296
* Read protection locked attribute.
238
- *
239
- * @param SimpleXMLElement|stdClass $style
240
297
*/
241
- public function readProtectionLocked (Style $ docStyle , $ style ): void
298
+ public function readProtectionLocked (Style $ docStyle , SimpleXMLElement $ style ): void
242
299
{
243
- if (isset ($ style ->protection ['locked ' ])) {
244
- if (self ::boolean ((string ) $ style ->protection ['locked ' ])) {
300
+ $ locked = '' ;
301
+ if ((string ) $ style ['locked ' ] !== '' ) {
302
+ $ locked = (string ) $ style ['locked ' ];
303
+ } else {
304
+ $ attr = $ this ->getStyleAttributes ($ style );
305
+ if (isset ($ attr ['locked ' ])) {
306
+ $ locked = (string ) $ attr ['locked ' ];
307
+ }
308
+ }
309
+ if ($ locked !== '' ) {
310
+ if (self ::boolean ($ locked )) {
245
311
$ docStyle ->getProtection ()->setLocked (Protection::PROTECTION_PROTECTED );
246
312
} else {
247
313
$ docStyle ->getProtection ()->setLocked (Protection::PROTECTION_UNPROTECTED );
@@ -251,13 +317,20 @@ public function readProtectionLocked(Style $docStyle, $style): void
251
317
252
318
/**
253
319
* Read protection hidden attribute.
254
- *
255
- * @param SimpleXMLElement|stdClass $style
256
320
*/
257
- public function readProtectionHidden (Style $ docStyle , $ style ): void
321
+ public function readProtectionHidden (Style $ docStyle , SimpleXMLElement $ style ): void
258
322
{
259
- if (isset ($ style ->protection ['hidden ' ])) {
260
- if (self ::boolean ((string ) $ style ->protection ['hidden ' ])) {
323
+ $ hidden = '' ;
324
+ if ((string ) $ style ['hidden ' ] !== '' ) {
325
+ $ hidden = (string ) $ style ['hidden ' ];
326
+ } else {
327
+ $ attr = $ this ->getStyleAttributes ($ style );
328
+ if (isset ($ attr ['hidden ' ])) {
329
+ $ hidden = (string ) $ attr ['hidden ' ];
330
+ }
331
+ }
332
+ if ($ hidden !== '' ) {
333
+ if (self ::boolean ((string ) $ hidden )) {
261
334
$ docStyle ->getProtection ()->setHidden (Protection::PROTECTION_PROTECTED );
262
335
} else {
263
336
$ docStyle ->getProtection ()->setHidden (Protection::PROTECTION_UNPROTECTED );
@@ -267,15 +340,18 @@ public function readProtectionHidden(Style $docStyle, $style): void
267
340
268
341
public function readColor (SimpleXMLElement $ color , bool $ background = false ): string
269
342
{
270
- if (isset ($ color ['rgb ' ])) {
271
- return (string ) $ color ['rgb ' ];
272
- } elseif (isset ($ color ['indexed ' ])) {
273
- return Color::indexedColor ((int ) ($ color ['indexed ' ] - 7 ), $ background )->getARGB () ?? '' ;
274
- } elseif (isset ($ color ['theme ' ])) {
343
+ $ attr = $ this ->getStyleAttributes ($ color );
344
+ if (isset ($ attr ['rgb ' ])) {
345
+ return (string ) $ attr ['rgb ' ];
346
+ }
347
+ if (isset ($ attr ['indexed ' ])) {
348
+ return Color::indexedColor ((int ) ($ attr ['indexed ' ] - 7 ), $ background )->getARGB () ?? '' ;
349
+ }
350
+ if (isset ($ attr ['theme ' ])) {
275
351
if ($ this ->theme !== null ) {
276
- $ returnColour = $ this ->theme ->getColourByIndex ((int ) $ color ['theme ' ]);
277
- if (isset ($ color ['tint ' ])) {
278
- $ tintAdjust = (float ) $ color ['tint ' ];
352
+ $ returnColour = $ this ->theme ->getColourByIndex ((int ) $ attr ['theme ' ]);
353
+ if (isset ($ attr ['tint ' ])) {
354
+ $ tintAdjust = (float ) $ attr ['tint ' ];
279
355
$ returnColour = Color::changeBrightness ($ returnColour ?? '' , $ tintAdjust );
280
356
}
281
357
0 commit comments