ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
PhpOffice\PhpSpreadsheet\Writer\Xls Class Reference
+ Inheritance diagram for PhpOffice\PhpSpreadsheet\Writer\Xls:
+ Collaboration diagram for PhpOffice\PhpSpreadsheet\Writer\Xls:

Public Member Functions

 __construct (Spreadsheet $spreadsheet)
 Create a new Xls Writer. More...
 
 save ($pFilename)
 Save Spreadsheet to file. More...
 
- Public Member Functions inherited from PhpOffice\PhpSpreadsheet\Writer\BaseWriter
 getIncludeCharts ()
 Write charts in workbook? If this is true, then the Writer will write definitions for any charts that exist in the PhpSpreadsheet object. More...
 
 setIncludeCharts ($pValue)
 Set write charts in workbook Set to true, to advise the Writer to include any charts that exist in the PhpSpreadsheet object. More...
 
 getPreCalculateFormulas ()
 Get Pre-Calculate Formulas flag If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet viewer when opening the file If false, then formulae are not calculated on save. More...
 
 setPreCalculateFormulas ($pValue)
 Set Pre-Calculate Formulas Set to true (the default) to advise the Writer to calculate all formulae on save Set to false to prevent precalculation of formulae on save. More...
 
 getUseDiskCaching ()
 Get use disk caching where possible? More...
 
 setUseDiskCaching ($pValue, $pDirectory=null)
 Set use disk caching where possible? More...
 
 getDiskCachingDirectory ()
 Get disk caching directory. More...
 
 openFileHandle ($filename)
 Open file handle. More...
 
 __construct (Spreadsheet $spreadsheet)
 IWriter constructor. More...
 
 getIncludeCharts ()
 Write charts in workbook? If this is true, then the Writer will write definitions for any charts that exist in the PhpSpreadsheet object. More...
 
 setIncludeCharts ($pValue)
 Set write charts in workbook Set to true, to advise the Writer to include any charts that exist in the PhpSpreadsheet object. More...
 
 getPreCalculateFormulas ()
 Get Pre-Calculate Formulas flag If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet viewer when opening the file If false, then formulae are not calculated on save. More...
 
 setPreCalculateFormulas ($pValue)
 Set Pre-Calculate Formulas Set to true (the default) to advise the Writer to calculate all formulae on save Set to false to prevent precalculation of formulae on save. More...
 
 save ($pFilename)
 Save PhpSpreadsheet to file. More...
 
 getUseDiskCaching ()
 Get use disk caching where possible? More...
 
 setUseDiskCaching ($pValue, $pDirectory=null)
 Set use disk caching where possible? More...
 
 getDiskCachingDirectory ()
 Get disk caching directory. More...
 

Private Member Functions

 buildWorksheetEschers ()
 Build the Worksheet Escher objects. More...
 
 processMemoryDrawing (BstoreContainer &$bstoreContainer, MemoryDrawing $drawing, string $renderingFunctionx)
 
 processDrawing (BstoreContainer &$bstoreContainer, Drawing $drawing)
 
 processBaseDrawing (BstoreContainer &$bstoreContainer, BaseDrawing $drawing)
 
 checkForDrawings ()
 
 buildWorkbookEscher ()
 Build the Escher object corresponding to the MSODRAWINGGROUP record. More...
 
 writeDocumentSummaryInformation ()
 Build the OLE Part for DocumentSummary Information. More...
 
 writeSummaryPropOle ($dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata)
 
 writeSummaryProp (string $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata)
 
 writeSummaryInformation ()
 Build the OLE Part for Summary Information. More...
 

Private Attributes

 $spreadsheet
 
 $strTotal = 0
 
 $strUnique = 0
 
 $strTable = []
 
 $colors
 
 $parser
 
 $IDCLs
 
 $summaryInformation
 
 $documentSummaryInformation
 
 $writerWorkbook
 
 $writerWorksheets
 

Additional Inherited Members

- Protected Member Functions inherited from PhpOffice\PhpSpreadsheet\Writer\BaseWriter
 maybeCloseFileHandle ()
 Close file handle only if we opened it ourselves. More...
 
- Protected Attributes inherited from PhpOffice\PhpSpreadsheet\Writer\BaseWriter
 $includeCharts = false
 
 $preCalculateFormulas = true
 
 $fileHandle
 

Detailed Description

Definition at line 30 of file Xls.php.

Constructor & Destructor Documentation

◆ __construct()

PhpOffice\PhpSpreadsheet\Writer\Xls::__construct ( Spreadsheet  $spreadsheet)

Create a new Xls Writer.

Parameters
Spreadsheet$spreadsheetPhpSpreadsheet object

Implements PhpOffice\PhpSpreadsheet\Writer\IWriter.

Definition at line 110 of file Xls.php.

111 {
112 $this->spreadsheet = $spreadsheet;
113
114 $this->parser = new Xls\Parser($spreadsheet);
115 }

References PhpOffice\PhpSpreadsheet\Writer\Xls\$spreadsheet.

Member Function Documentation

◆ buildWorkbookEscher()

PhpOffice\PhpSpreadsheet\Writer\Xls::buildWorkbookEscher ( )
private

