Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error trying to load then save a particular Excel file generated by SQL Server Reporting Services #3553

Closed
1 of 8 tasks
maddhatter opened this issue May 4, 2023 · 1 comment · Fixed by #3554
Closed
1 of 8 tasks

Comments

@maddhatter
Copy link

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

Load LinkTest.xlsx and save it.

LinkTest.xlsx is a SQL Server Reporting Services report exported as an Excel file. For reproducing this issue, the report is simply a single link to microsoft.com.

What is the current behavior?

Attempting to save the file throws:

Fatal error: Uncaught PhpOffice\PhpSpreadsheet\Writer\Exception: Invalid parameters passed. in C:\temp\XlsxBug\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx\Rels.php on line 477

PhpOffice\PhpSpreadsheet\Writer\Exception: Invalid parameters passed. in C:\temp\XlsxBug\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx\Rels.php on line 477

Call Stack:
    0.0003     402504   1. {main}() C:\temp\XlsxBug\repro.php:0
    0.0728    6976680   2. PhpOffice\PhpSpreadsheet\Writer\Xlsx->save($filename = 'C:\\temp\\LinkTestOutput.xlsx', $flags = ???) C:\temp\XlsxBug\repro.php:13
    0.0898    7154480   3. PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels->writeWorksheetRelationships($worksheet = class PhpOffice\PhpSpreadsheet\Worksheet\Worksheet { private $parent = class PhpOffice\PhpSpreadsheet\Spreadsheet { private $uniqueID = '6453de5bb83ef5.74814212'; private $properties = class PhpOffice\PhpSpreadsheet\Document\Properties { ... }; private $security = class PhpOffice\PhpSpreadsheet\Document\Security { ... }; private $workSheetCollection = [...]; private $calculationEngine = class PhpOffice\PhpSpreadsheet\Calculation\Calculation { ... }; private $activeSheetIndex = 0; private $definedNames = [...]; private $cellXfSupervisor = class PhpOffice\PhpSpreadsheet\Style\Style { ... }; private $cellXfCollection = [...]; private $cellStyleXfCollection = [...]; private $hasMacros = FALSE; private $macrosCode = NULL; private $macrosCertificate = NULL; private $ribbonXMLData = NULL; private $ribbonBinObjects = NULL; private $unparsedLoadedData = [...]; private $showHorizontalScroll = TRUE; private $showVerticalScroll = TRUE; private $showSheetTabs = TRUE; private $minimized = FALSE; private $autoFilterDateGrouping = TRUE; private $firstSheetIndex = 0; private $visibility = 'visible'; private $tabRatio = 600 }; private $cellCollection = class PhpOffice\PhpSpreadsheet\Collection\Cells { private $cache = class PhpOffice\PhpSpreadsheet\Collection\Memory\SimpleCache3 { ... }; private $parent = ...; private $currentCell = class PhpOffice\PhpSpreadsheet\Cell\Cell { ... }; private $currentCoordinate = 'B2'; private $currentCellIsDirty = FALSE; private $index = [...]; private $cachePrefix = '�R\au.#\036:' }; private $rowDimensions = [1 => class PhpOffice\PhpSpreadsheet\Worksheet\RowDimension { ... }, 2 => class PhpOffice\PhpSpreadsheet\Worksheet\RowDimension { ... }, 3 => class PhpOffice\PhpSpreadsheet\Worksheet\RowDimension { ... }]; private $defaultRowDimension = class PhpOffice\PhpSpreadsheet\Worksheet\RowDimension { private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}visible = TRUE; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}outlineLevel = 0; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}collapsed = FALSE; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}xfIndex = NULL; private $rowIndex = NULL; private $height = -1; private $zeroHeight = FALSE }; private $columnDimensions = ['A' => class PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension { ... }, 'B' => class PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension { ... }, 'C' => class PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension { ... }]; private $defaultColumnDimension = class PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension { private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}visible = TRUE; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}outlineLevel = 0; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}collapsed = FALSE; private ${PhpOffice\PhpSpreadsheet\Worksheet\Dimension}xfIndex = 0; private $columnIndex = NULL; private $width = -1; private $autoSize = FALSE }; private $drawingCollection = class ArrayObject { private $storage = [...] }; private $chartCollection = class ArrayObject { private $storage = [...] }; private $tableCollection = class ArrayObject { private $storage = [...] }; private $title = 'LinkTest'; private $sheetState = 'visible'; private $pageSetup = class PhpOffice\PhpSpreadsheet\Worksheet\PageSetup { private $paperSize = NULL; private $orientation = 'portrait'; private $scale = 100; private $fitToPage = FALSE; private $fitToHeight = 1; private $fitToWidth = 1; private $columnsToRepeatAtLeft = [...]; private $rowsToRepeatAtTop = [...]; private $horizontalCentered = FALSE; private $verticalCentered = FALSE; private $printArea = NULL; private $firstPageNumber = NULL; private $pageOrder = 'downThenOver' }; private $pageMargins = class PhpOffice\PhpSpreadsheet\Worksheet\PageMargins { private $left = 1; private $right = 1; private $top = 1; private $bottom = 1; private $header = 1; private $footer = 1 }; private $headerFooter = class PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooter { private $oddHeader = ''; private $oddFooter = ''; private $evenHeader = ''; private $evenFooter = ''; private $firstHeader = ''; private $firstFooter = ''; private $differentOddEven = FALSE; private $differentFirst = FALSE; private $scaleWithDocument = TRUE; private $alignWithMargins = FALSE; private $headerFooterImages = [...] }; private $sheetView = class PhpOffice\PhpSpreadsheet\Worksheet\SheetView { private $zoomScale = 100; private $zoomScaleNormal = 100; private $showZeros = TRUE; private $sheetviewType = 'normal' }; private $protection = class PhpOffice\PhpSpreadsheet\Worksheet\Protection { private $autoFilter = NULL; private $deleteColumns = NULL; private $deleteRows = NULL; private $formatCells = NULL; private $formatColumns = NULL; private $formatRows = NULL; private $insertColumns = NULL; private $insertHyperlinks = NULL; private $insertRows = NULL; private $objects = NULL; private $pivotTables = NULL; private $scenarios = NULL; private $selectLockedCells = NULL; private $selectUnlockedCells = NULL; private $sheet = NULL; private $sort = NULL; private $password = ''; private $algorithm = ''; private $salt = ''; private $spinCount = 10000 }; private $styles = []; private $conditionalStylesCollection = []; private $rowBreaks = []; private $columnBreaks = []; private $mergeCells = []; private $protectedCells = []; private $autoFilter = class PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter { private $workSheet = ...; private $range = ''; private $columns = [...]; private $evaluated = FALSE }; private $freezePane = NULL; private $topLeftCell = NULL; private $showGridlines = FALSE; private $printGridlines = FALSE; private $showRowColHeaders = TRUE; private $showSummaryBelow = TRUE; private $showSummaryRight = TRUE; private $comments = []; private $activeCell = 'A1'; private $selectedCells = 'A1'; private $cachedHighestColumn = 3; private $cachedHighestRow = 3; private $rightToLeft = FALSE; private $hyperlinkCollection = ['B2' => class PhpOffice\PhpSpreadsheet\Cell\Hyperlink { ... }]; private $dataValidationCollection = []; private $tabColor = NULL; private $dirty = FALSE; private $hash = '9412394574e76f7a1835eba79f128b38'; private $codeName = 'Worksheet' }, $worksheetId = 1, $includeCharts = FALSE, $tableRef = 1) C:\temp\XlsxBug\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx.php:411
    0.1124    7154600   4. PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels->writeRelationship($objWriter = class PhpOffice\PhpSpreadsheet\Shared\XMLWriter { private $tempFileName = '' }, $id = '_hyperlink_1', $type = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $target = NULL, $targetMode = 'External') C:\temp\XlsxBug\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx\Rels.php:233


