@@ -33,6 +33,27 @@ class Styles extends BaseParserClass
3333 /** @var SimpleXMLElement */
3434 private $ styleXml ;
3535
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+
3657 public function setStyleXml (SimpleXmlElement $ styleXml ): void
3758 {
3859 $ this ->styleXml = $ styleXml ;
@@ -52,48 +73,62 @@ public function setStyleBaseData(?Theme $theme = null, array $styles = [], array
5273
5374 public function readFontStyle (Font $ fontStyle , SimpleXMLElement $ fontStyleXml ): void
5475 {
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+ }
5781 }
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+ }
6087 }
6188 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 ' ]));
6391 }
6492 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 ' ]));
6695 }
6796 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 ' ]));
7199 }
72100 $ fontStyle ->getColor ()->setARGB ($ this ->readColor ($ fontStyleXml ->color ));
73101
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+ }
78109 }
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+ }
86119 }
87120 }
88121 }
89122
90123 private function readNumberFormat (NumberFormat $ numfmtStyle , SimpleXMLElement $ numfmtStyleXml ): void
91124 {
92- if ($ numfmtStyleXml ->count () === 0 ) {
125+ if ((string ) $ numfmtStyleXml ['formatCode ' ] !== '' ) {
126+ $ numfmtStyle ->setFormatCode (self ::formatGeneral ((string ) $ numfmtStyleXml ['formatCode ' ]));
127+
93128 return ;
94129 }
95- $ numfmt = Xlsx:: getAttributes ($ numfmtStyleXml );
96- if ($ numfmt -> count () > 0 && isset ($ numfmt ['formatCode ' ])) {
130+ $ numfmt = $ this -> getStyleAttributes ($ numfmtStyleXml );
131+ if (isset ($ numfmt ['formatCode ' ])) {
97132 $ numfmtStyle ->setFormatCode (self ::formatGeneral ((string ) $ numfmt ['formatCode ' ]));
98133 }
99134 }
@@ -103,10 +138,11 @@ public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml):
103138 if ($ fillStyleXml ->gradientFill ) {
104139 /** @var SimpleXMLElement $gradientFill */
105140 $ 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 ' ]);
108144 }
109- $ fillStyle ->setRotation ((float ) ($ gradientFill ['degree ' ]));
145+ $ fillStyle ->setRotation ((float ) ($ attr ['degree ' ]));
110146 $ gradientFill ->registerXPathNamespace ('sml ' , Namespaces::MAIN );
111147 $ fillStyle ->getStartColor ()->setARGB ($ this ->readColor (self ::getArrayItem ($ gradientFill ->xpath ('sml:stop[@position=0] ' ))->color ));
112148 $ 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):
121157 $ defaultFillStyle = Fill::FILL_SOLID ;
122158 }
123159
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 ;
127168
128169 $ fillStyle ->setFillType ($ patternType );
129170 }
130171 }
131172
132173 public function readBorderStyle (Borders $ borderStyle , SimpleXMLElement $ borderStyleXml ): void
133174 {
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 );
136179 if (!$ diagonalUp && !$ diagonalDown ) {
137180 $ borderStyle ->setDiagonalDirection (Borders::DIAGONAL_NONE );
138181 } elseif ($ diagonalUp && !$ diagonalDown ) {
@@ -150,10 +193,26 @@ public function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderSt
150193 $ this ->readBorder ($ borderStyle ->getDiagonal (), $ borderStyleXml ->diagonal );
151194 }
152195
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+
153211 private function readBorder (Border $ border , SimpleXMLElement $ borderXml ): void
154212 {
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 );
157216 }
158217 if (isset ($ borderXml ->color )) {
159218 $ border ->getColor ()->setARGB ($ this ->readColor ($ borderXml ->color ));
@@ -162,25 +221,25 @@ private function readBorder(Border $border, SimpleXMLElement $borderXml): void
162221
163222 public function readAlignmentStyle (Alignment $ alignment , SimpleXMLElement $ alignmentXml ): void
164223 {
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 ) );
184243 }
185244
186245 private static function formatGeneral (string $ formatString ): string
@@ -223,8 +282,8 @@ public function readStyle(Style $docStyle, $style): void
223282
224283 // protection
225284 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 );
228287 }
229288
230289 // top-level style settings
@@ -235,13 +294,20 @@ public function readStyle(Style $docStyle, $style): void
235294
236295 /**
237296 * Read protection locked attribute.
238- *
239- * @param SimpleXMLElement|stdClass $style
240297 */
241- public function readProtectionLocked (Style $ docStyle , $ style ): void
298+ public function readProtectionLocked (Style $ docStyle , SimpleXMLElement $ style ): void
242299 {
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 )) {
245311 $ docStyle ->getProtection ()->setLocked (Protection::PROTECTION_PROTECTED );
246312 } else {
247313 $ docStyle ->getProtection ()->setLocked (Protection::PROTECTION_UNPROTECTED );
@@ -251,13 +317,20 @@ public function readProtectionLocked(Style $docStyle, $style): void
251317
252318 /**
253319 * Read protection hidden attribute.
254- *
255- * @param SimpleXMLElement|stdClass $style
256320 */
257- public function readProtectionHidden (Style $ docStyle , $ style ): void
321+ public function readProtectionHidden (Style $ docStyle , SimpleXMLElement $ style ): void
258322 {
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 )) {
261334 $ docStyle ->getProtection ()->setHidden (Protection::PROTECTION_PROTECTED );
262335 } else {
263336 $ docStyle ->getProtection ()->setHidden (Protection::PROTECTION_UNPROTECTED );
@@ -267,15 +340,18 @@ public function readProtectionHidden(Style $docStyle, $style): void
267340
268341 public function readColor (SimpleXMLElement $ color , bool $ background = false ): string
269342 {
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 ' ])) {
275351 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 ' ];
279355 $ returnColour = Color::changeBrightness ($ returnColour ?? '' , $ tintAdjust );
280356 }
281357
0 commit comments