Build the Escher object corresponding to the MSODRAWINGGROUP record.

Definition at line 500 of file Xls.php.

500 : void
501 {
502 // nothing to do if there are no drawings
503 if (!$this->checkForDrawings()) {
504 return;
505 }
506
507 // if we reach here, then there are drawings in the workbook
508 $escher = new Escher();
509
510 // dggContainer
511 $dggContainer = new DggContainer();
512 $escher->setDggContainer($dggContainer);
513
514 // set IDCLs (identifier clusters)
515 $dggContainer->setIDCLs($this->IDCLs);
516
517 // this loop is for determining maximum shape identifier of all drawing
518 $spIdMax = 0;
519 $totalCountShapes = 0;
520 $countDrawings = 0;
521
522 foreach ($this->spreadsheet->getAllsheets() as $sheet) {
523 $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet
524
525 $addCount = 0;
526 foreach ($sheet->getDrawingCollection() as $drawing) {
527 $addCount = 1;
528 ++$sheetCountShapes;
529 ++$totalCountShapes;
530
531 $spId = $sheetCountShapes | ($this->spreadsheet->getIndex($sheet) + 1) << 10;
532 $spIdMax = max($spId, $spIdMax);
533 }
534 $countDrawings += $addCount;
535 }
536
537 $dggContainer->setSpIdMax($spIdMax + 1);
538 $dggContainer->setCDgSaved($countDrawings);
539 $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing
540
541 // bstoreContainer
542 $bstoreContainer = new BstoreContainer();
543 $dggContainer->setBstoreContainer($bstoreContainer);
544
545 // the BSE's (all the images)
546 foreach ($this->spreadsheet->getAllsheets() as $sheet) {
547 foreach ($sheet->getDrawingCollection() as $drawing) {
548 $this->processBaseDrawing($bstoreContainer, $drawing);
549 }
550 }
551
552 // Set the Escher object
553 $this->writerWorkbook->setEscher($escher);
554 }
processBaseDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing)
Definition: Xls.php:473

References PhpOffice\PhpSpreadsheet\Writer\Xls\checkForDrawings(), and PhpOffice\PhpSpreadsheet\Writer\Xls\processBaseDrawing().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\save().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildWorksheetEschers()

PhpOffice\PhpSpreadsheet\Writer\Xls::buildWorksheetEschers ( )
private

Build the Worksheet Escher objects.

Definition at line 236 of file Xls.php.