Variables in local scope (#4):
  $id = '_hyperlink_1'
  $objWriter = class PhpOffice\PhpSpreadsheet\Shared\XMLWriter { private $tempFileName = '' }
  $target = NULL
  $targetMode = 'External'
  $type = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink'

What are the steps to reproduce?

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

// Load the problematic Excel file, then attempt to save it - unfortunately this requires this spreadsheet to reproduce.
$filePath = 'C:\\temp\\LinkTest.xlsx';
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('C:\\temp\\LinkTestOutput.xlsx');

If this is an issue with reading a specific spreadsheet file, then it may be appropriate to provide a sample file that demonstrates the problem; but please keep it as small as possible, and sanitize any confidential information before uploading.

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

Which versions of PhpSpreadsheet and PHP are affected?

Tested with
PHP 8.1.11
PHPSpreadsheet 1.28.0

@maddhatter
Copy link
Author

While trying to troubleshoot this issue, I narrowed it down to this line:

$relationsFileName = dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels';

$relationsFileName for the problematic file is /xl/worksheets/_rels/sheet1.xml.rels.

The leading slash appears to be the issue, and causes $zip->locateName($relationsFileName) on the next line to return false. If I modify this file to strip off the leading /, the sheet can load and save successfully.

Not sure what it is about this file in particular that is making it have the leading slash.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue May 4, 2023
Fix PHPOffice#3553. Read of `\xl\worksheets\_rels\sheet1.xml.rels` fails on the new test worksheet (generated by 3rd party product), but read of `xl\worksheets\_rels\sheet1.xml.rels` (same name without leading slash) succeeds. I'm not sure why (over 400 tests succeed with the slash), so will probably delay this a bit while I do more research.
@oleibman oleibman mentioned this issue May 4, 2023
11 tasks
oleibman added a commit that referenced this issue May 11, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
* Not Finding Rels File

Fix #3553. Read of `\xl\worksheets\_rels\sheet1.xml.rels` fails on the new test worksheet (generated by 3rd party product), but read of `xl\worksheets\_rels\sheet1.xml.rels` (same name without leading slash) succeeds. I'm not sure why (over 400 tests succeed with the slash), so will probably delay this a bit while I do more research.

* Move Fix

Move to more logical place.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant