@@ -157,6 +157,10 @@ private function loadZipNonamespace(string $filename, string $ns): SimpleXMLElem
157157 Namespaces::PURL_RELATIONSHIPS => Namespaces::PURL_DRAWING ,
158158 ];
159159
160+ private const REL_TO_CHART = [
161+ Namespaces::PURL_RELATIONSHIPS => Namespaces::PURL_CHART ,
162+ ];
163+
160164 /**
161165 * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object.
162166 *
@@ -408,17 +412,21 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
408412
409413 // Read the theme first, because we need the colour scheme when reading the styles
410414 [$ workbookBasename , $ xmlNamespaceBase ] = $ this ->getWorkbookBaseName ();
415+ $ drawingNS = self ::REL_TO_DRAWING [$ xmlNamespaceBase ] ?? Namespaces::DRAWINGML ;
416+ $ chartNS = self ::REL_TO_CHART [$ xmlNamespaceBase ] ?? Namespaces::CHART ;
411417 $ wbRels = $ this ->loadZip ("xl/_rels/ $ {workbookBasename}.rels " , Namespaces::RELATIONSHIPS );
412418 $ theme = null ;
413419 $ this ->styleReader = new Styles ();
414420 foreach ($ wbRels ->Relationship as $ relx ) {
415421 $ rel = self ::getAttributes ($ relx );
416422 $ relTarget = (string ) $ rel ['Target ' ];
423+ if (substr ($ relTarget , 0 , 4 ) === '/xl/ ' ) {
424+ $ relTarget = substr ($ relTarget , 4 );
425+ }
417426 switch ($ rel ['Type ' ]) {
418427 case "$ xmlNamespaceBase/theme " :
419428 $ themeOrderArray = ['lt1 ' , 'dk1 ' , 'lt2 ' , 'dk2 ' ];
420429 $ themeOrderAdditional = count ($ themeOrderArray );
421- $ drawingNS = self ::REL_TO_DRAWING [$ xmlNamespaceBase ] ?? Namespaces::DRAWINGML ;
422430
423431 $ xmlTheme = $ this ->loadZip ("xl/ {$ relTarget }" , $ drawingNS );
424432 $ xmlThemeName = self ::getAttributes ($ xmlTheme );
@@ -1204,12 +1212,20 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
12041212 . '/_rels/ '
12051213 . basename ($ fileWorksheet )
12061214 . '.rels ' ;
1215+ if (substr ($ drawingFilename , 0 , 7 ) === 'xl//xl/ ' ) {
1216+ $ drawingFilename = substr ($ drawingFilename , 4 );
1217+ }
12071218 if ($ zip ->locateName ($ drawingFilename )) {
12081219 $ relsWorksheet = $ this ->loadZipNoNamespace ($ drawingFilename , Namespaces::RELATIONSHIPS );
12091220 $ drawings = [];
12101221 foreach ($ relsWorksheet ->Relationship as $ ele ) {
12111222 if ((string ) $ ele ['Type ' ] === "$ xmlNamespaceBase/drawing " ) {
1212- $ drawings [(string ) $ ele ['Id ' ]] = self ::dirAdd ("$ dir/ $ fileWorksheet " , $ ele ['Target ' ]);
1223+ $ eleTarget = (string ) $ ele ['Target ' ];
1224+ if (substr ($ eleTarget , 0 , 4 ) === '/xl/ ' ) {
1225+ $ drawings [(string ) $ ele ['Id ' ]] = substr ($ eleTarget , 1 );
1226+ } else {
1227+ $ drawings [(string ) $ ele ['Id ' ]] = self ::dirAdd ("$ dir/ $ fileWorksheet " , $ ele ['Target ' ]);
1228+ }
12131229 }
12141230 }
12151231
@@ -1234,7 +1250,13 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
12341250 $ images [(string ) $ ele ['Id ' ]] = self ::dirAdd ($ fileDrawing , $ ele ['Target ' ]);
12351251 } elseif ($ eleType === "$ xmlNamespaceBase/chart " ) {
12361252 if ($ this ->includeCharts ) {
1237- $ charts [self ::dirAdd ($ fileDrawing , $ ele ['Target ' ])] = [
1253+ $ eleTarget = (string ) $ ele ['Target ' ];
1254+ if (substr ($ eleTarget , 0 , 4 ) === '/xl/ ' ) {
1255+ $ index = substr ($ eleTarget , 1 );
1256+ } else {
1257+ $ index = self ::dirAdd ($ fileDrawing , $ eleTarget );
1258+ }
1259+ $ charts [$ index ] = [
12381260 'id ' => (string ) $ ele ['Id ' ],
12391261 'sheet ' => $ docSheet ->getTitle (),
12401262 ];
@@ -1326,6 +1348,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
13261348 'width ' => $ width ,
13271349 'height ' => $ height ,
13281350 'worksheetTitle ' => $ docSheet ->getTitle (),
1351+ 'oneCellAnchor ' => true ,
13291352 ];
13301353 }
13311354 }
@@ -1645,7 +1668,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
16451668 if ($ this ->includeCharts ) {
16461669 $ chartEntryRef = ltrim ((string ) $ contentType ['PartName ' ], '/ ' );
16471670 $ chartElements = $ this ->loadZip ($ chartEntryRef );
1648- $ chartReader = new Chart ();
1671+ $ chartReader = new Chart ($ chartNS , $ drawingNS );
16491672 $ objChart = $ chartReader ->readChart ($ chartElements , basename ($ chartEntryRef , '.xml ' ));
16501673 if (isset ($ charts [$ chartEntryRef ])) {
16511674 $ chartPositionRef = $ charts [$ chartEntryRef ]['sheet ' ] . '! ' . $ charts [$ chartEntryRef ]['id ' ];
@@ -1662,6 +1685,9 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
16621685 // oneCellAnchor or absoluteAnchor (e.g. Chart sheet)
16631686 $ objChart ->setTopLeftPosition ($ chartDetails [$ chartPositionRef ]['fromCoordinate ' ], $ chartDetails [$ chartPositionRef ]['fromOffsetX ' ], $ chartDetails [$ chartPositionRef ]['fromOffsetY ' ]);
16641687 $ objChart ->setBottomRightPosition ('' , $ chartDetails [$ chartPositionRef ]['width ' ], $ chartDetails [$ chartPositionRef ]['height ' ]);
1688+ if (array_key_exists ('oneCellAnchor ' , $ chartDetails [$ chartPositionRef ])) {
1689+ $ objChart ->setOneCellAnchor ($ chartDetails [$ chartPositionRef ]['oneCellAnchor ' ]);
1690+ }
16651691 }
16661692 }
16671693 }
@@ -1823,6 +1849,11 @@ private static function getArrayItem($array, $key = 0)
18231849
18241850 private static function dirAdd ($ base , $ add ): string
18251851 {
1852+ $ add = "$ add " ;
1853+ if (substr ($ add , 0 , 4 ) === '/xl/ ' ) {
1854+ $ add = substr ($ add , 4 );
1855+ }
1856+
18261857 return (string ) preg_replace ('~[^/]+/\.\./~ ' , '' , dirname ($ base ) . "/ $ add " );
18271858 }
18281859
0 commit comments