236 : void
237 {
238 // 1-based index to BstoreContainer
239 $blipIndex = 0;
240 $lastReducedSpId = 0;
241 $lastSpId = 0;
242
243 foreach ($this->spreadsheet->getAllsheets() as $sheet) {
244 // sheet index
245 $sheetIndex = $sheet->getParent()->getIndex($sheet);
246
247 $escher = null;
248
249 // check if there are any shapes for this sheet
250 $filterRange = $sheet->getAutoFilter()->getRange();
251 if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {
252 continue;
253 }
254
255 // create intermediate Escher object
256 $escher = new Escher();
257
258 // dgContainer
259 $dgContainer = new DgContainer();
260
261 // set the drawing index (we use sheet index + 1)
262 $dgId = $sheet->getParent()->getIndex($sheet) + 1;
263 $dgContainer->setDgId($dgId);
264 $escher->setDgContainer($dgContainer);
265
266 // spgrContainer
267 $spgrContainer = new SpgrContainer();
268 $dgContainer->setSpgrContainer($spgrContainer);
269
270 // add one shape which is the group shape
271 $spContainer = new SpContainer();
272 $spContainer->setSpgr(true);
273 $spContainer->setSpType(0);
274 $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
275 $spgrContainer->addChild($spContainer);
276
277 // add the shapes
278
279 $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet
280
281 foreach ($sheet->getDrawingCollection() as $drawing) {
282 ++$blipIndex;
283
284 ++$countShapes[$sheetIndex];
285
286 // add the shape
287 $spContainer = new SpContainer();
288
289 // set the shape type
290 $spContainer->setSpType(0x004B);
291 // set the shape flag
292 $spContainer->setSpFlag(0x02);
293
294 // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
295 $reducedSpId = $countShapes[$sheetIndex];
296 $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
297 $spContainer->setSpId($spId);
298
299 // keep track of last reducedSpId
300 $lastReducedSpId = $reducedSpId;
301
302 // keep track of last spId
303 $lastSpId = $spId;
304
305 // set the BLIP index
306 $spContainer->setOPT(0x4104, $blipIndex);
307
308 // set coordinates and offsets, client anchor
309 $coordinates = $drawing->getCoordinates();
310 $offsetX = $drawing->getOffsetX();
311 $offsetY = $drawing->getOffsetY();
312 $width = $drawing->getWidth();
313 $height = $drawing->getHeight();
314
315 $twoAnchor = \PhpOffice\PhpSpreadsheet\Shared\Xls::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height);
316
317 $spContainer->setStartCoordinates($twoAnchor['startCoordinates']);
318 $spContainer->setStartOffsetX($twoAnchor['startOffsetX']);
319 $spContainer->setStartOffsetY($twoAnchor['startOffsetY']);
320 $spContainer->setEndCoordinates($twoAnchor['endCoordinates']);
321 $spContainer->setEndOffsetX($twoAnchor['endOffsetX']);
322 $spContainer->setEndOffsetY($twoAnchor['endOffsetY']);
323
324 $spgrContainer->addChild($spContainer);
325 }
326
327 // AutoFilters
328 if (!empty($filterRange)) {
329 $rangeBounds = Coordinate::rangeBoundaries($filterRange);
330 $iNumColStart = $rangeBounds[0][0];
331 $iNumColEnd = $rangeBounds[1][0];
332
333 $iInc = $iNumColStart;
334 while ($iInc <= $iNumColEnd) {
335 ++$countShapes[$sheetIndex];
336
337 // create an Drawing Object for the dropdown
338 $oDrawing = new BaseDrawing();
339 // get the coordinates of drawing
340 $cDrawing = Coordinate::stringFromColumnIndex($iInc) . $rangeBounds[0][1];
341 $oDrawing->setCoordinates($cDrawing);
342 $oDrawing->setWorksheet($sheet);
343
344 // add the shape
345 $spContainer = new SpContainer();
346 // set the shape type
347 $spContainer->setSpType(0x00C9);
348 // set the shape flag
349 $spContainer->setSpFlag(0x01);
350
351 // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
352 $reducedSpId = $countShapes[$sheetIndex];
353 $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
354 $spContainer->setSpId($spId);
355
356 // keep track of last reducedSpId
357 $lastReducedSpId = $reducedSpId;
358
359 // keep track of last spId
360 $lastSpId = $spId;
361
362 $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
363 $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
364 $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
365 $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash
366 $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
367
368 // set coordinates and offsets, client anchor
369 $endCoordinates = Coordinate::stringFromColumnIndex($iInc);
370 $endCoordinates .= $rangeBounds[0][1] + 1;
371
372 $spContainer->setStartCoordinates($cDrawing);
373 $spContainer->setStartOffsetX(0);
374 $spContainer->setStartOffsetY(0);
375 $spContainer->setEndCoordinates($endCoordinates);
376 $spContainer->setEndOffsetX(0);
377 $spContainer->setEndOffsetY(0);
378
379 $spgrContainer->addChild($spContainer);
380 ++$iInc;
381 }
382 }
383
384 // identifier clusters, used for workbook Escher object
385 $this->IDCLs[$dgId] = $lastReducedSpId;
386
387 // set last shape index
388 $dgContainer->setLastSpId($lastSpId);
389
390 // set the Escher object
391 $this->writerWorksheets[$sheetIndex]->setEscher($escher);
392 }
393 }
static stringFromColumnIndex($columnIndex)
String from column index.
Definition: Coordinate.php:313
static rangeBoundaries($pRange)
Calculate range boundaries.
Definition: Coordinate.php:187
static oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
Convert 1-cell anchor coordinates to 2-cell anchor coordinates This function is ported from PEAR Spre...
Definition: Xls.php:210

References PhpOffice\PhpSpreadsheet\Shared\Xls\oneAnchor2twoAnchor(), PhpOffice\PhpSpreadsheet\Cell\Coordinate\rangeBoundaries(), and PhpOffice\PhpSpreadsheet\Cell\Coordinate\stringFromColumnIndex().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\save().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkForDrawings()

PhpOffice\PhpSpreadsheet\Writer\Xls::checkForDrawings ( )
private

Definition at line 482 of file Xls.php.

482 : bool
483 {
484 // any drawings in this workbook?
485 $found = false;
486 foreach ($this->spreadsheet->getAllSheets() as $sheet) {
487 if (count($sheet->getDrawingCollection()) > 0) {
488 $found = true;
489
490 break;
491 }
492 }
493
494 return $found;
495 }

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\buildWorkbookEscher().

+ Here is the caller graph for this function:

◆ processBaseDrawing()

PhpOffice\PhpSpreadsheet\Writer\Xls::processBaseDrawing ( BstoreContainer $bstoreContainer,
BaseDrawing  $drawing 
)
private

Definition at line 473 of file Xls.php.

473 : void
474 {
475 if ($drawing instanceof Drawing) {
476 $this->processDrawing($bstoreContainer, $drawing);
477 } elseif ($drawing instanceof MemoryDrawing) {
478 $this->processMemoryDrawing($bstoreContainer, $drawing, $drawing->getRenderingFunction());
479 }
480 }
processMemoryDrawing(BstoreContainer &$bstoreContainer, MemoryDrawing $drawing, string $renderingFunctionx)
Definition: Xls.php:395
processDrawing(BstoreContainer &$bstoreContainer, Drawing $drawing)
Definition: Xls.php:425

References PhpOffice\PhpSpreadsheet\Writer\Xls\processDrawing(), and PhpOffice\PhpSpreadsheet\Writer\Xls\processMemoryDrawing().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\buildWorkbookEscher().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ processDrawing()

PhpOffice\PhpSpreadsheet\Writer\Xls::processDrawing ( BstoreContainer $bstoreContainer,
Drawing  $drawing 
)
private

Definition at line 425 of file Xls.php.

