[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace Box\Spout\Writer\XLSX\Helper; 4 5 use Box\Spout\Writer\Common\Helper\ZipHelper; 6 use Box\Spout\Writer\XLSX\Internal\Worksheet; 7 8 /** 9 * Class FileSystemHelper 10 * This class provides helper functions to help with the file system operations 11 * like files/folders creation & deletion for XLSX files 12 * 13 * @package Box\Spout\Writer\XLSX\Helper 14 */ 15 class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper 16 { 17 const APP_NAME = 'Spout'; 18 19 const RELS_FOLDER_NAME = '_rels'; 20 const DOC_PROPS_FOLDER_NAME = 'docProps'; 21 const XL_FOLDER_NAME = 'xl'; 22 const WORKSHEETS_FOLDER_NAME = 'worksheets'; 23 24 const RELS_FILE_NAME = '.rels'; 25 const APP_XML_FILE_NAME = 'app.xml'; 26 const CORE_XML_FILE_NAME = 'core.xml'; 27 const CONTENT_TYPES_XML_FILE_NAME = '[Content_Types].xml'; 28 const WORKBOOK_XML_FILE_NAME = 'workbook.xml'; 29 const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels'; 30 const STYLES_XML_FILE_NAME = 'styles.xml'; 31 32 /** @var string Path to the root folder inside the temp folder where the files to create the XLSX will be stored */ 33 protected $rootFolder; 34 35 /** @var string Path to the "_rels" folder inside the root folder */ 36 protected $relsFolder; 37 38 /** @var string Path to the "docProps" folder inside the root folder */ 39 protected $docPropsFolder; 40 41 /** @var string Path to the "xl" folder inside the root folder */ 42 protected $xlFolder; 43 44 /** @var string Path to the "_rels" folder inside the "xl" folder */ 45 protected $xlRelsFolder; 46 47 /** @var string Path to the "worksheets" folder inside the "xl" folder */ 48 protected $xlWorksheetsFolder; 49 50 /** 51 * @return string 52 */ 53 public function getRootFolder() 54 { 55 return $this->rootFolder; 56 } 57 58 /** 59 * @return string 60 */ 61 public function getXlFolder() 62 { 63 return $this->xlFolder; 64 } 65 66 /** 67 * @return string 68 */ 69 public function getXlWorksheetsFolder() 70 { 71 return $this->xlWorksheetsFolder; 72 } 73 74 /** 75 * Creates all the folders needed to create a XLSX file, as well as the files that won't change. 76 * 77 * @return void 78 * @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the base folders 79 */ 80 public function createBaseFilesAndFolders() 81 { 82 $this 83 ->createRootFolder() 84 ->createRelsFolderAndFile() 85 ->createDocPropsFolderAndFiles() 86 ->createXlFolderAndSubFolders(); 87 } 88 89 /** 90 * Creates the folder that will be used as root 91 * 92 * @return FileSystemHelper 93 * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder 94 */ 95 protected function createRootFolder() 96 { 97 $this->rootFolder = $this->createFolder($this->baseFolderPath, uniqid('xlsx', true)); 98 return $this; 99 } 100 101 /** 102 * Creates the "_rels" folder under the root folder as well as the ".rels" file in it 103 * 104 * @return FileSystemHelper 105 * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder or the ".rels" file 106 */ 107 protected function createRelsFolderAndFile() 108 { 109 $this->relsFolder = $this->createFolder($this->rootFolder, self::RELS_FOLDER_NAME); 110 111 $this->createRelsFile(); 112 113 return $this; 114 } 115 116 /** 117 * Creates the ".rels" file under the "_rels" folder (under root) 118 * 119 * @return FileSystemHelper 120 * @throws \Box\Spout\Common\Exception\IOException If unable to create the file 121 */ 122 protected function createRelsFile() 123 { 124 $relsFileContents = <<<EOD 125 <?xml version="1.0" encoding="UTF-8"?> 126 <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 127 <Relationship Id="rIdWorkbook" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/> 128 <Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/> 129 <Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/> 130 </Relationships> 131 EOD; 132 133 $this->createFileWithContents($this->relsFolder, self::RELS_FILE_NAME, $relsFileContents); 134 135 return $this; 136 } 137 138 /** 139 * Creates the "docProps" folder under the root folder as well as the "app.xml" and "core.xml" files in it 140 * 141 * @return FileSystemHelper 142 * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder or one of the files 143 */ 144 protected function createDocPropsFolderAndFiles() 145 { 146 $this->docPropsFolder = $this->createFolder($this->rootFolder, self::DOC_PROPS_FOLDER_NAME); 147 148 $this->createAppXmlFile(); 149 $this->createCoreXmlFile(); 150 151 return $this; 152 } 153 154 /** 155 * Creates the "app.xml" file under the "docProps" folder 156 * 157 * @return FileSystemHelper 158 * @throws \Box\Spout\Common\Exception\IOException If unable to create the file 159 */ 160 protected function createAppXmlFile() 161 { 162 $appName = self::APP_NAME; 163 $appXmlFileContents = <<<EOD 164 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 165 <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"> 166 <Application>$appName</Application> 167 <TotalTime>0</TotalTime> 168 </Properties> 169 EOD; 170 171 $this->createFileWithContents($this->docPropsFolder, self::APP_XML_FILE_NAME, $appXmlFileContents); 172 173 return $this; 174 } 175 176 /** 177 * Creates the "core.xml" file under the "docProps" folder 178 * 179 * @return FileSystemHelper 180 * @throws \Box\Spout\Common\Exception\IOException If unable to create the file 181 */ 182 protected function createCoreXmlFile() 183 { 184 $createdDate = (new \DateTime())->format(\DateTime::W3C); 185 $coreXmlFileContents = <<<EOD 186 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 187 <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 188 <dcterms:created xsi:type="dcterms:W3CDTF">$createdDate</dcterms:created> 189 <dcterms:modified xsi:type="dcterms:W3CDTF">$createdDate</dcterms:modified> 190 <cp:revision>0</cp:revision> 191 </cp:coreProperties> 192 EOD; 193 194 $this->createFileWithContents($this->docPropsFolder, self::CORE_XML_FILE_NAME, $coreXmlFileContents); 195 196 return $this; 197 } 198 199 /** 200 * Creates the "xl" folder under the root folder as well as its subfolders 201 * 202 * @return FileSystemHelper 203 * @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the folders 204 */ 205 protected function createXlFolderAndSubFolders() 206 { 207 $this->xlFolder = $this->createFolder($this->rootFolder, self::XL_FOLDER_NAME); 208 $this->createXlRelsFolder(); 209 $this->createXlWorksheetsFolder(); 210 211 return $this; 212 } 213 214 /** 215 * Creates the "_rels" folder under the "xl" folder 216 * 217 * @return FileSystemHelper 218 * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder 219 */ 220 protected function createXlRelsFolder() 221 { 222 $this->xlRelsFolder = $this->createFolder($this->xlFolder, self::RELS_FOLDER_NAME); 223 return $this; 224 } 225 226 /** 227 * Creates the "worksheets" folder under the "xl" folder 228 * 229 * @return FileSystemHelper 230 * @throws \Box\Spout\Common\Exception\IOException If unable to create the folder 231 */ 232 protected function createXlWorksheetsFolder() 233 { 234 $this->xlWorksheetsFolder = $this->createFolder($this->xlFolder, self::WORKSHEETS_FOLDER_NAME); 235 return $this; 236 } 237 238 /** 239 * Creates the "[Content_Types].xml" file under the root folder 240 * 241 * @param Worksheet[] $worksheets 242 * @return FileSystemHelper 243 */ 244 public function createContentTypesFile($worksheets) 245 { 246 $contentTypesXmlFileContents = <<<EOD 247 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 248 <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 249 <Default ContentType="application/xml" Extension="xml"/> 250 <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/> 251 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/> 252 EOD; 253 254 /** @var Worksheet $worksheet */ 255 foreach ($worksheets as $worksheet) { 256 $contentTypesXmlFileContents .= '<Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet' . $worksheet->getId() . '.xml"/>'; 257 } 258 259 $contentTypesXmlFileContents .= <<<EOD 260 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/> 261 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" PartName="/xl/sharedStrings.xml"/> 262 <Override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/docProps/core.xml"/> 263 <Override ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" PartName="/docProps/app.xml"/> 264 </Types> 265 EOD; 266 267 $this->createFileWithContents($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME, $contentTypesXmlFileContents); 268 269 return $this; 270 } 271 272 /** 273 * Creates the "workbook.xml" file under the "xl" folder 274 * 275 * @param Worksheet[] $worksheets 276 * @return FileSystemHelper 277 */ 278 public function createWorkbookFile($worksheets) 279 { 280 $workbookXmlFileContents = <<<EOD 281 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 282 <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> 283 <sheets> 284 EOD; 285 286 /** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */ 287 $escaper = new \Box\Spout\Common\Escaper\XLSX(); 288 289 /** @var Worksheet $worksheet */ 290 foreach ($worksheets as $worksheet) { 291 $worksheetName = $worksheet->getExternalSheet()->getName(); 292 $worksheetId = $worksheet->getId(); 293 $workbookXmlFileContents .= '<sheet name="' . $escaper->escape($worksheetName) . '" sheetId="' . $worksheetId . '" r:id="rIdSheet' . $worksheetId . '"/>'; 294 } 295 296 $workbookXmlFileContents .= <<<EOD 297 </sheets> 298 </workbook> 299 EOD; 300 301 $this->createFileWithContents($this->xlFolder, self::WORKBOOK_XML_FILE_NAME, $workbookXmlFileContents); 302 303 return $this; 304 } 305 306 /** 307 * Creates the "workbook.xml.res" file under the "xl/_res" folder 308 * 309 * @param Worksheet[] $worksheets 310 * @return FileSystemHelper 311 */ 312 public function createWorkbookRelsFile($worksheets) 313 { 314 $workbookRelsXmlFileContents = <<<EOD 315 <?xml version="1.0" encoding="UTF-8"?> 316 <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 317 <Relationship Id="rIdStyles" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"/> 318 <Relationship Id="rIdSharedStrings" Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"/> 319 EOD; 320 321 /** @var Worksheet $worksheet */ 322 foreach ($worksheets as $worksheet) { 323 $worksheetId = $worksheet->getId(); 324 $workbookRelsXmlFileContents .= '<Relationship Id="rIdSheet' . $worksheetId . '" Target="worksheets/sheet' . $worksheetId . '.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"/>'; 325 } 326 327 $workbookRelsXmlFileContents .= '</Relationships>'; 328 329 $this->createFileWithContents($this->xlRelsFolder, self::WORKBOOK_RELS_XML_FILE_NAME, $workbookRelsXmlFileContents); 330 331 return $this; 332 } 333 334 /** 335 * Creates the "styles.xml" file under the "xl" folder 336 * 337 * @param StyleHelper $styleHelper 338 * @return FileSystemHelper 339 */ 340 public function createStylesFile($styleHelper) 341 { 342 $stylesXmlFileContents = $styleHelper->getStylesXMLFileContent(); 343 $this->createFileWithContents($this->xlFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents); 344 345 return $this; 346 } 347 348 /** 349 * Zips the root folder and streams the contents of the zip into the given stream 350 * 351 * @param resource $streamPointer Pointer to the stream to copy the zip 352 * @return void 353 */ 354 public function zipRootFolderAndCopyToStream($streamPointer) 355 { 356 $zipHelper = new ZipHelper($this->rootFolder); 357 358 // In order to have the file's mime type detected properly, files need to be added 359 // to the zip file in a particular order. 360 // "[Content_Types].xml" then at least 2 files located in "xl" folder should be zipped first. 361 $zipHelper->addFileToArchive($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME); 362 $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::WORKBOOK_XML_FILE_NAME); 363 $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::STYLES_XML_FILE_NAME); 364 365 $zipHelper->addFolderToArchive($this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); 366 $zipHelper->closeArchiveAndCopyToStream($streamPointer); 367 368 // once the zip is copied, remove it 369 $this->deleteFile($zipHelper->getZipFilePath()); 370 } 371 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |