PhpSpreadsheet icon indicating copy to clipboard operation
PhpSpreadsheet copied to clipboard

Class 'ZipStream\Option\Archive' not found error

Open roel018 opened this issue 4 years ago • 5 comments

Hi! I'm getting a Class 'ZipStream\Option\Archive' not found error, I have in fact installed the ZIP extension. This is actually working fine:

var_dump(extension_loaded('zip'));

...this produces bool(true)

The error gets procudes on the following line:

$options = new Archive(); in the file: /src/PhpSpreadsheet/Writer/Xlsx.php

When I use ZipArchive in my extensions myself, however, I always need to use \ZipArchive (with the backslash). Otherwise, it won't function. How can I solve this without needing to adjust all ZipArchive occurences in PhpSpreadSheet to \ZipArchive ? Thanks!

roel018 avatar Aug 17 '20 10:08 roel018

Did you manage to fix it?

forpaul avatar Nov 06 '20 07:11 forpaul

Hi! I am facing the same issue. Could anyone please help?

tonk379 avatar Nov 08 '20 14:11 tonk379

I just replaced the xls.php code:

setSpreadsheet($spreadsheet); $writerPartsArray = [ 'stringtable' => StringTable::class, 'contenttypes' => ContentTypes::class, 'docprops' => DocProps::class, 'rels' => Rels::class, 'theme' => Theme::class, 'style' => Style::class, 'workbook' => Workbook::class, 'worksheet' => Worksheet::class, 'drawing' => Drawing::class, 'comments' => Comments::class, 'chart' => Chart::class, 'relsvba' => RelsVBA::class, 'relsribbonobjects' => RelsRibbon::class, ]; // Initialise writer parts // and Assign their parent IWriters foreach ($writerPartsArray as $writer => $class) { $this->writerParts[$writer] = new $class($this); } $hashTablesArray = ['stylesConditionalHashTable', 'fillHashTable', 'fontHashTable', 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', 'styleHashTable', ]; // Set HashTable variables foreach ($hashTablesArray as $tableName) { $this->$tableName = new HashTable(); } } /** * Get writer part. * * @param string $pPartName Writer part name * * @return \PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart */ public function getWriterPart($pPartName) { if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { return $this->writerParts[strtolower($pPartName)]; } return null; } /** * Save PhpSpreadsheet to file. * * @param string $pFilename * * @throws WriterException */ public function save($pFilename) { if ($this->spreadSheet !== null) { // garbage collect $this->spreadSheet->garbageCollect(); // If $pFilename is php://output or php://stdout, make it a temporary file... $originalFilename = $pFilename; if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { $pFilename = @tempnam(File::sysGetTempDir(), 'phpxltmp'); if ($pFilename == '') { $pFilename = $originalFilename; } } $saveDebugLog = Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog(); Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false); $saveDateReturnType = Functions::getReturnDateType(); Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); // Create string lookup table $this->stringTable = []; for ($i = 0; $i spreadSheet->getSheetCount(); ++$i) { $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); } // Create styles dictionaries $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet)); $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet)); $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet)); $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet)); $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet)); $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet)); // Create drawing dictionary $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet)); $zip = new ZipArchive(); if (file_exists($pFilename)) { unlink($pFilename); } // Try opening the ZIP file if ($zip->open($pFilename, ZipArchive::OVERWRITE) !== true) { if ($zip->open($pFilename, ZipArchive::CREATE) !== true) { throw new WriterException('Could not open ' . $pFilename . ' for writing.'); } } // Add [Content_Types].xml to ZIP file $zip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts)); //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) if ($this->spreadSheet->hasMacros()) { $macrosCode = $this->spreadSheet->getMacrosCode(); if ($macrosCode !== null) { // we have the code ? $zip->addFromString('xl/vbaProject.bin', $macrosCode); //allways in 'xl', allways named vbaProject.bin if ($this->spreadSheet->hasMacrosCertificate()) { //signed macros ? // Yes : add the certificate file and the related rels file $zip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate()); $zip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet)); } } } //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) if ($this->spreadSheet->hasRibbon()) { $tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target'); $zip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data')); if ($this->spreadSheet->hasRibbonBinObjects()) { $tmpRootPath = dirname($tmpRibbonTarget) . '/'; $ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write foreach ($ribbonBinObjects as $aPath => $aContent) { $zip->addFromString($tmpRootPath . $aPath, $aContent); } //the rels for files $zip->addFromString($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet)); } } // Add relationships to ZIP file $zip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet)); $zip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet)); // Add document properties to ZIP file $zip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet)); $zip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet)); $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet); if ($customPropertiesPart !== null) { $zip->addFromString('docProps/custom.xml', $customPropertiesPart); } // Add theme to ZIP file $zip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet)); // Add string table to ZIP file $zip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable)); // Add styles to ZIP file $zip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet)); // Add workbook to ZIP file $zip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas)); $chartCount = 0; // Add worksheets for ($i = 0; $i spreadSheet->getSheetCount(); ++$i) { $zip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts)); if ($this->includeCharts) { $charts = $this->spreadSheet->getSheet($i)->getChartCollection(); if (count($charts) > 0) { foreach ($charts as $chart) { $zip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas)); ++$chartCount; } } } } $chartRef1 = 0; // Add worksheet relationships (drawings, ...) for ($i = 0; $i spreadSheet->getSheetCount(); ++$i) { // Add relationships $zip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); // Add unparsedLoadedData $sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName(); $unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData(); if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) { foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) { $zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']); } } if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) { foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) { $zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']); } } $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); if ($this->includeCharts) { $chartCount = $this->spreadSheet->getSheet($i)->getChartCount(); } // Add drawing and image relationship parts if (($drawingCount > 0) || ($chartCount > 0)) { // Drawing relationships $zip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); // Drawings $zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) { // Drawings $zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); } // Add unparsed drawings if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings'])) { foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['Drawings'] as $relId => $drawingXml) { $drawingFile = array_search($relId, $unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']); if ($drawingFile !== false) { $drawingFile = ltrim($drawingFile, '.'); $zip->addFromString('xl' . $drawingFile, $drawingXml); } } } // Add comment relationship parts if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) { // VML Comments $zip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i))); // Comments $zip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); } // Add unparsed relationship parts if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'])) { foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'] as $vmlDrawing) { $zip->addFromString($vmlDrawing['filePath'], $vmlDrawing['content']); } } // Add header/footer relationship parts if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { // VML Drawings $zip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i))); // VML Drawing relationships $zip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i))); // Media foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { $zip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); } } } // Add media for ($i = 0; $i getDrawingHashTable()->count(); ++$i) { if ($this->getDrawingHashTable()->getByIndex($i) instanceof WorksheetDrawing) { $imageContents = null; $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); if (strpos($imagePath, 'zip://') !== false) { $imagePath = substr($imagePath, 6); $imagePathSplitted = explode('#', $imagePath); $imageZip = new ZipArchive(); $imageZip->open($imagePathSplitted[0]); $imageContents = $imageZip->getFromName($imagePathSplitted[1]); $imageZip->close(); unset($imageZip); } else { $imageContents = file_get_contents($imagePath); } $zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) { ob_start(); call_user_func( $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), $this->getDrawingHashTable()->getByIndex($i)->getImageResource() ); $imageContents = ob_get_contents(); ob_end_clean(); $zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); } } Functions::setReturnDateType($saveDateReturnType); Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); // Close file if ($zip->close() === false) { throw new WriterException("Could not close zip file $pFilename."); } // If a temporary file was used, copy it to the correct file stream if ($originalFilename != $pFilename) { if (copy($pFilename, $originalFilename) === false) { throw new WriterException("Could not copy temporary zip file $pFilename to $originalFilename."); } @unlink($pFilename); } } else { throw new WriterException('PhpSpreadsheet object unassigned.'); } } /** * Get Spreadsheet object. * * @throws WriterException * * @return Spreadsheet */ public function getSpreadsheet() { if ($this->spreadSheet !== null) { return $this->spreadSheet; } throw new WriterException('No Spreadsheet object assigned.'); } /** * Set Spreadsheet object. * * @param Spreadsheet $spreadsheet PhpSpreadsheet object * * @return Xlsx */ public function setSpreadsheet(Spreadsheet $spreadsheet) { $this->spreadSheet = $spreadsheet; return $this; } /** * Get string table. * * @return string[] */ public function getStringTable() { return $this->stringTable; } /** * Get Style HashTable. * * @return HashTable */ public function getStyleHashTable() { return $this->styleHashTable; } /** * Get Conditional HashTable. * * @return HashTable */ public function getStylesConditionalHashTable() { return $this->stylesConditionalHashTable; } /** * Get Fill HashTable. * * @return HashTable */ public function getFillHashTable() { return $this->fillHashTable; } /** * Get \PhpOffice\PhpSpreadsheet\Style\Font HashTable. * * @return HashTable */ public function getFontHashTable() { return $this->fontHashTable; } /** * Get Borders HashTable. * * @return HashTable */ public function getBordersHashTable() { return $this->bordersHashTable; } /** * Get NumberFormat HashTable. * * @return HashTable */ public function getNumFmtHashTable() { return $this->numFmtHashTable; } /** * Get \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable. * * @return HashTable */ public function getDrawingHashTable() { return $this->drawingHashTable; } /** * Get Office2003 compatibility. * * @return bool */ public function getOffice2003Compatibility() { return $this->office2003compatibility; } /** * Set Office2003 compatibility. * * @param bool $pValue Office2003 compatibility? * * @return Xlsx */ public function setOffice2003Compatibility($pValue) { $this->office2003compatibility = $pValue; return $this; } }

devil861109 avatar Nov 12 '20 09:11 devil861109

It seems you maybe did not install phpspreadsheet via composer.

Composer would grab the depency for ZipStream from https://github.com/maennchen/ZipStream-PHP

RyAndrew avatar Nov 16 '20 23:11 RyAndrew

I just updated phpspreadsheet with composer and have this error.

ErnestOstro avatar Feb 22 '22 17:02 ErnestOstro

Closing. No update in 7 months, and several similar tickets have all been due to errors in the originator's environment. Please open a new ticket if this is still not working.

oleibman avatar Sep 03 '22 00:09 oleibman

According to maennchen/zipstream-php/README.md:

  • The class ZipStream\Option\Archive has been replaced in favor of named arguments in the ZipStream\ZipStream constuctor.

ftzdomino avatar Oct 17 '23 23:10 ftzdomino

The fix is to force a downgrade of maennchen/zipstream-php, as phpspreadsheet is not yet compatible with 3.x: composer require maennchen/zipstream-php=2.4.0

ftzdomino avatar Oct 17 '23 23:10 ftzdomino

uninstall package and reinstall with composer.json and add config its work with me: "require": { "phpoffice/phpspreadsheet": "^1.28" }, "config": { "platform": { "php": "8.0" } }

aliNassif10 avatar Oct 19 '23 12:10 aliNassif10

The downgrade helped me to clear the errors. But I had to also downgrade psr/http-message from version 2.0 to 1.1 and that's when the errors got cleared Downgrading psr/http-message composer require psr/http-message=1.1

Downgrading maennchen/zipstream-php composer require maennchen/zipstream-php=2.4.0

guma256 avatar Dec 17 '23 10:12 guma256

me too , the error is same to you @guma256 . do you have fixed it ?

hongtoushizi avatar Jan 13 '24 08:01 hongtoushizi

Hi @hongtoushizi , Yes I fixed the issue by the downgrading versions as below Downgrade psr/http-message=2 to psr/http-message=1.1 by running command below sudo composer require `psr/http-message=1.1 If me maennchen/zipstream-php throws an error, also downgrade it by running the command below sudo composer require maennchen/zipstream-php=2.4.0

guma256 avatar Jan 14 '24 20:01 guma256