425 : void
426 {
427 $blipType = null;
428 $blipData = '';
429 $filename = $drawing->getPath();
430
431 [$imagesx, $imagesy, $imageFormat] = getimagesize($filename);
432
433 switch ($imageFormat) {
434 case 1: // GIF, not supported by BIFF8, we convert to PNG
435 $blipType = BSE::BLIPTYPE_PNG;
436 ob_start();
437 imagepng(imagecreatefromgif($filename));
438 $blipData = ob_get_contents();
439 ob_end_clean();
440
441 break;
442 case 2: // JPEG
443 $blipType = BSE::BLIPTYPE_JPEG;
444 $blipData = file_get_contents($filename);
445
446 break;
447 case 3: // PNG
448 $blipType = BSE::BLIPTYPE_PNG;
449 $blipData = file_get_contents($filename);
450
451 break;
452 case 6: // Windows DIB (BMP), we convert to PNG
453 $blipType = BSE::BLIPTYPE_PNG;
454 ob_start();
455 imagepng(SharedDrawing::imagecreatefrombmp($filename));
456 $blipData = ob_get_contents();
457 ob_end_clean();
458
459 break;
460 }
461 if ($blipData) {
462 $blip = new Blip();
463 $blip->setData($blipData);
464
465 $BSE = new BSE();
466 $BSE->setBlipType($blipType);
467 $BSE->setBlip($blip);
468
469 $bstoreContainer->addBSE($BSE);
470 }
471 }
$filename
Definition: buildRTE.php:89

References $filename, PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\addBSE(), PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\BLIPTYPE_JPEG, PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\BLIPTYPE_PNG, and PhpOffice\PhpSpreadsheet\Worksheet\Drawing\getPath().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\processBaseDrawing().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ processMemoryDrawing()

PhpOffice\PhpSpreadsheet\Writer\Xls::processMemoryDrawing ( BstoreContainer $bstoreContainer,
MemoryDrawing  $drawing,
string  $renderingFunctionx 
)
private

Definition at line 395 of file Xls.php.

395 : void
396 {
397 switch ($renderingFunctionx) {
399 $blipType = BSE::BLIPTYPE_JPEG;
400 $renderingFunction = 'imagejpeg';
401
402 break;
403 default:
404 $blipType = BSE::BLIPTYPE_PNG;
405 $renderingFunction = 'imagepng';
406
407 break;
408 }
409
410 ob_start();
411 call_user_func($renderingFunction, $drawing->getImageResource());
412 $blipData = ob_get_contents();
413 ob_end_clean();
414
415 $blip = new Blip();
416 $blip->setData($blipData);
417
418 $BSE = new BSE();
419 $BSE->setBlipType($blipType);
420 $BSE->setBlip($blip);
421
422 $bstoreContainer->addBSE($BSE);
423 }

References PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\addBSE(), PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\BLIPTYPE_JPEG, PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE\BLIPTYPE_PNG, PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing\getImageResource(), and PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing\RENDERING_JPEG.

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\processBaseDrawing().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save()

PhpOffice\PhpSpreadsheet\Writer\Xls::save (   $pFilename)

Save Spreadsheet to file.

Parameters
resource | string$pFilename

Implements PhpOffice\PhpSpreadsheet\Writer\IWriter.

Definition at line 122 of file Xls.php.

