Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401]
1 <?php 2 3 namespace Box\Spout\Writer\Common\Manager; 4 5 use Box\Spout\Common\Entity\Row; 6 use Box\Spout\Common\Exception\IOException; 7 use Box\Spout\Common\Manager\OptionsManagerInterface; 8 use Box\Spout\Writer\Common\Creator\InternalEntityFactory; 9 use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface; 10 use Box\Spout\Writer\Common\Entity\Options; 11 use Box\Spout\Writer\Common\Entity\Sheet; 12 use Box\Spout\Writer\Common\Entity\Workbook; 13 use Box\Spout\Writer\Common\Entity\Worksheet; 14 use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface; 15 use Box\Spout\Writer\Common\Manager\Style\StyleManagerInterface; 16 use Box\Spout\Writer\Common\Manager\Style\StyleMerger; 17 use Box\Spout\Writer\Exception\SheetNotFoundException; 18 use Box\Spout\Writer\Exception\WriterException; 19 20 /** 21 * Class WorkbookManagerAbstract 22 * Abstract workbook manager, providing the generic interfaces to work with workbook. 23 */ 24 abstract class WorkbookManagerAbstract implements WorkbookManagerInterface 25 { 26 /** @var Workbook The workbook to manage */ 27 protected $workbook; 28 29 /** @var OptionsManagerInterface */ 30 protected $optionsManager; 31 32 /** @var WorksheetManagerInterface */ 33 protected $worksheetManager; 34 35 /** @var StyleManagerInterface Manages styles */ 36 protected $styleManager; 37 38 /** @var StyleMerger Helper to merge styles */ 39 protected $styleMerger; 40 41 /** @var FileSystemWithRootFolderHelperInterface Helper to perform file system operations */ 42 protected $fileSystemHelper; 43 44 /** @var InternalEntityFactory Factory to create entities */ 45 protected $entityFactory; 46 47 /** @var ManagerFactoryInterface $managerFactory Factory to create managers */ 48 protected $managerFactory; 49 50 /** @var Worksheet The worksheet where data will be written to */ 51 protected $currentWorksheet; 52 53 /** 54 * @param Workbook $workbook 55 * @param OptionsManagerInterface $optionsManager 56 * @param WorksheetManagerInterface $worksheetManager 57 * @param StyleManagerInterface $styleManager 58 * @param StyleMerger $styleMerger 59 * @param FileSystemWithRootFolderHelperInterface $fileSystemHelper 60 * @param InternalEntityFactory $entityFactory 61 * @param ManagerFactoryInterface $managerFactory 62 */ 63 public function __construct( 64 Workbook $workbook, 65 OptionsManagerInterface $optionsManager, 66 WorksheetManagerInterface $worksheetManager, 67 StyleManagerInterface $styleManager, 68 StyleMerger $styleMerger, 69 FileSystemWithRootFolderHelperInterface $fileSystemHelper, 70 InternalEntityFactory $entityFactory, 71 ManagerFactoryInterface $managerFactory 72 ) { 73 $this->workbook = $workbook; 74 $this->optionsManager = $optionsManager; 75 $this->worksheetManager = $worksheetManager; 76 $this->styleManager = $styleManager; 77 $this->styleMerger = $styleMerger; 78 $this->fileSystemHelper = $fileSystemHelper; 79 $this->entityFactory = $entityFactory; 80 $this->managerFactory = $managerFactory; 81 } 82 83 /** 84 * @return int Maximum number of rows/columns a sheet can contain 85 */ 86 abstract protected function getMaxRowsPerWorksheet(); 87 88 /** 89 * @param Sheet $sheet 90 * @return string The file path where the data for the given sheet will be stored 91 */ 92 abstract protected function getWorksheetFilePath(Sheet $sheet); 93 94 /** 95 * @return Workbook 96 */ 97 public function getWorkbook() 98 { 99 return $this->workbook; 100 } 101 102 /** 103 * Creates a new sheet in the workbook and make it the current sheet. 104 * The writing will resume where it stopped (i.e. data won't be truncated). 105 * 106 * @throws IOException If unable to open the sheet for writing 107 * @return Worksheet The created sheet 108 */ 109 public function addNewSheetAndMakeItCurrent() 110 { 111 $worksheet = $this->addNewSheet(); 112 $this->setCurrentWorksheet($worksheet); 113 114 return $worksheet; 115 } 116 117 /** 118 * Creates a new sheet in the workbook. The current sheet remains unchanged. 119 * 120 * @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing 121 * @return Worksheet The created sheet 122 */ 123 private function addNewSheet() 124 { 125 $worksheets = $this->getWorksheets(); 126 127 $newSheetIndex = count($worksheets); 128 $sheetManager = $this->managerFactory->createSheetManager(); 129 $sheet = $this->entityFactory->createSheet($newSheetIndex, $this->workbook->getInternalId(), $sheetManager); 130 131 $worksheetFilePath = $this->getWorksheetFilePath($sheet); 132 $worksheet = $this->entityFactory->createWorksheet($worksheetFilePath, $sheet); 133 134 $this->worksheetManager->startSheet($worksheet); 135 136 $worksheets[] = $worksheet; 137 $this->workbook->setWorksheets($worksheets); 138 139 return $worksheet; 140 } 141 142 /** 143 * @return Worksheet[] All the workbook's sheets 144 */ 145 public function getWorksheets() 146 { 147 return $this->workbook->getWorksheets(); 148 } 149 150 /** 151 * Returns the current sheet 152 * 153 * @return Worksheet The current sheet 154 */ 155 public function getCurrentWorksheet() 156 { 157 return $this->currentWorksheet; 158 } 159 160 /** 161 * Sets the given sheet as the current one. New data will be written to this sheet. 162 * The writing will resume where it stopped (i.e. data won't be truncated). 163 * 164 * @param Sheet $sheet The "external" sheet to set as current 165 * @throws SheetNotFoundException If the given sheet does not exist in the workbook 166 * @return void 167 */ 168 public function setCurrentSheet(Sheet $sheet) 169 { 170 $worksheet = $this->getWorksheetFromExternalSheet($sheet); 171 if ($worksheet !== null) { 172 $this->currentWorksheet = $worksheet; 173 } else { 174 throw new SheetNotFoundException('The given sheet does not exist in the workbook.'); 175 } 176 } 177 178 /** 179 * @param Worksheet $worksheet 180 * @return void 181 */ 182 private function setCurrentWorksheet($worksheet) 183 { 184 $this->currentWorksheet = $worksheet; 185 } 186 187 /** 188 * Returns the worksheet associated to the given external sheet. 189 * 190 * @param Sheet $sheet 191 * @return Worksheet|null The worksheet associated to the given external sheet or null if not found. 192 */ 193 private function getWorksheetFromExternalSheet($sheet) 194 { 195 $worksheetFound = null; 196 197 foreach ($this->getWorksheets() as $worksheet) { 198 if ($worksheet->getExternalSheet() === $sheet) { 199 $worksheetFound = $worksheet; 200 break; 201 } 202 } 203 204 return $worksheetFound; 205 } 206 207 /** 208 * Adds a row to the current sheet. 209 * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination 210 * with the creation of new worksheets if one worksheet has reached its maximum capicity. 211 * 212 * @param Row $row The row to be added 213 * @throws IOException If trying to create a new sheet and unable to open the sheet for writing 214 * @throws WriterException If unable to write data 215 * @return void 216 */ 217 public function addRowToCurrentWorksheet(Row $row) 218 { 219 $currentWorksheet = $this->getCurrentWorksheet(); 220 $hasReachedMaxRows = $this->hasCurrentWorksheetReachedMaxRows(); 221 222 // if we reached the maximum number of rows for the current sheet... 223 if ($hasReachedMaxRows) { 224 // ... continue writing in a new sheet if option set 225 if ($this->optionsManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) { 226 $currentWorksheet = $this->addNewSheetAndMakeItCurrent(); 227 228 $this->addRowToWorksheet($currentWorksheet, $row); 229 } else { 230 // otherwise, do nothing as the data won't be written anyways 231 } 232 } else { 233 $this->addRowToWorksheet($currentWorksheet, $row); 234 } 235 } 236 237 /** 238 * @return bool Whether the current worksheet has reached the maximum number of rows per sheet. 239 */ 240 private function hasCurrentWorksheetReachedMaxRows() 241 { 242 $currentWorksheet = $this->getCurrentWorksheet(); 243 244 return ($currentWorksheet->getLastWrittenRowIndex() >= $this->getMaxRowsPerWorksheet()); 245 } 246 247 /** 248 * Adds a row to the given sheet. 249 * 250 * @param Worksheet $worksheet Worksheet to write the row to 251 * @param Row $row The row to be added 252 * @throws WriterException If unable to write data 253 * @return void 254 */ 255 private function addRowToWorksheet(Worksheet $worksheet, Row $row) 256 { 257 $this->applyDefaultRowStyle($row); 258 $this->worksheetManager->addRow($worksheet, $row); 259 260 // update max num columns for the worksheet 261 $currentMaxNumColumns = $worksheet->getMaxNumColumns(); 262 $cellsCount = $row->getNumCells(); 263 $worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount)); 264 } 265 266 /** 267 * @param Row $row 268 */ 269 private function applyDefaultRowStyle(Row $row) 270 { 271 $defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE); 272 273 if ($defaultRowStyle !== null) { 274 $mergedStyle = $this->styleMerger->merge($row->getStyle(), $defaultRowStyle); 275 $row->setStyle($mergedStyle); 276 } 277 } 278 279 /** 280 * Closes the workbook and all its associated sheets. 281 * All the necessary files are written to disk and zipped together to create the final file. 282 * All the temporary files are then deleted. 283 * 284 * @param resource $finalFilePointer Pointer to the spreadsheet that will be created 285 * @return void 286 */ 287 public function close($finalFilePointer) 288 { 289 $this->closeAllWorksheets(); 290 $this->closeRemainingObjects(); 291 $this->writeAllFilesToDiskAndZipThem($finalFilePointer); 292 $this->cleanupTempFolder(); 293 } 294 295 /** 296 * Closes custom objects that are still opened 297 * 298 * @return void 299 */ 300 protected function closeRemainingObjects() 301 { 302 // do nothing by default 303 } 304 305 /** 306 * Writes all the necessary files to disk and zip them together to create the final file. 307 * 308 * @param resource $finalFilePointer Pointer to the spreadsheet that will be created 309 * @return void 310 */ 311 abstract protected function writeAllFilesToDiskAndZipThem($finalFilePointer); 312 313 /** 314 * Closes all workbook's associated sheets. 315 * 316 * @return void 317 */ 318 private function closeAllWorksheets() 319 { 320 $worksheets = $this->getWorksheets(); 321 322 foreach ($worksheets as $worksheet) { 323 $this->worksheetManager->close($worksheet); 324 } 325 } 326 327 /** 328 * Deletes the root folder created in the temp folder and all its contents. 329 * 330 * @return void 331 */ 332 protected function cleanupTempFolder() 333 { 334 $rootFolder = $this->fileSystemHelper->getRootFolder(); 335 $this->fileSystemHelper->deleteFolderRecursively($rootFolder); 336 } 337 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body