rootFolder; } /** * @return string */ public function getXlFolder() { return $this->xlFolder; } /** * @return string */ public function getXlWorksheetsFolder() { return $this->xlWorksheetsFolder; } /** * Creates all the folders needed to create a XLSX file, as well as the files that won't change. * * @return void * @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the base folders */ public function createBaseFilesAndFolders() { $this ->createRootFolder() ->createRelsFolderAndFile() ->createDocPropsFolderAndFiles() ->createXlFolderAndSubFolders(); } /** * Creates the folder that will be used as root * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder */ protected function createRootFolder() { $this->rootFolder = $this->createFolder($this->baseFolderPath, uniqid('xlsx', true)); return $this; } /** * Creates the "_rels" folder under the root folder as well as the ".rels" file in it * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder or the ".rels" file */ protected function createRelsFolderAndFile() { $this->relsFolder = $this->createFolder($this->rootFolder, self::RELS_FOLDER_NAME); $this->createRelsFile(); return $this; } /** * Creates the ".rels" file under the "_rels" folder (under root) * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the file */ protected function createRelsFile() { $relsFileContents = << EOD; $this->createFileWithContents($this->relsFolder, self::RELS_FILE_NAME, $relsFileContents); return $this; } /** * Creates the "docProps" folder under the root folder as well as the "app.xml" and "core.xml" files in it * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder or one of the files */ protected function createDocPropsFolderAndFiles() { $this->docPropsFolder = $this->createFolder($this->rootFolder, self::DOC_PROPS_FOLDER_NAME); $this->createAppXmlFile(); $this->createCoreXmlFile(); return $this; } /** * Creates the "app.xml" file under the "docProps" folder * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the file */ protected function createAppXmlFile() { $appName = self::APP_NAME; $appXmlFileContents = << $appName 0 EOD; $this->createFileWithContents($this->docPropsFolder, self::APP_XML_FILE_NAME, $appXmlFileContents); return $this; } /** * Creates the "core.xml" file under the "docProps" folder * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the file */ protected function createCoreXmlFile() { $createdDate = (new \DateTime())->format(\DateTime::W3C); $coreXmlFileContents = << $createdDate $createdDate 0 EOD; $this->createFileWithContents($this->docPropsFolder, self::CORE_XML_FILE_NAME, $coreXmlFileContents); return $this; } /** * Creates the "xl" folder under the root folder as well as its subfolders * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the folders */ protected function createXlFolderAndSubFolders() { $this->xlFolder = $this->createFolder($this->rootFolder, self::XL_FOLDER_NAME); $this->createXlRelsFolder(); $this->createXlWorksheetsFolder(); return $this; } /** * Creates the "_rels" folder under the "xl" folder * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder */ protected function createXlRelsFolder() { $this->xlRelsFolder = $this->createFolder($this->xlFolder, self::RELS_FOLDER_NAME); return $this; } /** * Creates the "worksheets" folder under the "xl" folder * * @return FileSystemHelper * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder */ protected function createXlWorksheetsFolder() { $this->xlWorksheetsFolder = $this->createFolder($this->xlFolder, self::WORKSHEETS_FOLDER_NAME); return $this; } /** * Creates the "[Content_Types].xml" file under the root folder * * @param Worksheet[] $worksheets * @return FileSystemHelper */ public function createContentTypesFile($worksheets) { $contentTypesXmlFileContents = << EOD; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $contentTypesXmlFileContents .= ''; } $contentTypesXmlFileContents .= << EOD; $this->createFileWithContents($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME, $contentTypesXmlFileContents); return $this; } /** * Creates the "workbook.xml" file under the "xl" folder * * @param Worksheet[] $worksheets * @return FileSystemHelper */ public function createWorkbookFile($worksheets) { $workbookXmlFileContents = << EOD; /** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */ $escaper = new \Box\Spout\Common\Escaper\XLSX(); /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $worksheetName = $worksheet->getExternalSheet()->getName(); $worksheetId = $worksheet->getId(); $workbookXmlFileContents .= ''; } $workbookXmlFileContents .= << EOD; $this->createFileWithContents($this->xlFolder, self::WORKBOOK_XML_FILE_NAME, $workbookXmlFileContents); return $this; } /** * Creates the "workbook.xml.res" file under the "xl/_res" folder * * @param Worksheet[] $worksheets * @return FileSystemHelper */ public function createWorkbookRelsFile($worksheets) { $workbookRelsXmlFileContents = << EOD; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $worksheetId = $worksheet->getId(); $workbookRelsXmlFileContents .= ''; } $workbookRelsXmlFileContents .= ''; $this->createFileWithContents($this->xlRelsFolder, self::WORKBOOK_RELS_XML_FILE_NAME, $workbookRelsXmlFileContents); return $this; } /** * Creates the "styles.xml" file under the "xl" folder * * @param StyleHelper $styleHelper * @return FileSystemHelper */ public function createStylesFile($styleHelper) { $stylesXmlFileContents = $styleHelper->getStylesXMLFileContent(); $this->createFileWithContents($this->xlFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents); return $this; } /** * Zips the root folder and streams the contents of the zip into the given stream * * @param resource $streamPointer Pointer to the stream to copy the zip * @return void */ public function zipRootFolderAndCopyToStream($streamPointer) { $zipHelper = new ZipHelper($this->rootFolder); // In order to have the file's mime type detected properly, files need to be added // to the zip file in a particular order. // "[Content_Types].xml" then at least 2 files located in "xl" folder should be zipped first. $zipHelper->addFileToArchive($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME); $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::WORKBOOK_XML_FILE_NAME); $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::STYLES_XML_FILE_NAME); $zipHelper->addFolderToArchive($this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); $zipHelper->closeArchiveAndCopyToStream($streamPointer); // once the zip is copied, remove it $this->deleteFile($zipHelper->getZipFilePath()); } }