122 : void
123 {
124 // garbage collect
125 $this->spreadsheet->garbageCollect();
126
127 $saveDebugLog = Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog();
128 Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false);
129 $saveDateReturnType = Functions::getReturnDateType();
131
132 // initialize colors array
133 $this->colors = [];
134
135 // Initialise workbook writer
136 $this->writerWorkbook = new Xls\Workbook($this->spreadsheet, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser);
137
138 // Initialise worksheet writers
139 $countSheets = $this->spreadsheet->getSheetCount();
140 for ($i = 0; $i < $countSheets; ++$i) {
141 $this->writerWorksheets[$i] = new Xls\Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->spreadsheet->getSheet($i));
142 }
143
144 // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.
145 $this->buildWorksheetEschers();
146 $this->buildWorkbookEscher();
147
148 // add 15 identical cell style Xfs
149 // for now, we use the first cellXf instead of cellStyleXf
150 $cellXfCollection = $this->spreadsheet->getCellXfCollection();
151 for ($i = 0; $i < 15; ++$i) {
152 $this->writerWorkbook->addXfWriter($cellXfCollection[0], true);
153 }
154
155 // add all the cell Xfs
156 foreach ($this->spreadsheet->getCellXfCollection() as $style) {
157 $this->writerWorkbook->addXfWriter($style, false);
158 }
159
160 // add fonts from rich text eleemnts
161 for ($i = 0; $i < $countSheets; ++$i) {
162 foreach ($this->writerWorksheets[$i]->phpSheet->getCoordinates() as $coordinate) {
163 $cell = $this->writerWorksheets[$i]->phpSheet->getCell($coordinate);
164 $cVal = $cell->getValue();
165 if ($cVal instanceof RichText) {
166 $elements = $cVal->getRichTextElements();
167 foreach ($elements as $element) {
168 if ($element instanceof Run) {
169 $font = $element->getFont();
170 $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font);
171 }
172 }
173 }
174 }
175 }
176
177 // initialize OLE file
178 $workbookStreamName = 'Workbook';
179 $OLE = new File(OLE::ascToUcs($workbookStreamName));
180
181 // Write the worksheet streams before the global workbook stream,
182 // because the byte sizes of these are needed in the global workbook stream
183 $worksheetSizes = [];
184 for ($i = 0; $i < $countSheets; ++$i) {
185 $this->writerWorksheets[$i]->close();
186 $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize;
187 }
188
189 // add binary data for global workbook stream
190 $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes));
191
192 // add binary data for sheet streams
193 for ($i = 0; $i < $countSheets; ++$i) {
194 $OLE->append($this->writerWorksheets[$i]->getData());
195 }
196
197 $this->documentSummaryInformation = $this->writeDocumentSummaryInformation();
198 // initialize OLE Document Summary Information
199 if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) {
200 $OLE_DocumentSummaryInformation = new File(OLE::ascToUcs(chr(5) . 'DocumentSummaryInformation'));
201 $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation);
202 }
203
204 $this->summaryInformation = $this->writeSummaryInformation();
205 // initialize OLE Summary Information
206 if (isset($this->summaryInformation) && !empty($this->summaryInformation)) {
207 $OLE_SummaryInformation = new File(OLE::ascToUcs(chr(5) . 'SummaryInformation'));
208 $OLE_SummaryInformation->append($this->summaryInformation);
209 }
210
211 // define OLE Parts
212 $arrRootData = [$OLE];
213 // initialize OLE Properties file
214 if (isset($OLE_SummaryInformation)) {
215 $arrRootData[] = $OLE_SummaryInformation;
216 }
217 // initialize OLE Extended Properties file
218 if (isset($OLE_DocumentSummaryInformation)) {
219 $arrRootData[] = $OLE_DocumentSummaryInformation;
220 }
221
222 $time = $this->spreadsheet->getProperties()->getModified();
223 $root = new Root($time, $time, $arrRootData);
224 // save the OLE file
225 $this->openFileHandle($pFilename);
226 $root->save($this->fileHandle);
227 $this->maybeCloseFileHandle();
228
229 Functions::setReturnDateType($saveDateReturnType);
230 Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
231 }
static getInstance(?Spreadsheet $spreadsheet=null)
Get an instance of this class.
static setReturnDateType($returnDateType)
Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric o...
Definition: Functions.php:109
static getReturnDateType()
Return the current Return Date Format for functions that return a date/time (Excel,...
Definition: Functions.php:133
static ascToUcs($ascii)
Utility function to transform ASCII text to Unicode.
Definition: OLE.php:478
openFileHandle($filename)
Open file handle.
Definition: BaseWriter.php:102
maybeCloseFileHandle()
Close file handle only if we opened it ourselves.
Definition: BaseWriter.php:123
writeSummaryInformation()
Build the OLE Part for Summary Information.
Definition: Xls.php:803
buildWorkbookEscher()
Build the Escher object corresponding to the MSODRAWINGGROUP record.
Definition: Xls.php:500
buildWorksheetEschers()
Build the Worksheet Escher objects.
Definition: Xls.php:236
writeDocumentSummaryInformation()
Build the OLE Part for DocumentSummary Information.
Definition: Xls.php:561
$i
Definition: disco.tpl.php:19
$style
Definition: example_012.php:70
$time
Definition: cron.php:21
$root
Definition: sabredav.php:45

References $i, $root, $style, $time, PhpOffice\PhpSpreadsheet\Shared\OLE\ascToUcs(), PhpOffice\PhpSpreadsheet\Writer\Xls\buildWorkbookEscher(), PhpOffice\PhpSpreadsheet\Writer\Xls\buildWorksheetEschers(), PhpOffice\PhpSpreadsheet\Calculation\Calculation\getInstance(), PhpOffice\PhpSpreadsheet\Calculation\Functions\getReturnDateType(), PhpOffice\PhpSpreadsheet\Writer\BaseWriter\maybeCloseFileHandle(), PhpOffice\PhpSpreadsheet\Writer\BaseWriter\openFileHandle(), PhpOffice\PhpSpreadsheet\Calculation\Functions\RETURNDATE_EXCEL, PhpOffice\PhpSpreadsheet\Calculation\Functions\setReturnDateType(), PhpOffice\PhpSpreadsheet\Writer\Xls\writeDocumentSummaryInformation(), and PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryInformation().

+ Here is the call graph for this function:

◆ writeDocumentSummaryInformation()

PhpOffice\PhpSpreadsheet\Writer\Xls::writeDocumentSummaryInformation ( )
private

Build the OLE Part for DocumentSummary Information.

Returns
string

Definition at line 561 of file Xls.php.

562 {
563 // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
564 $data = pack('v', 0xFFFE);
565 // offset: 2; size: 2;
566 $data .= pack('v', 0x0000);
567 // offset: 4; size: 2; OS version
568 $data .= pack('v', 0x0106);
569 // offset: 6; size: 2; OS indicator
570 $data .= pack('v', 0x0002);
571 // offset: 8; size: 16
572 $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
573 // offset: 24; size: 4; section count
574 $data .= pack('V', 0x0001);
575
576 // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae
577 $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
578 // offset: 44; size: 4; offset of the start
579 $data .= pack('V', 0x30);
580
581 // SECTION
582 $dataSection = [];
583 $dataSection_NumProps = 0;
584 $dataSection_Summary = '';
585 $dataSection_Content = '';
586
587 // GKPIDDSI_CODEPAGE: CodePage
588 $dataSection[] = [
589 'summary' => ['pack' => 'V', 'data' => 0x01],
590 'offset' => ['pack' => 'V'],
591 'type' => ['pack' => 'V', 'data' => 0x02], // 2 byte signed integer
592 'data' => ['data' => 1252],
593 ];
594 ++$dataSection_NumProps;
595
596 // GKPIDDSI_CATEGORY : Category
597 $dataProp = $this->spreadsheet->getProperties()->getCategory();
598 if ($dataProp) {
599 $dataSection[] = [
600 'summary' => ['pack' => 'V', 'data' => 0x02],
601 'offset' => ['pack' => 'V'],
602 'type' => ['pack' => 'V', 'data' => 0x1E],
603 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
604 ];
605 ++$dataSection_NumProps;
606 }
607 // GKPIDDSI_VERSION :Version of the application that wrote the property storage
608 $dataSection[] = [
609 'summary' => ['pack' => 'V', 'data' => 0x17],
610 'offset' => ['pack' => 'V'],
611 'type' => ['pack' => 'V', 'data' => 0x03],
612 'data' => ['pack' => 'V', 'data' => 0x000C0000],
613 ];
614 ++$dataSection_NumProps;
615 // GKPIDDSI_SCALE : FALSE
616 $dataSection[] = [
617 'summary' => ['pack' => 'V', 'data' => 0x0B],
618 'offset' => ['pack' => 'V'],
619 'type' => ['pack' => 'V', 'data' => 0x0B],
620 'data' => ['data' => false],
621 ];
622 ++$dataSection_NumProps;
623 // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
624 $dataSection[] = [
625 'summary' => ['pack' => 'V', 'data' => 0x10],
626 'offset' => ['pack' => 'V'],
627 'type' => ['pack' => 'V', 'data' => 0x0B],
628 'data' => ['data' => false],
629 ];
630 ++$dataSection_NumProps;
631 // GKPIDDSI_SHAREDOC : FALSE
632 $dataSection[] = [
633 'summary' => ['pack' => 'V', 'data' => 0x13],
634 'offset' => ['pack' => 'V'],
635 'type' => ['pack' => 'V', 'data' => 0x0B],
636 'data' => ['data' => false],
637 ];
638 ++$dataSection_NumProps;
639 // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application
640 $dataSection[] = [
641 'summary' => ['pack' => 'V', 'data' => 0x16],
642 'offset' => ['pack' => 'V'],
643 'type' => ['pack' => 'V', 'data' => 0x0B],
644 'data' => ['data' => false],
645 ];
646 ++$dataSection_NumProps;
647
648 // GKPIDDSI_DOCSPARTS
649 // MS-OSHARED p75 (2.3.3.2.2.1)
650 // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)
651 // cElements
652 $dataProp = pack('v', 0x0001);
653 $dataProp .= pack('v', 0x0000);
654 // array of UnalignedLpstr
655 // cch
656 $dataProp .= pack('v', 0x000A);
657 $dataProp .= pack('v', 0x0000);
658 // value
659 $dataProp .= 'Worksheet' . chr(0);
660
661 $dataSection[] = [
662 'summary' => ['pack' => 'V', 'data' => 0x0D],
663 'offset' => ['pack' => 'V'],
664 'type' => ['pack' => 'V', 'data' => 0x101E],
665 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
666 ];
667 ++$dataSection_NumProps;
668
669 // GKPIDDSI_HEADINGPAIR
670 // VtVecHeadingPairValue
671 // cElements
672 $dataProp = pack('v', 0x0002);
673 $dataProp .= pack('v', 0x0000);
674 // Array of vtHeadingPair
675 // vtUnalignedString - headingString
676 // stringType
677 $dataProp .= pack('v', 0x001E);
678 // padding
679 $dataProp .= pack('v', 0x0000);
680 // UnalignedLpstr
681 // cch
682 $dataProp .= pack('v', 0x0013);
683 $dataProp .= pack('v', 0x0000);
684 // value
685 $dataProp .= 'Feuilles de calcul';
686 // vtUnalignedString - headingParts
687 // wType : 0x0003 = 32 bit signed integer
688 $dataProp .= pack('v', 0x0300);
689 // padding
690 $dataProp .= pack('v', 0x0000);
691 // value
692 $dataProp .= pack('v', 0x0100);
693 $dataProp .= pack('v', 0x0000);
694 $dataProp .= pack('v', 0x0000);
695 $dataProp .= pack('v', 0x0000);
696
697 $dataSection[] = [
698 'summary' => ['pack' => 'V', 'data' => 0x0C],
699 'offset' => ['pack' => 'V'],
700 'type' => ['pack' => 'V', 'data' => 0x100C],
701 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
702 ];
703 ++$dataSection_NumProps;
704
705 // 4 Section Length
706 // 4 Property count
707 // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
708 $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
709 foreach ($dataSection as $dataProp) {
710 // Summary
711 $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
712 // Offset
713 $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
714 // DataType
715 $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
716 // Data
717 if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
718 $dataSection_Content .= pack('V', $dataProp['data']['data']);
719
720 $dataSection_Content_Offset += 4 + 4;
721 } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
722 $dataSection_Content .= pack('V', $dataProp['data']['data']);
723
724 $dataSection_Content_Offset += 4 + 4;
725 } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean
726 $dataSection_Content .= pack('V', (int) $dataProp['data']['data']);
727 $dataSection_Content_Offset += 4 + 4;
728 } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
729 // Null-terminated string
730 $dataProp['data']['data'] .= chr(0);
731 // @phpstan-ignore-next-line
732 ++$dataProp['data']['length'];
733 // Complete the string with null string for being a %4
734 $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4));
735 $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
736
737 $dataSection_Content .= pack('V', $dataProp['data']['length']);
738 $dataSection_Content .= $dataProp['data']['data'];
739
740 $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
741 // Condition below can never be true
742 //} elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
743 // $dataSection_Content .= $dataProp['data']['data'];
744
745 // $dataSection_Content_Offset += 4 + 8;
746 } else {
747 $dataSection_Content .= $dataProp['data']['data'];
748
749 // @phpstan-ignore-next-line
750 $dataSection_Content_Offset += 4 + $dataProp['data']['length'];
751 }
752 }
753 // Now $dataSection_Content_Offset contains the size of the content
754
755 // section header
756 // offset: $secOffset; size: 4; section length
757 // + x Size of the content (summary + content)
758 $data .= pack('V', $dataSection_Content_Offset);
759 // offset: $secOffset+4; size: 4; property count
760 $data .= pack('V', $dataSection_NumProps);
761 // Section Summary
762 $data .= $dataSection_Summary;
763 // Section Content
764 $data .= $dataSection_Content;
765
766 return $data;
767 }
$data
Definition: bench.php:6

