@@ -157,6 +157,10 @@ private function loadZipNonamespace(string $filename, string $ns): SimpleXMLElem
157
157
Namespaces::PURL_RELATIONSHIPS => Namespaces::PURL_DRAWING ,
158
158
];
159
159
160
+ private const REL_TO_CHART = [
161
+ Namespaces::PURL_RELATIONSHIPS => Namespaces::PURL_CHART ,
162
+ ];
163
+
160
164
/**
161
165
* Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object.
162
166
*
@@ -408,17 +412,21 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
408
412
409
413
// Read the theme first, because we need the colour scheme when reading the styles
410
414
[$ workbookBasename , $ xmlNamespaceBase ] = $ this ->getWorkbookBaseName ();
415
+ $ drawingNS = self ::REL_TO_DRAWING [$ xmlNamespaceBase ] ?? Namespaces::DRAWINGML ;
416
+ $ chartNS = self ::REL_TO_CHART [$ xmlNamespaceBase ] ?? Namespaces::CHART ;
411
417
$ wbRels = $ this ->loadZip ("xl/_rels/ $ {workbookBasename}.rels " , Namespaces::RELATIONSHIPS );
412
418
$ theme = null ;
413
419
$ this ->styleReader = new Styles ();
414
420
foreach ($ wbRels ->Relationship as $ relx ) {
415
421
$ rel = self ::getAttributes ($ relx );
416
422
$ relTarget = (string ) $ rel ['Target ' ];
423
+ if (substr ($ relTarget , 0 , 4 ) === '/xl/ ' ) {
424
+ $ relTarget = substr ($ relTarget , 4 );
425
+ }
417
426
switch ($ rel ['Type ' ]) {
418
427
case "$ xmlNamespaceBase/theme " :
419
428
$ themeOrderArray = ['lt1 ' , 'dk1 ' , 'lt2 ' , 'dk2 ' ];
420
429
$ themeOrderAdditional = count ($ themeOrderArray );
421
- $ drawingNS = self ::REL_TO_DRAWING [$ xmlNamespaceBase ] ?? Namespaces::DRAWINGML ;
422
430
423
431
$ xmlTheme = $ this ->loadZip ("xl/ {$ relTarget }" , $ drawingNS );
424
432
$ xmlThemeName = self ::getAttributes ($ xmlTheme );
@@ -1204,12 +1212,20 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
1204
1212
. '/_rels/ '
1205
1213
. basename ($ fileWorksheet )
1206
1214
. '.rels ' ;
1215
+ if (substr ($ drawingFilename , 0 , 7 ) === 'xl//xl/ ' ) {
1216
+ $ drawingFilename = substr ($ drawingFilename , 4 );
1217
+ }
1207
1218
if ($ zip ->locateName ($ drawingFilename )) {
1208
1219
$ relsWorksheet = $ this ->loadZipNoNamespace ($ drawingFilename , Namespaces::RELATIONSHIPS );
1209
1220
$ drawings = [];
1210
1221
foreach ($ relsWorksheet ->Relationship as $ ele ) {
1211
1222
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
+ }
1213
1229
}
1214
1230
}
1215
1231
@@ -1234,7 +1250,13 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
1234
1250
$ images [(string ) $ ele ['Id ' ]] = self ::dirAdd ($ fileDrawing , $ ele ['Target ' ]);
1235
1251
} elseif ($ eleType === "$ xmlNamespaceBase/chart " ) {
1236
1252
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 ] = [
1238
1260
'id ' => (string ) $ ele ['Id ' ],
1239
1261
'sheet ' => $ docSheet ->getTitle (),
1240
1262
];
@@ -1326,6 +1348,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
1326
1348
'width ' => $ width ,
1327
1349
'height ' => $ height ,
1328
1350
'worksheetTitle ' => $ docSheet ->getTitle (),
1351
+ 'oneCellAnchor ' => true ,
1329
1352
];
1330
1353
}
1331
1354
}
@@ -1645,7 +1668,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
1645
1668
if ($ this ->includeCharts ) {
1646
1669
$ chartEntryRef = ltrim ((string ) $ contentType ['PartName ' ], '/ ' );
1647
1670
$ chartElements = $ this ->loadZip ($ chartEntryRef );
1648
- $ chartReader = new Chart ();
1671
+ $ chartReader = new Chart ($ chartNS , $ drawingNS );
1649
1672
$ objChart = $ chartReader ->readChart ($ chartElements , basename ($ chartEntryRef , '.xml ' ));
1650
1673
if (isset ($ charts [$ chartEntryRef ])) {
1651
1674
$ chartPositionRef = $ charts [$ chartEntryRef ]['sheet ' ] . '! ' . $ charts [$ chartEntryRef ]['id ' ];
@@ -1662,6 +1685,9 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
1662
1685
// oneCellAnchor or absoluteAnchor (e.g. Chart sheet)
1663
1686
$ objChart ->setTopLeftPosition ($ chartDetails [$ chartPositionRef ]['fromCoordinate ' ], $ chartDetails [$ chartPositionRef ]['fromOffsetX ' ], $ chartDetails [$ chartPositionRef ]['fromOffsetY ' ]);
1664
1687
$ objChart ->setBottomRightPosition ('' , $ chartDetails [$ chartPositionRef ]['width ' ], $ chartDetails [$ chartPositionRef ]['height ' ]);
1688
+ if (array_key_exists ('oneCellAnchor ' , $ chartDetails [$ chartPositionRef ])) {
1689
+ $ objChart ->setOneCellAnchor ($ chartDetails [$ chartPositionRef ]['oneCellAnchor ' ]);
1690
+ }
1665
1691
}
1666
1692
}
1667
1693
}
@@ -1823,6 +1849,11 @@ private static function getArrayItem($array, $key = 0)
1823
1849
1824
1850
private static function dirAdd ($ base , $ add )
1825
1851
{
1852
+ $ add = "$ add " ;
1853
+ if (substr ($ add , 0 , 4 ) === '/xl/ ' ) {
1854
+ $ add = substr ($ add , 4 );
1855
+ }
1856
+
1826
1857
return preg_replace ('~[^/]+/\.\./~ ' , '' , dirname ($ base ) . "/ $ add " );
1827
1858
}
1828
1859
0 commit comments