References $data.

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\save().

+ Here is the caller graph for this function:

◆ writeSummaryInformation()

PhpOffice\PhpSpreadsheet\Writer\Xls::writeSummaryInformation ( )
private

Build the OLE Part for Summary Information.

Returns
string

Definition at line 803 of file Xls.php.

804 {
805 // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
806 $data = pack('v', 0xFFFE);
807 // offset: 2; size: 2;
808 $data .= pack('v', 0x0000);
809 // offset: 4; size: 2; OS version
810 $data .= pack('v', 0x0106);
811 // offset: 6; size: 2; OS indicator
812 $data .= pack('v', 0x0002);
813 // offset: 8; size: 16
814 $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
815 // offset: 24; size: 4; section count
816 $data .= pack('V', 0x0001);
817
818 // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9
819 $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3);
820 // offset: 44; size: 4; offset of the start
821 $data .= pack('V', 0x30);
822
823 // SECTION
824 $dataSection = [];
825 $dataSection_NumProps = 0;
826 $dataSection_Summary = '';
827 $dataSection_Content = '';
828
829 // CodePage : CP-1252
830 $dataSection[] = [
831 'summary' => ['pack' => 'V', 'data' => 0x01],
832 'offset' => ['pack' => 'V'],
833 'type' => ['pack' => 'V', 'data' => 0x02], // 2 byte signed integer
834 'data' => ['data' => 1252],
835 ];
836 ++$dataSection_NumProps;
837
838 $props = $this->spreadsheet->getProperties();
839 $this->writeSummaryProp($props->getTitle(), $dataSection_NumProps, $dataSection, 0x02, 0x1e);
840 $this->writeSummaryProp($props->getSubject(), $dataSection_NumProps, $dataSection, 0x03, 0x1e);
841 $this->writeSummaryProp($props->getCreator(), $dataSection_NumProps, $dataSection, 0x04, 0x1e);
842 $this->writeSummaryProp($props->getKeywords(), $dataSection_NumProps, $dataSection, 0x05, 0x1e);
843 $this->writeSummaryProp($props->getDescription(), $dataSection_NumProps, $dataSection, 0x06, 0x1e);
844 $this->writeSummaryProp($props->getLastModifiedBy(), $dataSection_NumProps, $dataSection, 0x08, 0x1e);
845 $this->writeSummaryPropOle($props->getCreated(), $dataSection_NumProps, $dataSection, 0x0c, 0x40);
846 $this->writeSummaryPropOle($props->getModified(), $dataSection_NumProps, $dataSection, 0x0d, 0x40);
847
848 // Security
849 $dataSection[] = [
850 'summary' => ['pack' => 'V', 'data' => 0x13],
851 'offset' => ['pack' => 'V'],
852 'type' => ['pack' => 'V', 'data' => 0x03], // 4 byte signed integer
853 'data' => ['data' => 0x00],
854 ];
855 ++$dataSection_NumProps;
856
857 // 4 Section Length
858 // 4 Property count
859 // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
860 $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
861 foreach ($dataSection as $dataProp) {
862 // Summary
863 $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
864 // Offset
865 $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
866 // DataType
867 $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
868 // Data
869 if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
870 $dataSection_Content .= pack('V', $dataProp['data']['data']);
871
872 $dataSection_Content_Offset += 4 + 4;
873 } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
874 $dataSection_Content .= pack('V', $dataProp['data']['data']);
875
876 $dataSection_Content_Offset += 4 + 4;
877 } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
878 // Null-terminated string
879 $dataProp['data']['data'] .= chr(0);
880 ++$dataProp['data']['length'];
881 // Complete the string with null string for being a %4
882 $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4));
883 $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
884
885 $dataSection_Content .= pack('V', $dataProp['data']['length']);
886 $dataSection_Content .= $dataProp['data']['data'];
887
888 $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
889 } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
890 $dataSection_Content .= $dataProp['data']['data'];
891
892 $dataSection_Content_Offset += 4 + 8;
893 }
894 // Data Type Not Used at the moment
895 }
896 // Now $dataSection_Content_Offset contains the size of the content
897
898 // section header
899 // offset: $secOffset; size: 4; section length
900 // + x Size of the content (summary + content)
901 $data .= pack('V', $dataSection_Content_Offset);
902 // offset: $secOffset+4; size: 4; property count
903 $data .= pack('V', $dataSection_NumProps);
904 // Section Summary
905 $data .= $dataSection_Summary;
906 // Section Content
907 $data .= $dataSection_Content;
908
909 return $data;
910 }
writeSummaryPropOle($dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata)
Definition: Xls.php:772
writeSummaryProp(string $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata)
Definition: Xls.php:785

References $data, PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryProp(), and PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryPropOle().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\save().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ writeSummaryProp()

PhpOffice\PhpSpreadsheet\Writer\Xls::writeSummaryProp ( string  $dataProp,
int &  $dataSection_NumProps,
array &  $dataSection,
int  $sumdata,
int  $typdata 
)
private

Definition at line 785 of file Xls.php.

785 : void
786 {
787 if ($dataProp) {
788 $dataSection[] = [
789 'summary' => ['pack' => 'V', 'data' => $sumdata],
790 'offset' => ['pack' => 'V'],
791 'type' => ['pack' => 'V', 'data' => $typdata], // null-terminated string prepended by dword string length
792 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
793 ];
794 ++$dataSection_NumProps;
795 }
796 }

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryInformation().

+ Here is the caller graph for this function:

◆ writeSummaryPropOle()

PhpOffice\PhpSpreadsheet\Writer\Xls::writeSummaryPropOle (   $dataProp,
int &  $dataSection_NumProps,
array &  $dataSection,
int  $sumdata,
int  $typdata 
)
private
Parameters
float | int$dataProp

Definition at line 772 of file Xls.php.

772 : void
773 {
774 if ($dataProp) {
775 $dataSection[] = [
776 'summary' => ['pack' => 'V', 'data' => $sumdata],
777 'offset' => ['pack' => 'V'],
778 'type' => ['pack' => 'V', 'data' => $typdata], // null-terminated string prepended by dword string length
779 'data' => ['data' => OLE::localDateToOLE($dataProp)],
780 ];
781 ++$dataSection_NumProps;
782 }
783 }
static localDateToOLE($date)
Utility function Returns a string for the OLE container with the date given.
Definition: OLE.php:498

References PhpOffice\PhpSpreadsheet\Shared\OLE\localDateToOLE().

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\writeSummaryInformation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $colors

PhpOffice\PhpSpreadsheet\Writer\Xls::$colors
private

Definition at line 65 of file Xls.php.

◆ $documentSummaryInformation

PhpOffice\PhpSpreadsheet\Writer\Xls::$documentSummaryInformation
private

Definition at line 93 of file Xls.php.

◆ $IDCLs

PhpOffice\PhpSpreadsheet\Writer\Xls::$IDCLs
private

Definition at line 79 of file Xls.php.

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\Escher\close().

◆ $parser

PhpOffice\PhpSpreadsheet\Writer\Xls::$parser
private

Definition at line 72 of file Xls.php.

◆ $spreadsheet

PhpOffice\PhpSpreadsheet\Writer\Xls::$spreadsheet
private

Definition at line 37 of file Xls.php.

Referenced by PhpOffice\PhpSpreadsheet\Writer\Xls\__construct().

◆ $strTable

PhpOffice\PhpSpreadsheet\Writer\Xls::$strTable = []
private

Definition at line 58 of file Xls.php.

◆ $strTotal

PhpOffice\PhpSpreadsheet\Writer\Xls::$strTotal = 0
private

Definition at line 44 of file Xls.php.

◆ $strUnique

PhpOffice\PhpSpreadsheet\Writer\Xls::$strUnique = 0
private

Definition at line 51 of file Xls.php.

◆ $summaryInformation

PhpOffice\PhpSpreadsheet\Writer\Xls::$summaryInformation
private

Definition at line 86 of file Xls.php.

◆ $writerWorkbook

PhpOffice\PhpSpreadsheet\Writer\Xls::$writerWorkbook
private

Definition at line 98 of file Xls.php.

◆ $writerWorksheets

PhpOffice\PhpSpreadsheet\Writer\Xls::$writerWorksheets
private

Definition at line 103 of file Xls.php.


The documentation for this class was generated from the following file: