, ...].
- *
- * @param array $pValue
- */
- public function setIDCLs($pValue): void
- {
- $this->IDCLs = $pValue;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer.php b/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer.php
deleted file mode 100644
index b07786f..0000000
--- a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer.php
+++ /dev/null
@@ -1,34 +0,0 @@
-BSECollection[] = $BSE;
- $BSE->setParent($this);
- }
-
- /**
- * Get the collection of BLIP Store Entries.
- *
- * @return BstoreContainer\BSE[]
- */
- public function getBSECollection()
- {
- return $this->BSECollection;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE.php
deleted file mode 100644
index e885146..0000000
--- a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE.php
+++ /dev/null
@@ -1,89 +0,0 @@
-parent = $parent;
- }
-
- /**
- * Get the BLIP.
- *
- * @return BSE\Blip
- */
- public function getBlip()
- {
- return $this->blip;
- }
-
- /**
- * Set the BLIP.
- *
- * @param BSE\Blip $blip
- */
- public function setBlip($blip): void
- {
- $this->blip = $blip;
- $blip->setParent($this);
- }
-
- /**
- * Get the BLIP type.
- *
- * @return int
- */
- public function getBlipType()
- {
- return $this->blipType;
- }
-
- /**
- * Set the BLIP type.
- *
- * @param int $blipType
- */
- public function setBlipType($blipType): void
- {
- $this->blipType = $blipType;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php
deleted file mode 100644
index 500d7ea..0000000
--- a/vendor/PhpSpreadsheet/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php
+++ /dev/null
@@ -1,60 +0,0 @@
-data;
- }
-
- /**
- * Set the raw image data.
- *
- * @param string $data
- */
- public function setData($data): void
- {
- $this->data = $data;
- }
-
- /**
- * Set parent BSE.
- *
- * @param \PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE $parent
- */
- public function setParent($parent): void
- {
- $this->parent = $parent;
- }
-
- /**
- * Get parent BSE.
- *
- * @return \PhpOffice\PhpSpreadsheet\Shared\Escher\DggContainer\BstoreContainer\BSE $parent
- */
- public function getParent()
- {
- return $this->parent;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/File.php b/vendor/PhpSpreadsheet/Shared/File.php
deleted file mode 100644
index 7525df8..0000000
--- a/vendor/PhpSpreadsheet/Shared/File.php
+++ /dev/null
@@ -1,142 +0,0 @@
-open($zipFile) === true) {
- $returnValue = ($zip->getFromName($archiveFile) !== false);
- $zip->close();
-
- return $returnValue;
- }
-
- return false;
- }
-
- return file_exists($pFilename);
- }
-
- /**
- * Returns canonicalized absolute pathname, also for ZIP archives.
- *
- * @param string $pFilename
- *
- * @return string
- */
- public static function realpath($pFilename)
- {
- // Returnvalue
- $returnValue = '';
-
- // Try using realpath()
- if (file_exists($pFilename)) {
- $returnValue = realpath($pFilename);
- }
-
- // Found something?
- if ($returnValue == '' || ($returnValue === null)) {
- $pathArray = explode('/', $pFilename);
- while (in_array('..', $pathArray) && $pathArray[0] != '..') {
- $iMax = count($pathArray);
- for ($i = 0; $i < $iMax; ++$i) {
- if ($pathArray[$i] == '..' && $i > 0) {
- unset($pathArray[$i], $pathArray[$i - 1]);
-
- break;
- }
- }
- }
- $returnValue = implode('/', $pathArray);
- }
-
- // Return
- return $returnValue;
- }
-
- /**
- * Get the systems temporary directory.
- *
- * @return string
- */
- public static function sysGetTempDir()
- {
- if (self::$useUploadTempDirectory) {
- // use upload-directory when defined to allow running on environments having very restricted
- // open_basedir configs
- if (ini_get('upload_tmp_dir') !== false) {
- if ($temp = ini_get('upload_tmp_dir')) {
- if (file_exists($temp)) {
- return realpath($temp);
- }
- }
- }
- }
-
- return realpath(sys_get_temp_dir());
- }
-
- /**
- * Assert that given path is an existing file and is readable, otherwise throw exception.
- *
- * @param string $filename
- */
- public static function assertFile($filename): void
- {
- if (!is_file($filename)) {
- throw new InvalidArgumentException('File "' . $filename . '" does not exist.');
- }
-
- if (!is_readable($filename)) {
- throw new InvalidArgumentException('Could not open "' . $filename . '" for reading.');
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Font.php b/vendor/PhpSpreadsheet/Shared/Font.php
deleted file mode 100644
index ee1f8ab..0000000
--- a/vendor/PhpSpreadsheet/Shared/Font.php
+++ /dev/null
@@ -1,763 +0,0 @@
- [
- 1 => ['px' => 24, 'width' => 12.00000000],
- 2 => ['px' => 24, 'width' => 12.00000000],
- 3 => ['px' => 32, 'width' => 10.66406250],
- 4 => ['px' => 32, 'width' => 10.66406250],
- 5 => ['px' => 40, 'width' => 10.00000000],
- 6 => ['px' => 48, 'width' => 9.59765625],
- 7 => ['px' => 48, 'width' => 9.59765625],
- 8 => ['px' => 56, 'width' => 9.33203125],
- 9 => ['px' => 64, 'width' => 9.14062500],
- 10 => ['px' => 64, 'width' => 9.14062500],
- ],
- 'Calibri' => [
- 1 => ['px' => 24, 'width' => 12.00000000],
- 2 => ['px' => 24, 'width' => 12.00000000],
- 3 => ['px' => 32, 'width' => 10.66406250],
- 4 => ['px' => 32, 'width' => 10.66406250],
- 5 => ['px' => 40, 'width' => 10.00000000],
- 6 => ['px' => 48, 'width' => 9.59765625],
- 7 => ['px' => 48, 'width' => 9.59765625],
- 8 => ['px' => 56, 'width' => 9.33203125],
- 9 => ['px' => 56, 'width' => 9.33203125],
- 10 => ['px' => 64, 'width' => 9.14062500],
- 11 => ['px' => 64, 'width' => 9.14062500],
- ],
- 'Verdana' => [
- 1 => ['px' => 24, 'width' => 12.00000000],
- 2 => ['px' => 24, 'width' => 12.00000000],
- 3 => ['px' => 32, 'width' => 10.66406250],
- 4 => ['px' => 32, 'width' => 10.66406250],
- 5 => ['px' => 40, 'width' => 10.00000000],
- 6 => ['px' => 48, 'width' => 9.59765625],
- 7 => ['px' => 48, 'width' => 9.59765625],
- 8 => ['px' => 64, 'width' => 9.14062500],
- 9 => ['px' => 72, 'width' => 9.00000000],
- 10 => ['px' => 72, 'width' => 9.00000000],
- ],
- ];
-
- /**
- * Set autoSize method.
- *
- * @param string $pValue see self::AUTOSIZE_METHOD_*
- *
- * @return bool Success or failure
- */
- public static function setAutoSizeMethod($pValue)
- {
- if (!in_array($pValue, self::$autoSizeMethods)) {
- return false;
- }
- self::$autoSizeMethod = $pValue;
-
- return true;
- }
-
- /**
- * Get autoSize method.
- *
- * @return string
- */
- public static function getAutoSizeMethod()
- {
- return self::$autoSizeMethod;
- }
-
- /**
- * Set the path to the folder containing .ttf files. There should be a trailing slash.
- * Typical locations on variout some platforms:
- *
- * - C:/Windows/Fonts/
- * - /usr/share/fonts/truetype/
- * - ~/.fonts/
- *
.
- *
- * @param string $pValue
- */
- public static function setTrueTypeFontPath($pValue): void
- {
- self::$trueTypeFontPath = $pValue;
- }
-
- /**
- * Get the path to the folder containing .ttf files.
- *
- * @return string
- */
- public static function getTrueTypeFontPath()
- {
- return self::$trueTypeFontPath;
- }
-
- /**
- * Calculate an (approximate) OpenXML column width, based on font size and text contained.
- *
- * @param \PhpOffice\PhpSpreadsheet\Style\Font $font Font object
- * @param RichText|string $cellText Text to calculate width
- * @param int $rotation Rotation angle
- * @param null|\PhpOffice\PhpSpreadsheet\Style\Font $defaultFont Font object
- *
- * @return int Column width
- */
- public static function calculateColumnWidth(\PhpOffice\PhpSpreadsheet\Style\Font $font, $cellText = '', $rotation = 0, ?\PhpOffice\PhpSpreadsheet\Style\Font $defaultFont = null)
- {
- // If it is rich text, use plain text
- if ($cellText instanceof RichText) {
- $cellText = $cellText->getPlainText();
- }
-
- // Special case if there are one or more newline characters ("\n")
- if (strpos($cellText, "\n") !== false) {
- $lineTexts = explode("\n", $cellText);
- $lineWidths = [];
- foreach ($lineTexts as $lineText) {
- $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont);
- }
-
- return max($lineWidths); // width of longest line in cell
- }
-
- // Try to get the exact text width in pixels
- $approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX;
- if (!$approximate) {
- $columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07);
-
- try {
- // Width of text in pixels excl. padding
- // and addition because Excel adds some padding, just use approx width of 'n' glyph
- $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + $columnWidthAdjust;
- } catch (PhpSpreadsheetException $e) {
- $approximate = true;
- }
- }
-
- if ($approximate) {
- $columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0);
- // Width of text in pixels excl. padding, approximation
- // and addition because Excel adds some padding, just use approx width of 'n' glyph
- $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust;
- }
-
- // Convert from pixel width to column width
- $columnWidth = Drawing::pixelsToCellDimension($columnWidth, $defaultFont);
-
- // Return
- return round($columnWidth, 6);
- }
-
- /**
- * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle.
- *
- * @param string $text
- * @param \PhpOffice\PhpSpreadsheet\Style\Font
- * @param int $rotation
- *
- * @return int
- */
- public static function getTextWidthPixelsExact($text, \PhpOffice\PhpSpreadsheet\Style\Font $font, $rotation = 0)
- {
- if (!function_exists('imagettfbbox')) {
- throw new PhpSpreadsheetException('GD library needs to be enabled');
- }
-
- // font size should really be supplied in pixels in GD2,
- // but since GD2 seems to assume 72dpi, pixels and points are the same
- $fontFile = self::getTrueTypeFontFileFromFont($font);
- $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text);
-
- // Get corners positions
- $lowerLeftCornerX = $textBox[0];
- $lowerRightCornerX = $textBox[2];
- $upperRightCornerX = $textBox[4];
- $upperLeftCornerX = $textBox[6];
-
- // Consider the rotation when calculating the width
- return max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX);
- }
-
- /**
- * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle.
- *
- * @param string $columnText
- * @param int $rotation
- *
- * @return int Text width in pixels (no padding added)
- */
- public static function getTextWidthPixelsApprox($columnText, \PhpOffice\PhpSpreadsheet\Style\Font $font, $rotation = 0)
- {
- $fontName = $font->getName();
- $fontSize = $font->getSize();
-
- // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size.
- switch ($fontName) {
- case 'Calibri':
- // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.
- $columnWidth = (int) (8.26 * StringHelper::countCharacters($columnText));
- $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
-
- break;
- case 'Arial':
- // value 8 was set because of experience in different exports at Arial 10 font.
- $columnWidth = (int) (8 * StringHelper::countCharacters($columnText));
- $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
-
- break;
- case 'Verdana':
- // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font.
- $columnWidth = (int) (8 * StringHelper::countCharacters($columnText));
- $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
-
- break;
- default:
- // just assume Calibri
- $columnWidth = (int) (8.26 * StringHelper::countCharacters($columnText));
- $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
-
- break;
- }
-
- // Calculate approximate rotated column width
- if ($rotation !== 0) {
- if ($rotation == -165) {
- // stacked text
- $columnWidth = 4; // approximation
- } else {
- // rotated text
- $columnWidth = $columnWidth * cos(deg2rad($rotation))
- + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
- }
- }
-
- // pixel width is an integer
- return (int) $columnWidth;
- }
-
- /**
- * Calculate an (approximate) pixel size, based on a font points size.
- *
- * @param int $fontSizeInPoints Font size (in points)
- *
- * @return int Font size (in pixels)
- */
- public static function fontSizeToPixels($fontSizeInPoints)
- {
- return (int) ((4 / 3) * $fontSizeInPoints);
- }
-
- /**
- * Calculate an (approximate) pixel size, based on inch size.
- *
- * @param int $sizeInInch Font size (in inch)
- *
- * @return int Size (in pixels)
- */
- public static function inchSizeToPixels($sizeInInch)
- {
- return $sizeInInch * 96;
- }
-
- /**
- * Calculate an (approximate) pixel size, based on centimeter size.
- *
- * @param int $sizeInCm Font size (in centimeters)
- *
- * @return float Size (in pixels)
- */
- public static function centimeterSizeToPixels($sizeInCm)
- {
- return $sizeInCm * 37.795275591;
- }
-
- /**
- * Returns the font path given the font.
- *
- * @param \PhpOffice\PhpSpreadsheet\Style\Font $font
- *
- * @return string Path to TrueType font file
- */
- public static function getTrueTypeFontFileFromFont($font)
- {
- if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) {
- throw new PhpSpreadsheetException('Valid directory to TrueType Font files not specified');
- }
-
- $name = $font->getName();
- $bold = $font->getBold();
- $italic = $font->getItalic();
-
- // Check if we can map font to true type font file
- switch ($name) {
- case 'Arial':
- $fontFile = (
- $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)
- : ($italic ? self::ARIAL_ITALIC : self::ARIAL)
- );
-
- break;
- case 'Calibri':
- $fontFile = (
- $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)
- : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)
- );
-
- break;
- case 'Courier New':
- $fontFile = (
- $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)
- : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)
- );
-
- break;
- case 'Comic Sans MS':
- $fontFile = (
- $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS
- );
-
- break;
- case 'Georgia':
- $fontFile = (
- $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)
- : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)
- );
-
- break;
- case 'Impact':
- $fontFile = self::IMPACT;
-
- break;
- case 'Liberation Sans':
- $fontFile = (
- $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)
- : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)
- );
-
- break;
- case 'Lucida Console':
- $fontFile = self::LUCIDA_CONSOLE;
-
- break;
- case 'Lucida Sans Unicode':
- $fontFile = self::LUCIDA_SANS_UNICODE;
-
- break;
- case 'Microsoft Sans Serif':
- $fontFile = self::MICROSOFT_SANS_SERIF;
-
- break;
- case 'Palatino Linotype':
- $fontFile = (
- $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)
- : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)
- );
-
- break;
- case 'Symbol':
- $fontFile = self::SYMBOL;
-
- break;
- case 'Tahoma':
- $fontFile = (
- $bold ? self::TAHOMA_BOLD : self::TAHOMA
- );
-
- break;
- case 'Times New Roman':
- $fontFile = (
- $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)
- : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)
- );
-
- break;
- case 'Trebuchet MS':
- $fontFile = (
- $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)
- : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)
- );
-
- break;
- case 'Verdana':
- $fontFile = (
- $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)
- : ($italic ? self::VERDANA_ITALIC : self::VERDANA)
- );
-
- break;
- default:
- throw new PhpSpreadsheetException('Unknown font name "' . $name . '". Cannot map to TrueType font file');
-
- break;
- }
-
- $fontFile = self::$trueTypeFontPath . $fontFile;
-
- // Check if file actually exists
- if (!file_exists($fontFile)) {
- throw new PhpSpreadsheetException('TrueType Font file not found');
- }
-
- return $fontFile;
- }
-
- /**
- * Returns the associated charset for the font name.
- *
- * @param string $name Font name
- *
- * @return int Character set code
- */
- public static function getCharsetFromFontName($name)
- {
- switch ($name) {
- // Add more cases. Check FONT records in real Excel files.
- case 'EucrosiaUPC':
- return self::CHARSET_ANSI_THAI;
- case 'Wingdings':
- return self::CHARSET_SYMBOL;
- case 'Wingdings 2':
- return self::CHARSET_SYMBOL;
- case 'Wingdings 3':
- return self::CHARSET_SYMBOL;
- default:
- return self::CHARSET_ANSI_LATIN;
- }
- }
-
- /**
- * Get the effective column width for columns without a column dimension or column with width -1
- * For example, for Calibri 11 this is 9.140625 (64 px).
- *
- * @param \PhpOffice\PhpSpreadsheet\Style\Font $font The workbooks default font
- * @param bool $pPixels true = return column width in pixels, false = return in OOXML units
- *
- * @return mixed Column width
- */
- public static function getDefaultColumnWidthByFont(\PhpOffice\PhpSpreadsheet\Style\Font $font, $pPixels = false)
- {
- if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) {
- // Exact width can be determined
- $columnWidth = $pPixels ?
- self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px']
- : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];
- } else {
- // We don't have data for this particular font and size, use approximation by
- // extrapolating from Calibri 11
- $columnWidth = $pPixels ?
- self::$defaultColumnWidths['Calibri'][11]['px']
- : self::$defaultColumnWidths['Calibri'][11]['width'];
- $columnWidth = $columnWidth * $font->getSize() / 11;
-
- // Round pixels to closest integer
- if ($pPixels) {
- $columnWidth = (int) round($columnWidth);
- }
- }
-
- return $columnWidth;
- }
-
- /**
- * Get the effective row height for rows without a row dimension or rows with height -1
- * For example, for Calibri 11 this is 15 points.
- *
- * @param \PhpOffice\PhpSpreadsheet\Style\Font $font The workbooks default font
- *
- * @return float Row height in points
- */
- public static function getDefaultRowHeightByFont(\PhpOffice\PhpSpreadsheet\Style\Font $font)
- {
- switch ($font->getName()) {
- case 'Arial':
- switch ($font->getSize()) {
- case 10:
- // inspection of Arial 10 workbook says 12.75pt ~17px
- $rowHeight = 12.75;
-
- break;
- case 9:
- // inspection of Arial 9 workbook says 12.00pt ~16px
- $rowHeight = 12;
-
- break;
- case 8:
- // inspection of Arial 8 workbook says 11.25pt ~15px
- $rowHeight = 11.25;
-
- break;
- case 7:
- // inspection of Arial 7 workbook says 9.00pt ~12px
- $rowHeight = 9;
-
- break;
- case 6:
- case 5:
- // inspection of Arial 5,6 workbook says 8.25pt ~11px
- $rowHeight = 8.25;
-
- break;
- case 4:
- // inspection of Arial 4 workbook says 6.75pt ~9px
- $rowHeight = 6.75;
-
- break;
- case 3:
- // inspection of Arial 3 workbook says 6.00pt ~8px
- $rowHeight = 6;
-
- break;
- case 2:
- case 1:
- // inspection of Arial 1,2 workbook says 5.25pt ~7px
- $rowHeight = 5.25;
-
- break;
- default:
- // use Arial 10 workbook as an approximation, extrapolation
- $rowHeight = 12.75 * $font->getSize() / 10;
-
- break;
- }
-
- break;
- case 'Calibri':
- switch ($font->getSize()) {
- case 11:
- // inspection of Calibri 11 workbook says 15.00pt ~20px
- $rowHeight = 15;
-
- break;
- case 10:
- // inspection of Calibri 10 workbook says 12.75pt ~17px
- $rowHeight = 12.75;
-
- break;
- case 9:
- // inspection of Calibri 9 workbook says 12.00pt ~16px
- $rowHeight = 12;
-
- break;
- case 8:
- // inspection of Calibri 8 workbook says 11.25pt ~15px
- $rowHeight = 11.25;
-
- break;
- case 7:
- // inspection of Calibri 7 workbook says 9.00pt ~12px
- $rowHeight = 9;
-
- break;
- case 6:
- case 5:
- // inspection of Calibri 5,6 workbook says 8.25pt ~11px
- $rowHeight = 8.25;
-
- break;
- case 4:
- // inspection of Calibri 4 workbook says 6.75pt ~9px
- $rowHeight = 6.75;
-
- break;
- case 3:
- // inspection of Calibri 3 workbook says 6.00pt ~8px
- $rowHeight = 6.00;
-
- break;
- case 2:
- case 1:
- // inspection of Calibri 1,2 workbook says 5.25pt ~7px
- $rowHeight = 5.25;
-
- break;
- default:
- // use Calibri 11 workbook as an approximation, extrapolation
- $rowHeight = 15 * $font->getSize() / 11;
-
- break;
- }
-
- break;
- case 'Verdana':
- switch ($font->getSize()) {
- case 10:
- // inspection of Verdana 10 workbook says 12.75pt ~17px
- $rowHeight = 12.75;
-
- break;
- case 9:
- // inspection of Verdana 9 workbook says 11.25pt ~15px
- $rowHeight = 11.25;
-
- break;
- case 8:
- // inspection of Verdana 8 workbook says 10.50pt ~14px
- $rowHeight = 10.50;
-
- break;
- case 7:
- // inspection of Verdana 7 workbook says 9.00pt ~12px
- $rowHeight = 9.00;
-
- break;
- case 6:
- case 5:
- // inspection of Verdana 5,6 workbook says 8.25pt ~11px
- $rowHeight = 8.25;
-
- break;
- case 4:
- // inspection of Verdana 4 workbook says 6.75pt ~9px
- $rowHeight = 6.75;
-
- break;
- case 3:
- // inspection of Verdana 3 workbook says 6.00pt ~8px
- $rowHeight = 6;
-
- break;
- case 2:
- case 1:
- // inspection of Verdana 1,2 workbook says 5.25pt ~7px
- $rowHeight = 5.25;
-
- break;
- default:
- // use Verdana 10 workbook as an approximation, extrapolation
- $rowHeight = 12.75 * $font->getSize() / 10;
-
- break;
- }
-
- break;
- default:
- // just use Calibri as an approximation
- $rowHeight = 15 * $font->getSize() / 11;
-
- break;
- }
-
- return $rowHeight;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/CHANGELOG.TXT b/vendor/PhpSpreadsheet/Shared/JAMA/CHANGELOG.TXT
deleted file mode 100644
index 1c18a5d..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/CHANGELOG.TXT
+++ /dev/null
@@ -1,16 +0,0 @@
-Mar 1, 2005 11:15 AST by PM
-
-+ For consistency, renamed Math.php to Maths.java, utils to util,
- tests to test, docs to doc -
-
-+ Removed conditional logic from top of Matrix class.
-
-+ Switched to using hypo function in Maths.php for all php-hypot calls.
- NOTE TO SELF: Need to make sure that all decompositions have been
- switched over to using the bundled hypo.
-
-Feb 25, 2005 at 10:00 AST by PM
-
-+ Recommend using simpler Error.php instead of JAMA_Error.php but
- can be persuaded otherwise.
-
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php b/vendor/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php
deleted file mode 100644
index 2b241d5..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php
+++ /dev/null
@@ -1,147 +0,0 @@
-L = $A->getArray();
- $this->m = $A->getRowDimension();
-
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = $i; $j < $this->m; ++$j) {
- for ($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) {
- $sum -= $this->L[$i][$k] * $this->L[$j][$k];
- }
- if ($i == $j) {
- if ($sum >= 0) {
- $this->L[$i][$i] = sqrt($sum);
- } else {
- $this->isspd = false;
- }
- } else {
- if ($this->L[$i][$i] != 0) {
- $this->L[$j][$i] = $sum / $this->L[$i][$i];
- }
- }
- }
-
- for ($k = $i + 1; $k < $this->m; ++$k) {
- $this->L[$i][$k] = 0.0;
- }
- }
- }
-
- /**
- * Is the matrix symmetric and positive definite?
- *
- * @return bool
- */
- public function isSPD()
- {
- return $this->isspd;
- }
-
- /**
- * getL.
- *
- * Return triangular factor.
- *
- * @return Matrix Lower triangular matrix
- */
- public function getL()
- {
- return new Matrix($this->L);
- }
-
- /**
- * Solve A*X = B.
- *
- * @param $B Row-equal matrix
- *
- * @return Matrix L * L' * X = B
- */
- public function solve(Matrix $B)
- {
- if ($B->getRowDimension() == $this->m) {
- if ($this->isspd) {
- $X = $B->getArrayCopy();
- $nx = $B->getColumnDimension();
-
- for ($k = 0; $k < $this->m; ++$k) {
- for ($i = $k + 1; $i < $this->m; ++$i) {
- for ($j = 0; $j < $nx; ++$j) {
- $X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k];
- }
- }
- for ($j = 0; $j < $nx; ++$j) {
- $X[$k][$j] /= $this->L[$k][$k];
- }
- }
-
- for ($k = $this->m - 1; $k >= 0; --$k) {
- for ($j = 0; $j < $nx; ++$j) {
- $X[$k][$j] /= $this->L[$k][$k];
- }
- for ($i = 0; $i < $k; ++$i) {
- for ($j = 0; $j < $nx; ++$j) {
- $X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i];
- }
- }
- }
-
- return new Matrix($X, $this->m, $nx);
- }
-
- throw new CalculationException(Matrix::MATRIX_SPD_EXCEPTION);
- }
-
- throw new CalculationException(Matrix::MATRIX_DIMENSION_EXCEPTION);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php b/vendor/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
deleted file mode 100644
index 4c67c3a..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
+++ /dev/null
@@ -1,863 +0,0 @@
-d = $this->V[$this->n - 1];
- // Householder reduction to tridiagonal form.
- for ($i = $this->n - 1; $i > 0; --$i) {
- $i_ = $i - 1;
- // Scale to avoid under/overflow.
- $h = $scale = 0.0;
- $scale += array_sum(array_map('abs', $this->d));
- if ($scale == 0.0) {
- $this->e[$i] = $this->d[$i_];
- $this->d = array_slice($this->V[$i_], 0, $i_);
- for ($j = 0; $j < $i; ++$j) {
- $this->V[$j][$i] = $this->V[$i][$j] = 0.0;
- }
- } else {
- // Generate Householder vector.
- for ($k = 0; $k < $i; ++$k) {
- $this->d[$k] /= $scale;
- $h += $this->d[$k] ** 2;
- }
- $f = $this->d[$i_];
- $g = sqrt($h);
- if ($f > 0) {
- $g = -$g;
- }
- $this->e[$i] = $scale * $g;
- $h = $h - $f * $g;
- $this->d[$i_] = $f - $g;
- for ($j = 0; $j < $i; ++$j) {
- $this->e[$j] = 0.0;
- }
- // Apply similarity transformation to remaining columns.
- for ($j = 0; $j < $i; ++$j) {
- $f = $this->d[$j];
- $this->V[$j][$i] = $f;
- $g = $this->e[$j] + $this->V[$j][$j] * $f;
- for ($k = $j + 1; $k <= $i_; ++$k) {
- $g += $this->V[$k][$j] * $this->d[$k];
- $this->e[$k] += $this->V[$k][$j] * $f;
- }
- $this->e[$j] = $g;
- }
- $f = 0.0;
- for ($j = 0; $j < $i; ++$j) {
- $this->e[$j] /= $h;
- $f += $this->e[$j] * $this->d[$j];
- }
- $hh = $f / (2 * $h);
- for ($j = 0; $j < $i; ++$j) {
- $this->e[$j] -= $hh * $this->d[$j];
- }
- for ($j = 0; $j < $i; ++$j) {
- $f = $this->d[$j];
- $g = $this->e[$j];
- for ($k = $j; $k <= $i_; ++$k) {
- $this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]);
- }
- $this->d[$j] = $this->V[$i - 1][$j];
- $this->V[$i][$j] = 0.0;
- }
- }
- $this->d[$i] = $h;
- }
-
- // Accumulate transformations.
- for ($i = 0; $i < $this->n - 1; ++$i) {
- $this->V[$this->n - 1][$i] = $this->V[$i][$i];
- $this->V[$i][$i] = 1.0;
- $h = $this->d[$i + 1];
- if ($h != 0.0) {
- for ($k = 0; $k <= $i; ++$k) {
- $this->d[$k] = $this->V[$k][$i + 1] / $h;
- }
- for ($j = 0; $j <= $i; ++$j) {
- $g = 0.0;
- for ($k = 0; $k <= $i; ++$k) {
- $g += $this->V[$k][$i + 1] * $this->V[$k][$j];
- }
- for ($k = 0; $k <= $i; ++$k) {
- $this->V[$k][$j] -= $g * $this->d[$k];
- }
- }
- }
- for ($k = 0; $k <= $i; ++$k) {
- $this->V[$k][$i + 1] = 0.0;
- }
- }
-
- $this->d = $this->V[$this->n - 1];
- $this->V[$this->n - 1] = array_fill(0, $j, 0.0);
- $this->V[$this->n - 1][$this->n - 1] = 1.0;
- $this->e[0] = 0.0;
- }
-
- /**
- * Symmetric tridiagonal QL algorithm.
- *
- * This is derived from the Algol procedures tql2, by
- * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
- * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
- * Fortran subroutine in EISPACK.
- */
- private function tql2(): void
- {
- for ($i = 1; $i < $this->n; ++$i) {
- $this->e[$i - 1] = $this->e[$i];
- }
- $this->e[$this->n - 1] = 0.0;
- $f = 0.0;
- $tst1 = 0.0;
- $eps = 2.0 ** (-52.0);
-
- for ($l = 0; $l < $this->n; ++$l) {
- // Find small subdiagonal element
- $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l]));
- $m = $l;
- while ($m < $this->n) {
- if (abs($this->e[$m]) <= $eps * $tst1) {
- break;
- }
- ++$m;
- }
- // If m == l, $this->d[l] is an eigenvalue,
- // otherwise, iterate.
- if ($m > $l) {
- $iter = 0;
- do {
- // Could check iteration count here.
- ++$iter;
- // Compute implicit shift
- $g = $this->d[$l];
- $p = ($this->d[$l + 1] - $g) / (2.0 * $this->e[$l]);
- $r = hypo($p, 1.0);
- if ($p < 0) {
- $r *= -1;
- }
- $this->d[$l] = $this->e[$l] / ($p + $r);
- $this->d[$l + 1] = $this->e[$l] * ($p + $r);
- $dl1 = $this->d[$l + 1];
- $h = $g - $this->d[$l];
- for ($i = $l + 2; $i < $this->n; ++$i) {
- $this->d[$i] -= $h;
- }
- $f += $h;
- // Implicit QL transformation.
- $p = $this->d[$m];
- $c = 1.0;
- $c2 = $c3 = $c;
- $el1 = $this->e[$l + 1];
- $s = $s2 = 0.0;
- for ($i = $m - 1; $i >= $l; --$i) {
- $c3 = $c2;
- $c2 = $c;
- $s2 = $s;
- $g = $c * $this->e[$i];
- $h = $c * $p;
- $r = hypo($p, $this->e[$i]);
- $this->e[$i + 1] = $s * $r;
- $s = $this->e[$i] / $r;
- $c = $p / $r;
- $p = $c * $this->d[$i] - $s * $g;
- $this->d[$i + 1] = $h + $s * ($c * $g + $s * $this->d[$i]);
- // Accumulate transformation.
- for ($k = 0; $k < $this->n; ++$k) {
- $h = $this->V[$k][$i + 1];
- $this->V[$k][$i + 1] = $s * $this->V[$k][$i] + $c * $h;
- $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h;
- }
- }
- $p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1;
- $this->e[$l] = $s * $p;
- $this->d[$l] = $c * $p;
- // Check for convergence.
- } while (abs($this->e[$l]) > $eps * $tst1);
- }
- $this->d[$l] = $this->d[$l] + $f;
- $this->e[$l] = 0.0;
- }
-
- // Sort eigenvalues and corresponding vectors.
- for ($i = 0; $i < $this->n - 1; ++$i) {
- $k = $i;
- $p = $this->d[$i];
- for ($j = $i + 1; $j < $this->n; ++$j) {
- if ($this->d[$j] < $p) {
- $k = $j;
- $p = $this->d[$j];
- }
- }
- if ($k != $i) {
- $this->d[$k] = $this->d[$i];
- $this->d[$i] = $p;
- for ($j = 0; $j < $this->n; ++$j) {
- $p = $this->V[$j][$i];
- $this->V[$j][$i] = $this->V[$j][$k];
- $this->V[$j][$k] = $p;
- }
- }
- }
- }
-
- /**
- * Nonsymmetric reduction to Hessenberg form.
- *
- * This is derived from the Algol procedures orthes and ortran,
- * by Martin and Wilkinson, Handbook for Auto. Comp.,
- * Vol.ii-Linear Algebra, and the corresponding
- * Fortran subroutines in EISPACK.
- */
- private function orthes(): void
- {
- $low = 0;
- $high = $this->n - 1;
-
- for ($m = $low + 1; $m <= $high - 1; ++$m) {
- // Scale column.
- $scale = 0.0;
- for ($i = $m; $i <= $high; ++$i) {
- $scale = $scale + abs($this->H[$i][$m - 1]);
- }
- if ($scale != 0.0) {
- // Compute Householder transformation.
- $h = 0.0;
- for ($i = $high; $i >= $m; --$i) {
- $this->ort[$i] = $this->H[$i][$m - 1] / $scale;
- $h += $this->ort[$i] * $this->ort[$i];
- }
- $g = sqrt($h);
- if ($this->ort[$m] > 0) {
- $g *= -1;
- }
- $h -= $this->ort[$m] * $g;
- $this->ort[$m] -= $g;
- // Apply Householder similarity transformation
- // H = (I -u * u' / h) * H * (I -u * u') / h)
- for ($j = $m; $j < $this->n; ++$j) {
- $f = 0.0;
- for ($i = $high; $i >= $m; --$i) {
- $f += $this->ort[$i] * $this->H[$i][$j];
- }
- $f /= $h;
- for ($i = $m; $i <= $high; ++$i) {
- $this->H[$i][$j] -= $f * $this->ort[$i];
- }
- }
- for ($i = 0; $i <= $high; ++$i) {
- $f = 0.0;
- for ($j = $high; $j >= $m; --$j) {
- $f += $this->ort[$j] * $this->H[$i][$j];
- }
- $f = $f / $h;
- for ($j = $m; $j <= $high; ++$j) {
- $this->H[$i][$j] -= $f * $this->ort[$j];
- }
- }
- $this->ort[$m] = $scale * $this->ort[$m];
- $this->H[$m][$m - 1] = $scale * $g;
- }
- }
-
- // Accumulate transformations (Algol's ortran).
- for ($i = 0; $i < $this->n; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $this->V[$i][$j] = ($i == $j ? 1.0 : 0.0);
- }
- }
- for ($m = $high - 1; $m >= $low + 1; --$m) {
- if ($this->H[$m][$m - 1] != 0.0) {
- for ($i = $m + 1; $i <= $high; ++$i) {
- $this->ort[$i] = $this->H[$i][$m - 1];
- }
- for ($j = $m; $j <= $high; ++$j) {
- $g = 0.0;
- for ($i = $m; $i <= $high; ++$i) {
- $g += $this->ort[$i] * $this->V[$i][$j];
- }
- // Double division avoids possible underflow
- $g = ($g / $this->ort[$m]) / $this->H[$m][$m - 1];
- for ($i = $m; $i <= $high; ++$i) {
- $this->V[$i][$j] += $g * $this->ort[$i];
- }
- }
- }
- }
- }
-
- /**
- * Performs complex division.
- *
- * @param mixed $xr
- * @param mixed $xi
- * @param mixed $yr
- * @param mixed $yi
- */
- private function cdiv($xr, $xi, $yr, $yi): void
- {
- if (abs($yr) > abs($yi)) {
- $r = $yi / $yr;
- $d = $yr + $r * $yi;
- $this->cdivr = ($xr + $r * $xi) / $d;
- $this->cdivi = ($xi - $r * $xr) / $d;
- } else {
- $r = $yr / $yi;
- $d = $yi + $r * $yr;
- $this->cdivr = ($r * $xr + $xi) / $d;
- $this->cdivi = ($r * $xi - $xr) / $d;
- }
- }
-
- /**
- * Nonsymmetric reduction from Hessenberg to real Schur form.
- *
- * Code is derived from the Algol procedure hqr2,
- * by Martin and Wilkinson, Handbook for Auto. Comp.,
- * Vol.ii-Linear Algebra, and the corresponding
- * Fortran subroutine in EISPACK.
- */
- private function hqr2(): void
- {
- // Initialize
- $nn = $this->n;
- $n = $nn - 1;
- $low = 0;
- $high = $nn - 1;
- $eps = 2.0 ** (-52.0);
- $exshift = 0.0;
- $p = $q = $r = $s = $z = 0;
- // Store roots isolated by balanc and compute matrix norm
- $norm = 0.0;
-
- for ($i = 0; $i < $nn; ++$i) {
- if (($i < $low) || ($i > $high)) {
- $this->d[$i] = $this->H[$i][$i];
- $this->e[$i] = 0.0;
- }
- for ($j = max($i - 1, 0); $j < $nn; ++$j) {
- $norm = $norm + abs($this->H[$i][$j]);
- }
- }
-
- // Outer loop over eigenvalue index
- $iter = 0;
- while ($n >= $low) {
- // Look for single small sub-diagonal element
- $l = $n;
- while ($l > $low) {
- $s = abs($this->H[$l - 1][$l - 1]) + abs($this->H[$l][$l]);
- if ($s == 0.0) {
- $s = $norm;
- }
- if (abs($this->H[$l][$l - 1]) < $eps * $s) {
- break;
- }
- --$l;
- }
- // Check for convergence
- // One root found
- if ($l == $n) {
- $this->H[$n][$n] = $this->H[$n][$n] + $exshift;
- $this->d[$n] = $this->H[$n][$n];
- $this->e[$n] = 0.0;
- --$n;
- $iter = 0;
- // Two roots found
- } elseif ($l == $n - 1) {
- $w = $this->H[$n][$n - 1] * $this->H[$n - 1][$n];
- $p = ($this->H[$n - 1][$n - 1] - $this->H[$n][$n]) / 2.0;
- $q = $p * $p + $w;
- $z = sqrt(abs($q));
- $this->H[$n][$n] = $this->H[$n][$n] + $exshift;
- $this->H[$n - 1][$n - 1] = $this->H[$n - 1][$n - 1] + $exshift;
- $x = $this->H[$n][$n];
- // Real pair
- if ($q >= 0) {
- if ($p >= 0) {
- $z = $p + $z;
- } else {
- $z = $p - $z;
- }
- $this->d[$n - 1] = $x + $z;
- $this->d[$n] = $this->d[$n - 1];
- if ($z != 0.0) {
- $this->d[$n] = $x - $w / $z;
- }
- $this->e[$n - 1] = 0.0;
- $this->e[$n] = 0.0;
- $x = $this->H[$n][$n - 1];
- $s = abs($x) + abs($z);
- $p = $x / $s;
- $q = $z / $s;
- $r = sqrt($p * $p + $q * $q);
- $p = $p / $r;
- $q = $q / $r;
- // Row modification
- for ($j = $n - 1; $j < $nn; ++$j) {
- $z = $this->H[$n - 1][$j];
- $this->H[$n - 1][$j] = $q * $z + $p * $this->H[$n][$j];
- $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z;
- }
- // Column modification
- for ($i = 0; $i <= $n; ++$i) {
- $z = $this->H[$i][$n - 1];
- $this->H[$i][$n - 1] = $q * $z + $p * $this->H[$i][$n];
- $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z;
- }
- // Accumulate transformations
- for ($i = $low; $i <= $high; ++$i) {
- $z = $this->V[$i][$n - 1];
- $this->V[$i][$n - 1] = $q * $z + $p * $this->V[$i][$n];
- $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z;
- }
- // Complex pair
- } else {
- $this->d[$n - 1] = $x + $p;
- $this->d[$n] = $x + $p;
- $this->e[$n - 1] = $z;
- $this->e[$n] = -$z;
- }
- $n = $n - 2;
- $iter = 0;
- // No convergence yet
- } else {
- // Form shift
- $x = $this->H[$n][$n];
- $y = 0.0;
- $w = 0.0;
- if ($l < $n) {
- $y = $this->H[$n - 1][$n - 1];
- $w = $this->H[$n][$n - 1] * $this->H[$n - 1][$n];
- }
- // Wilkinson's original ad hoc shift
- if ($iter == 10) {
- $exshift += $x;
- for ($i = $low; $i <= $n; ++$i) {
- $this->H[$i][$i] -= $x;
- }
- $s = abs($this->H[$n][$n - 1]) + abs($this->H[$n - 1][$n - 2]);
- $x = $y = 0.75 * $s;
- $w = -0.4375 * $s * $s;
- }
- // MATLAB's new ad hoc shift
- if ($iter == 30) {
- $s = ($y - $x) / 2.0;
- $s = $s * $s + $w;
- if ($s > 0) {
- $s = sqrt($s);
- if ($y < $x) {
- $s = -$s;
- }
- $s = $x - $w / (($y - $x) / 2.0 + $s);
- for ($i = $low; $i <= $n; ++$i) {
- $this->H[$i][$i] -= $s;
- }
- $exshift += $s;
- $x = $y = $w = 0.964;
- }
- }
- // Could check iteration count here.
- $iter = $iter + 1;
- // Look for two consecutive small sub-diagonal elements
- $m = $n - 2;
- while ($m >= $l) {
- $z = $this->H[$m][$m];
- $r = $x - $z;
- $s = $y - $z;
- $p = ($r * $s - $w) / $this->H[$m + 1][$m] + $this->H[$m][$m + 1];
- $q = $this->H[$m + 1][$m + 1] - $z - $r - $s;
- $r = $this->H[$m + 2][$m + 1];
- $s = abs($p) + abs($q) + abs($r);
- $p = $p / $s;
- $q = $q / $s;
- $r = $r / $s;
- if ($m == $l) {
- break;
- }
- if (
- abs($this->H[$m][$m - 1]) * (abs($q) + abs($r)) <
- $eps * (abs($p) * (abs($this->H[$m - 1][$m - 1]) + abs($z) + abs($this->H[$m + 1][$m + 1])))
- ) {
- break;
- }
- --$m;
- }
- for ($i = $m + 2; $i <= $n; ++$i) {
- $this->H[$i][$i - 2] = 0.0;
- if ($i > $m + 2) {
- $this->H[$i][$i - 3] = 0.0;
- }
- }
- // Double QR step involving rows l:n and columns m:n
- for ($k = $m; $k <= $n - 1; ++$k) {
- $notlast = ($k != $n - 1);
- if ($k != $m) {
- $p = $this->H[$k][$k - 1];
- $q = $this->H[$k + 1][$k - 1];
- $r = ($notlast ? $this->H[$k + 2][$k - 1] : 0.0);
- $x = abs($p) + abs($q) + abs($r);
- if ($x != 0.0) {
- $p = $p / $x;
- $q = $q / $x;
- $r = $r / $x;
- }
- }
- if ($x == 0.0) {
- break;
- }
- $s = sqrt($p * $p + $q * $q + $r * $r);
- if ($p < 0) {
- $s = -$s;
- }
- if ($s != 0) {
- if ($k != $m) {
- $this->H[$k][$k - 1] = -$s * $x;
- } elseif ($l != $m) {
- $this->H[$k][$k - 1] = -$this->H[$k][$k - 1];
- }
- $p = $p + $s;
- $x = $p / $s;
- $y = $q / $s;
- $z = $r / $s;
- $q = $q / $p;
- $r = $r / $p;
- // Row modification
- for ($j = $k; $j < $nn; ++$j) {
- $p = $this->H[$k][$j] + $q * $this->H[$k + 1][$j];
- if ($notlast) {
- $p = $p + $r * $this->H[$k + 2][$j];
- $this->H[$k + 2][$j] = $this->H[$k + 2][$j] - $p * $z;
- }
- $this->H[$k][$j] = $this->H[$k][$j] - $p * $x;
- $this->H[$k + 1][$j] = $this->H[$k + 1][$j] - $p * $y;
- }
- // Column modification
- $iMax = min($n, $k + 3);
- for ($i = 0; $i <= $iMax; ++$i) {
- $p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k + 1];
- if ($notlast) {
- $p = $p + $z * $this->H[$i][$k + 2];
- $this->H[$i][$k + 2] = $this->H[$i][$k + 2] - $p * $r;
- }
- $this->H[$i][$k] = $this->H[$i][$k] - $p;
- $this->H[$i][$k + 1] = $this->H[$i][$k + 1] - $p * $q;
- }
- // Accumulate transformations
- for ($i = $low; $i <= $high; ++$i) {
- $p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k + 1];
- if ($notlast) {
- $p = $p + $z * $this->V[$i][$k + 2];
- $this->V[$i][$k + 2] = $this->V[$i][$k + 2] - $p * $r;
- }
- $this->V[$i][$k] = $this->V[$i][$k] - $p;
- $this->V[$i][$k + 1] = $this->V[$i][$k + 1] - $p * $q;
- }
- } // ($s != 0)
- } // k loop
- } // check convergence
- } // while ($n >= $low)
-
- // Backsubstitute to find vectors of upper triangular form
- if ($norm == 0.0) {
- return;
- }
-
- for ($n = $nn - 1; $n >= 0; --$n) {
- $p = $this->d[$n];
- $q = $this->e[$n];
- // Real vector
- if ($q == 0) {
- $l = $n;
- $this->H[$n][$n] = 1.0;
- for ($i = $n - 1; $i >= 0; --$i) {
- $w = $this->H[$i][$i] - $p;
- $r = 0.0;
- for ($j = $l; $j <= $n; ++$j) {
- $r = $r + $this->H[$i][$j] * $this->H[$j][$n];
- }
- if ($this->e[$i] < 0.0) {
- $z = $w;
- $s = $r;
- } else {
- $l = $i;
- if ($this->e[$i] == 0.0) {
- if ($w != 0.0) {
- $this->H[$i][$n] = -$r / $w;
- } else {
- $this->H[$i][$n] = -$r / ($eps * $norm);
- }
- // Solve real equations
- } else {
- $x = $this->H[$i][$i + 1];
- $y = $this->H[$i + 1][$i];
- $q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i];
- $t = ($x * $s - $z * $r) / $q;
- $this->H[$i][$n] = $t;
- if (abs($x) > abs($z)) {
- $this->H[$i + 1][$n] = (-$r - $w * $t) / $x;
- } else {
- $this->H[$i + 1][$n] = (-$s - $y * $t) / $z;
- }
- }
- // Overflow control
- $t = abs($this->H[$i][$n]);
- if (($eps * $t) * $t > 1) {
- for ($j = $i; $j <= $n; ++$j) {
- $this->H[$j][$n] = $this->H[$j][$n] / $t;
- }
- }
- }
- }
- // Complex vector
- } elseif ($q < 0) {
- $l = $n - 1;
- // Last vector component imaginary so matrix is triangular
- if (abs($this->H[$n][$n - 1]) > abs($this->H[$n - 1][$n])) {
- $this->H[$n - 1][$n - 1] = $q / $this->H[$n][$n - 1];
- $this->H[$n - 1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n - 1];
- } else {
- $this->cdiv(0.0, -$this->H[$n - 1][$n], $this->H[$n - 1][$n - 1] - $p, $q);
- $this->H[$n - 1][$n - 1] = $this->cdivr;
- $this->H[$n - 1][$n] = $this->cdivi;
- }
- $this->H[$n][$n - 1] = 0.0;
- $this->H[$n][$n] = 1.0;
- for ($i = $n - 2; $i >= 0; --$i) {
- // double ra,sa,vr,vi;
- $ra = 0.0;
- $sa = 0.0;
- for ($j = $l; $j <= $n; ++$j) {
- $ra = $ra + $this->H[$i][$j] * $this->H[$j][$n - 1];
- $sa = $sa + $this->H[$i][$j] * $this->H[$j][$n];
- }
- $w = $this->H[$i][$i] - $p;
- if ($this->e[$i] < 0.0) {
- $z = $w;
- $r = $ra;
- $s = $sa;
- } else {
- $l = $i;
- if ($this->e[$i] == 0) {
- $this->cdiv(-$ra, -$sa, $w, $q);
- $this->H[$i][$n - 1] = $this->cdivr;
- $this->H[$i][$n] = $this->cdivi;
- } else {
- // Solve complex equations
- $x = $this->H[$i][$i + 1];
- $y = $this->H[$i + 1][$i];
- $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q;
- $vi = ($this->d[$i] - $p) * 2.0 * $q;
- if ($vr == 0.0 & $vi == 0.0) {
- $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z));
- }
- $this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi);
- $this->H[$i][$n - 1] = $this->cdivr;
- $this->H[$i][$n] = $this->cdivi;
- if (abs($x) > (abs($z) + abs($q))) {
- $this->H[$i + 1][$n - 1] = (-$ra - $w * $this->H[$i][$n - 1] + $q * $this->H[$i][$n]) / $x;
- $this->H[$i + 1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n - 1]) / $x;
- } else {
- $this->cdiv(-$r - $y * $this->H[$i][$n - 1], -$s - $y * $this->H[$i][$n], $z, $q);
- $this->H[$i + 1][$n - 1] = $this->cdivr;
- $this->H[$i + 1][$n] = $this->cdivi;
- }
- }
- // Overflow control
- $t = max(abs($this->H[$i][$n - 1]), abs($this->H[$i][$n]));
- if (($eps * $t) * $t > 1) {
- for ($j = $i; $j <= $n; ++$j) {
- $this->H[$j][$n - 1] = $this->H[$j][$n - 1] / $t;
- $this->H[$j][$n] = $this->H[$j][$n] / $t;
- }
- }
- } // end else
- } // end for
- } // end else for complex case
- } // end for
-
- // Vectors of isolated roots
- for ($i = 0; $i < $nn; ++$i) {
- if ($i < $low | $i > $high) {
- for ($j = $i; $j < $nn; ++$j) {
- $this->V[$i][$j] = $this->H[$i][$j];
- }
- }
- }
-
- // Back transformation to get eigenvectors of original matrix
- for ($j = $nn - 1; $j >= $low; --$j) {
- for ($i = $low; $i <= $high; ++$i) {
- $z = 0.0;
- $kMax = min($j, $high);
- for ($k = $low; $k <= $kMax; ++$k) {
- $z = $z + $this->V[$i][$k] * $this->H[$k][$j];
- }
- $this->V[$i][$j] = $z;
- }
- }
- }
-
- // end hqr2
-
- /**
- * Constructor: Check for symmetry, then construct the eigenvalue decomposition.
- *
- * @param mixed $Arg A Square matrix
- */
- public function __construct($Arg)
- {
- $this->A = $Arg->getArray();
- $this->n = $Arg->getColumnDimension();
-
- $issymmetric = true;
- for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) {
- for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) {
- $issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]);
- }
- }
-
- if ($issymmetric) {
- $this->V = $this->A;
- // Tridiagonalize.
- $this->tred2();
- // Diagonalize.
- $this->tql2();
- } else {
- $this->H = $this->A;
- $this->ort = [];
- // Reduce to Hessenberg form.
- $this->orthes();
- // Reduce Hessenberg to real Schur form.
- $this->hqr2();
- }
- }
-
- /**
- * Return the eigenvector matrix.
- *
- * @return Matrix V
- */
- public function getV()
- {
- return new Matrix($this->V, $this->n, $this->n);
- }
-
- /**
- * Return the real parts of the eigenvalues.
- *
- * @return array real(diag(D))
- */
- public function getRealEigenvalues()
- {
- return $this->d;
- }
-
- /**
- * Return the imaginary parts of the eigenvalues.
- *
- * @return array imag(diag(D))
- */
- public function getImagEigenvalues()
- {
- return $this->e;
- }
-
- /**
- * Return the block diagonal eigenvalue matrix.
- *
- * @return Matrix D
- */
- public function getD()
- {
- for ($i = 0; $i < $this->n; ++$i) {
- $D[$i] = array_fill(0, $this->n, 0.0);
- $D[$i][$i] = $this->d[$i];
- if ($this->e[$i] == 0) {
- continue;
- }
- $o = ($this->e[$i] > 0) ? $i + 1 : $i - 1;
- $D[$i][$o] = $this->e[$i];
- }
-
- return new Matrix($D);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php b/vendor/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
deleted file mode 100644
index 4aecff7..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
+++ /dev/null
@@ -1,282 +0,0 @@
-= n, the LU decomposition is an m-by-n
- * unit lower triangular matrix L, an n-by-n upper triangular matrix U,
- * and a permutation vector piv of length m so that A(piv,:) = L*U.
- * If m < n, then L is m-by-m and U is m-by-n.
- *
- * The LU decompostion with pivoting always exists, even if the matrix is
- * singular, so the constructor will never fail. The primary use of the
- * LU decomposition is in the solution of square systems of simultaneous
- * linear equations. This will fail if isNonsingular() returns false.
- *
- * @author Paul Meagher
- * @author Bartosz Matosiuk
- * @author Michael Bommarito
- *
- * @version 1.1
- */
-class LUDecomposition
-{
- const MATRIX_SINGULAR_EXCEPTION = 'Can only perform operation on singular matrix.';
- const MATRIX_SQUARE_EXCEPTION = 'Mismatched Row dimension';
-
- /**
- * Decomposition storage.
- *
- * @var array
- */
- private $LU = [];
-
- /**
- * Row dimension.
- *
- * @var int
- */
- private $m;
-
- /**
- * Column dimension.
- *
- * @var int
- */
- private $n;
-
- /**
- * Pivot sign.
- *
- * @var int
- */
- private $pivsign;
-
- /**
- * Internal storage of pivot vector.
- *
- * @var array
- */
- private $piv = [];
-
- /**
- * LU Decomposition constructor.
- *
- * @param Matrix $A Rectangular matrix
- */
- public function __construct($A)
- {
- if ($A instanceof Matrix) {
- // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
- $this->LU = $A->getArray();
- $this->m = $A->getRowDimension();
- $this->n = $A->getColumnDimension();
- for ($i = 0; $i < $this->m; ++$i) {
- $this->piv[$i] = $i;
- }
- $this->pivsign = 1;
- $LUrowi = $LUcolj = [];
-
- // Outer loop.
- for ($j = 0; $j < $this->n; ++$j) {
- // Make a copy of the j-th column to localize references.
- for ($i = 0; $i < $this->m; ++$i) {
- $LUcolj[$i] = &$this->LU[$i][$j];
- }
- // Apply previous transformations.
- for ($i = 0; $i < $this->m; ++$i) {
- $LUrowi = $this->LU[$i];
- // Most of the time is spent in the following dot product.
- $kmax = min($i, $j);
- $s = 0.0;
- for ($k = 0; $k < $kmax; ++$k) {
- $s += $LUrowi[$k] * $LUcolj[$k];
- }
- $LUrowi[$j] = $LUcolj[$i] -= $s;
- }
- // Find pivot and exchange if necessary.
- $p = $j;
- for ($i = $j + 1; $i < $this->m; ++$i) {
- if (abs($LUcolj[$i]) > abs($LUcolj[$p])) {
- $p = $i;
- }
- }
- if ($p != $j) {
- for ($k = 0; $k < $this->n; ++$k) {
- $t = $this->LU[$p][$k];
- $this->LU[$p][$k] = $this->LU[$j][$k];
- $this->LU[$j][$k] = $t;
- }
- $k = $this->piv[$p];
- $this->piv[$p] = $this->piv[$j];
- $this->piv[$j] = $k;
- $this->pivsign = $this->pivsign * -1;
- }
- // Compute multipliers.
- if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) {
- for ($i = $j + 1; $i < $this->m; ++$i) {
- $this->LU[$i][$j] /= $this->LU[$j][$j];
- }
- }
- }
- } else {
- throw new CalculationException(Matrix::ARGUMENT_TYPE_EXCEPTION);
- }
- }
-
- // function __construct()
-
- /**
- * Get lower triangular factor.
- *
- * @return Matrix Lower triangular factor
- */
- public function getL()
- {
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($i > $j) {
- $L[$i][$j] = $this->LU[$i][$j];
- } elseif ($i == $j) {
- $L[$i][$j] = 1.0;
- } else {
- $L[$i][$j] = 0.0;
- }
- }
- }
-
- return new Matrix($L);
- }
-
- // function getL()
-
- /**
- * Get upper triangular factor.
- *
- * @return Matrix Upper triangular factor
- */
- public function getU()
- {
- for ($i = 0; $i < $this->n; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($i <= $j) {
- $U[$i][$j] = $this->LU[$i][$j];
- } else {
- $U[$i][$j] = 0.0;
- }
- }
- }
-
- return new Matrix($U);
- }
-
- // function getU()
-
- /**
- * Return pivot permutation vector.
- *
- * @return array Pivot vector
- */
- public function getPivot()
- {
- return $this->piv;
- }
-
- // function getPivot()
-
- /**
- * Alias for getPivot.
- *
- * @see getPivot
- */
- public function getDoublePivot()
- {
- return $this->getPivot();
- }
-
- // function getDoublePivot()
-
- /**
- * Is the matrix nonsingular?
- *
- * @return bool true if U, and hence A, is nonsingular
- */
- public function isNonsingular()
- {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($this->LU[$j][$j] == 0) {
- return false;
- }
- }
-
- return true;
- }
-
- // function isNonsingular()
-
- /**
- * Count determinants.
- *
- * @return array d matrix deterninat
- */
- public function det()
- {
- if ($this->m == $this->n) {
- $d = $this->pivsign;
- for ($j = 0; $j < $this->n; ++$j) {
- $d *= $this->LU[$j][$j];
- }
-
- return $d;
- }
-
- throw new CalculationException(Matrix::MATRIX_DIMENSION_EXCEPTION);
- }
-
- // function det()
-
- /**
- * Solve A*X = B.
- *
- * @param mixed $B a Matrix with as many rows as A and any number of columns
- *
- * @return Matrix X so that L*U*X = B(piv,:)
- */
- public function solve($B)
- {
- if ($B->getRowDimension() == $this->m) {
- if ($this->isNonsingular()) {
- // Copy right hand side with pivoting
- $nx = $B->getColumnDimension();
- $X = $B->getMatrix($this->piv, 0, $nx - 1);
- // Solve L*Y = B(piv,:)
- for ($k = 0; $k < $this->n; ++$k) {
- for ($i = $k + 1; $i < $this->n; ++$i) {
- for ($j = 0; $j < $nx; ++$j) {
- $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
- }
- }
- }
- // Solve U*X = Y;
- for ($k = $this->n - 1; $k >= 0; --$k) {
- for ($j = 0; $j < $nx; ++$j) {
- $X->A[$k][$j] /= $this->LU[$k][$k];
- }
- for ($i = 0; $i < $k; ++$i) {
- for ($j = 0; $j < $nx; ++$j) {
- $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
- }
- }
- }
-
- return $X;
- }
-
- throw new CalculationException(self::MATRIX_SINGULAR_EXCEPTION);
- }
-
- throw new CalculationException(self::MATRIX_SQUARE_EXCEPTION);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/Matrix.php b/vendor/PhpSpreadsheet/Shared/JAMA/Matrix.php
deleted file mode 100644
index a5cb6de..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/Matrix.php
+++ /dev/null
@@ -1,1202 +0,0 @@
- 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- //Rectangular matrix - m x n initialized from 2D array
- case 'array':
- $this->m = count($args[0]);
- $this->n = count($args[0][0]);
- $this->A = $args[0];
-
- break;
- //Square matrix - n x n
- case 'integer':
- $this->m = $args[0];
- $this->n = $args[0];
- $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
-
- break;
- //Rectangular matrix - m x n
- case 'integer,integer':
- $this->m = $args[0];
- $this->n = $args[1];
- $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));
-
- break;
- //Rectangular matrix - m x n initialized from packed array
- case 'array,integer':
- $this->m = $args[1];
- if ($this->m != 0) {
- $this->n = count($args[0]) / $this->m;
- } else {
- $this->n = 0;
- }
- if (($this->m * $this->n) == count($args[0])) {
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $this->A[$i][$j] = $args[0][$i + $j * $this->m];
- }
- }
- } else {
- throw new CalculationException(self::ARRAY_LENGTH_EXCEPTION);
- }
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- } else {
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
- }
-
- /**
- * getArray.
- *
- * @return array Matrix array
- */
- public function getArray()
- {
- return $this->A;
- }
-
- /**
- * getRowDimension.
- *
- * @return int Row dimension
- */
- public function getRowDimension()
- {
- return $this->m;
- }
-
- /**
- * getColumnDimension.
- *
- * @return int Column dimension
- */
- public function getColumnDimension()
- {
- return $this->n;
- }
-
- /**
- * get.
- *
- * Get the i,j-th element of the matrix.
- *
- * @param int $i Row position
- * @param int $j Column position
- *
- * @return mixed Element (int/float/double)
- */
- public function get($i = null, $j = null)
- {
- return $this->A[$i][$j];
- }
-
- /**
- * getMatrix.
- *
- * Get a submatrix
- *
- * @return Matrix Submatrix
- */
- public function getMatrix(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- //A($i0...; $j0...)
- case 'integer,integer':
- [$i0, $j0] = $args;
- if ($i0 >= 0) {
- $m = $this->m - $i0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- if ($j0 >= 0) {
- $n = $this->n - $j0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- $R = new self($m, $n);
- for ($i = $i0; $i < $this->m; ++$i) {
- for ($j = $j0; $j < $this->n; ++$j) {
- $R->set($i, $j, $this->A[$i][$j]);
- }
- }
-
- return $R;
-
- break;
- //A($i0...$iF; $j0...$jF)
- case 'integer,integer,integer,integer':
- [$i0, $iF, $j0, $jF] = $args;
- if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) {
- $m = $iF - $i0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) {
- $n = $jF - $j0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- $R = new self($m + 1, $n + 1);
- for ($i = $i0; $i <= $iF; ++$i) {
- for ($j = $j0; $j <= $jF; ++$j) {
- $R->set($i - $i0, $j - $j0, $this->A[$i][$j]);
- }
- }
-
- return $R;
-
- break;
- //$R = array of row indices; $C = array of column indices
- case 'array,array':
- [$RL, $CL] = $args;
- if (count($RL) > 0) {
- $m = count($RL);
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- if (count($CL) > 0) {
- $n = count($CL);
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- $R = new self($m, $n);
- for ($i = 0; $i < $m; ++$i) {
- for ($j = 0; $j < $n; ++$j) {
- $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]);
- }
- }
-
- return $R;
-
- break;
- //A($i0...$iF); $CL = array of column indices
- case 'integer,integer,array':
- [$i0, $iF, $CL] = $args;
- if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) {
- $m = $iF - $i0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- if (count($CL) > 0) {
- $n = count($CL);
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- $R = new self($m, $n);
- for ($i = $i0; $i < $iF; ++$i) {
- for ($j = 0; $j < $n; ++$j) {
- $R->set($i - $i0, $j, $this->A[$i][$CL[$j]]);
- }
- }
-
- return $R;
-
- break;
- //$RL = array of row indices
- case 'array,integer,integer':
- [$RL, $j0, $jF] = $args;
- if (count($RL) > 0) {
- $m = count($RL);
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) {
- $n = $jF - $j0;
- } else {
- throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
- }
- $R = new self($m, $n + 1);
- for ($i = 0; $i < $m; ++$i) {
- for ($j = $j0; $j <= $jF; ++$j) {
- $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]);
- }
- }
-
- return $R;
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- } else {
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
- }
-
- /**
- * checkMatrixDimensions.
- *
- * Is matrix B the same size?
- *
- * @param Matrix $B Matrix B
- *
- * @return bool
- */
- public function checkMatrixDimensions($B = null)
- {
- if ($B instanceof self) {
- if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {
- return true;
- }
-
- throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
- }
-
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- // function checkMatrixDimensions()
-
- /**
- * set.
- *
- * Set the i,j-th element of the matrix.
- *
- * @param int $i Row position
- * @param int $j Column position
- * @param mixed $c Int/float/double value
- *
- * @return mixed Element (int/float/double)
- */
- public function set($i = null, $j = null, $c = null)
- {
- // Optimized set version just has this
- $this->A[$i][$j] = $c;
- }
-
- // function set()
-
- /**
- * identity.
- *
- * Generate an identity matrix.
- *
- * @param int $m Row dimension
- * @param int $n Column dimension
- *
- * @return Matrix Identity matrix
- */
- public function identity($m = null, $n = null)
- {
- return $this->diagonal($m, $n, 1);
- }
-
- /**
- * diagonal.
- *
- * Generate a diagonal matrix
- *
- * @param int $m Row dimension
- * @param int $n Column dimension
- * @param mixed $c Diagonal value
- *
- * @return Matrix Diagonal matrix
- */
- public function diagonal($m = null, $n = null, $c = 1)
- {
- $R = new self($m, $n);
- for ($i = 0; $i < $m; ++$i) {
- $R->set($i, $i, $c);
- }
-
- return $R;
- }
-
- /**
- * getMatrixByRow.
- *
- * Get a submatrix by row index/range
- *
- * @param int $i0 Initial row index
- * @param int $iF Final row index
- *
- * @return Matrix Submatrix
- */
- public function getMatrixByRow($i0 = null, $iF = null)
- {
- if (is_int($i0)) {
- if (is_int($iF)) {
- return $this->getMatrix($i0, 0, $iF + 1, $this->n);
- }
-
- return $this->getMatrix($i0, 0, $i0 + 1, $this->n);
- }
-
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- /**
- * getMatrixByCol.
- *
- * Get a submatrix by column index/range
- *
- * @param int $j0 Initial column index
- * @param int $jF Final column index
- *
- * @return Matrix Submatrix
- */
- public function getMatrixByCol($j0 = null, $jF = null)
- {
- if (is_int($j0)) {
- if (is_int($jF)) {
- return $this->getMatrix(0, $j0, $this->m, $jF + 1);
- }
-
- return $this->getMatrix(0, $j0, $this->m, $j0 + 1);
- }
-
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- /**
- * transpose.
- *
- * Tranpose matrix
- *
- * @return Matrix Transposed matrix
- */
- public function transpose()
- {
- $R = new self($this->n, $this->m);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $R->set($j, $i, $this->A[$i][$j]);
- }
- }
-
- return $R;
- }
-
- // function transpose()
-
- /**
- * trace.
- *
- * Sum of diagonal elements
- *
- * @return float Sum of diagonal elements
- */
- public function trace()
- {
- $s = 0;
- $n = min($this->m, $this->n);
- for ($i = 0; $i < $n; ++$i) {
- $s += $this->A[$i][$i];
- }
-
- return $s;
- }
-
- /**
- * uminus.
- *
- * Unary minus matrix -A
- *
- * @return Matrix Unary minus matrix
- */
- public function uminus()
- {
- }
-
- /**
- * plus.
- *
- * A + B
- *
- * @return Matrix Sum
- */
- public function plus(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * plusEquals.
- *
- * A = A + B
- *
- * @return $this
- */
- public function plusEquals(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $validValues = true;
- $value = $M->get($i, $j);
- if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"');
- $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
- }
- if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
- $value = trim($value, '"');
- $validValues &= StringHelper::convertToNumberIfFraction($value);
- }
- if ($validValues) {
- $this->A[$i][$j] += $value;
- } else {
- $this->A[$i][$j] = Functions::NAN();
- }
- }
- }
-
- return $this;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * minus.
- *
- * A - B
- *
- * @return Matrix Sum
- */
- public function minus(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]);
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * minusEquals.
- *
- * A = A - B
- *
- * @return $this
- */
- public function minusEquals(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $validValues = true;
- $value = $M->get($i, $j);
- if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"');
- $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
- }
- if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
- $value = trim($value, '"');
- $validValues &= StringHelper::convertToNumberIfFraction($value);
- }
- if ($validValues) {
- $this->A[$i][$j] -= $value;
- } else {
- $this->A[$i][$j] = Functions::NAN();
- }
- }
- }
-
- return $this;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayTimes.
- *
- * Element-by-element multiplication
- * Cij = Aij * Bij
- *
- * @return Matrix Matrix Cij
- */
- public function arrayTimes(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]);
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayTimesEquals.
- *
- * Element-by-element multiplication
- * Aij = Aij * Bij
- *
- * @return $this
- */
- public function arrayTimesEquals(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $validValues = true;
- $value = $M->get($i, $j);
- if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"');
- $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
- }
- if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
- $value = trim($value, '"');
- $validValues &= StringHelper::convertToNumberIfFraction($value);
- }
- if ($validValues) {
- $this->A[$i][$j] *= $value;
- } else {
- $this->A[$i][$j] = Functions::NAN();
- }
- }
- }
-
- return $this;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayRightDivide.
- *
- * Element-by-element right division
- * A / B
- *
- * @return Matrix Division result
- */
- public function arrayRightDivide(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $validValues = true;
- $value = $M->get($i, $j);
- if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"');
- $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
- }
- if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
- $value = trim($value, '"');
- $validValues &= StringHelper::convertToNumberIfFraction($value);
- }
- if ($validValues) {
- if ($value == 0) {
- // Trap for Divide by Zero error
- $M->set($i, $j, '#DIV/0!');
- } else {
- $M->set($i, $j, $this->A[$i][$j] / $value);
- }
- } else {
- $M->set($i, $j, Functions::NAN());
- }
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayRightDivideEquals.
- *
- * Element-by-element right division
- * Aij = Aij / Bij
- *
- * @return Matrix Matrix Aij
- */
- public function arrayRightDivideEquals(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j);
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayLeftDivide.
- *
- * Element-by-element Left division
- * A / B
- *
- * @return Matrix Division result
- */
- public function arrayLeftDivide(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]);
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * arrayLeftDivideEquals.
- *
- * Element-by-element Left division
- * Aij = Aij / Bij
- *
- * @return Matrix Matrix Aij
- */
- public function arrayLeftDivideEquals(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j];
- }
- }
-
- return $M;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * times.
- *
- * Matrix multiplication
- *
- * @return Matrix Product
- */
- public function times(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $B = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
- if ($this->n == $B->m) {
- $C = new self($this->m, $B->n);
- for ($j = 0; $j < $B->n; ++$j) {
- $Bcolj = [];
- for ($k = 0; $k < $this->n; ++$k) {
- $Bcolj[$k] = $B->A[$k][$j];
- }
- for ($i = 0; $i < $this->m; ++$i) {
- $Arowi = $this->A[$i];
- $s = 0;
- for ($k = 0; $k < $this->n; ++$k) {
- $s += $Arowi[$k] * $Bcolj[$k];
- }
- $C->A[$i][$j] = $s;
- }
- }
-
- return $C;
- }
-
- throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
- case 'array':
- $B = new self($args[0]);
- if ($this->n == $B->m) {
- $C = new self($this->m, $B->n);
- for ($i = 0; $i < $C->m; ++$i) {
- for ($j = 0; $j < $C->n; ++$j) {
- $s = '0';
- for ($k = 0; $k < $C->n; ++$k) {
- $s += $this->A[$i][$k] * $B->A[$k][$j];
- }
- $C->A[$i][$j] = $s;
- }
- }
-
- return $C;
- }
-
- throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
- case 'integer':
- $C = new self($this->A);
- for ($i = 0; $i < $C->m; ++$i) {
- for ($j = 0; $j < $C->n; ++$j) {
- $C->A[$i][$j] *= $args[0];
- }
- }
-
- return $C;
- case 'double':
- $C = new self($this->m, $this->n);
- for ($i = 0; $i < $C->m; ++$i) {
- for ($j = 0; $j < $C->n; ++$j) {
- $C->A[$i][$j] = $args[0] * $this->A[$i][$j];
- }
- }
-
- return $C;
- case 'float':
- $C = new self($this->A);
- for ($i = 0; $i < $C->m; ++$i) {
- for ($j = 0; $j < $C->n; ++$j) {
- $C->A[$i][$j] *= $args[0];
- }
- }
-
- return $C;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
- } else {
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
- }
-
- /**
- * power.
- *
- * A = A ^ B
- *
- * @return $this
- */
- public function power(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $validValues = true;
- $value = $M->get($i, $j);
- if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"');
- $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
- }
- if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
- $value = trim($value, '"');
- $validValues &= StringHelper::convertToNumberIfFraction($value);
- }
- if ($validValues) {
- $this->A[$i][$j] = $this->A[$i][$j] ** $value;
- } else {
- $this->A[$i][$j] = Functions::NAN();
- }
- }
- }
-
- return $this;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * concat.
- *
- * A = A & B
- *
- * @return $this
- */
- public function concat(...$args)
- {
- if (count($args) > 0) {
- $match = implode(',', array_map('gettype', $args));
-
- switch ($match) {
- case 'object':
- if ($args[0] instanceof self) {
- $M = $args[0];
- } else {
- throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
- }
-
- break;
- case 'array':
- $M = new self($args[0]);
-
- break;
- default:
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
-
- break;
- }
- $this->checkMatrixDimensions($M);
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $this->A[$i][$j] = trim($this->A[$i][$j], '"') . trim($M->get($i, $j), '"');
- }
- }
-
- return $this;
- }
-
- throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
- }
-
- /**
- * Solve A*X = B.
- *
- * @param Matrix $B Right hand side
- *
- * @return Matrix ... Solution if A is square, least squares solution otherwise
- */
- public function solve($B)
- {
- if ($this->m == $this->n) {
- $LU = new LUDecomposition($this);
-
- return $LU->solve($B);
- }
- $QR = new QRDecomposition($this);
-
- return $QR->solve($B);
- }
-
- /**
- * Matrix inverse or pseudoinverse.
- *
- * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise.
- */
- public function inverse()
- {
- return $this->solve($this->identity($this->m, $this->m));
- }
-
- /**
- * det.
- *
- * Calculate determinant
- *
- * @return float Determinant
- */
- public function det()
- {
- $L = new LUDecomposition($this);
-
- return $L->det();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php b/vendor/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php
deleted file mode 100644
index 3bb8a10..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php
+++ /dev/null
@@ -1,249 +0,0 @@
-= n, the QR decomposition is an m-by-n
- * orthogonal matrix Q and an n-by-n upper triangular matrix R so that
- * A = Q*R.
- *
- * The QR decompostion always exists, even if the matrix does not have
- * full rank, so the constructor will never fail. The primary use of the
- * QR decomposition is in the least squares solution of nonsquare systems
- * of simultaneous linear equations. This will fail if isFullRank()
- * returns false.
- *
- * @author Paul Meagher
- *
- * @version 1.1
- */
-class QRDecomposition
-{
- const MATRIX_RANK_EXCEPTION = 'Can only perform operation on full-rank matrix.';
-
- /**
- * Array for internal storage of decomposition.
- *
- * @var array
- */
- private $QR = [];
-
- /**
- * Row dimension.
- *
- * @var int
- */
- private $m;
-
- /**
- * Column dimension.
- *
- * @var int
- */
- private $n;
-
- /**
- * Array for internal storage of diagonal of R.
- *
- * @var array
- */
- private $Rdiag = [];
-
- /**
- * QR Decomposition computed by Householder reflections.
- *
- * @param matrix $A Rectangular matrix
- */
- public function __construct($A)
- {
- if ($A instanceof Matrix) {
- // Initialize.
- $this->QR = $A->getArray();
- $this->m = $A->getRowDimension();
- $this->n = $A->getColumnDimension();
- // Main loop.
- for ($k = 0; $k < $this->n; ++$k) {
- // Compute 2-norm of k-th column without under/overflow.
- $nrm = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $nrm = hypo($nrm, $this->QR[$i][$k]);
- }
- if ($nrm != 0.0) {
- // Form k-th Householder vector.
- if ($this->QR[$k][$k] < 0) {
- $nrm = -$nrm;
- }
- for ($i = $k; $i < $this->m; ++$i) {
- $this->QR[$i][$k] /= $nrm;
- }
- $this->QR[$k][$k] += 1.0;
- // Apply transformation to remaining columns.
- for ($j = $k + 1; $j < $this->n; ++$j) {
- $s = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $s += $this->QR[$i][$k] * $this->QR[$i][$j];
- }
- $s = -$s / $this->QR[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $this->QR[$i][$j] += $s * $this->QR[$i][$k];
- }
- }
- }
- $this->Rdiag[$k] = -$nrm;
- }
- } else {
- throw new CalculationException(Matrix::ARGUMENT_TYPE_EXCEPTION);
- }
- }
-
- // function __construct()
-
- /**
- * Is the matrix full rank?
- *
- * @return bool true if R, and hence A, has full rank, else false
- */
- public function isFullRank()
- {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($this->Rdiag[$j] == 0) {
- return false;
- }
- }
-
- return true;
- }
-
- // function isFullRank()
-
- /**
- * Return the Householder vectors.
- *
- * @return Matrix Lower trapezoidal matrix whose columns define the reflections
- */
- public function getH()
- {
- $H = [];
- for ($i = 0; $i < $this->m; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($i >= $j) {
- $H[$i][$j] = $this->QR[$i][$j];
- } else {
- $H[$i][$j] = 0.0;
- }
- }
- }
-
- return new Matrix($H);
- }
-
- // function getH()
-
- /**
- * Return the upper triangular factor.
- *
- * @return Matrix upper triangular factor
- */
- public function getR()
- {
- $R = [];
- for ($i = 0; $i < $this->n; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- if ($i < $j) {
- $R[$i][$j] = $this->QR[$i][$j];
- } elseif ($i == $j) {
- $R[$i][$j] = $this->Rdiag[$i];
- } else {
- $R[$i][$j] = 0.0;
- }
- }
- }
-
- return new Matrix($R);
- }
-
- // function getR()
-
- /**
- * Generate and return the (economy-sized) orthogonal factor.
- *
- * @return Matrix orthogonal factor
- */
- public function getQ()
- {
- $Q = [];
- for ($k = $this->n - 1; $k >= 0; --$k) {
- for ($i = 0; $i < $this->m; ++$i) {
- $Q[$i][$k] = 0.0;
- }
- $Q[$k][$k] = 1.0;
- for ($j = $k; $j < $this->n; ++$j) {
- if ($this->QR[$k][$k] != 0) {
- $s = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $s += $this->QR[$i][$k] * $Q[$i][$j];
- }
- $s = -$s / $this->QR[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $Q[$i][$j] += $s * $this->QR[$i][$k];
- }
- }
- }
- }
-
- return new Matrix($Q);
- }
-
- // function getQ()
-
- /**
- * Least squares solution of A*X = B.
- *
- * @param Matrix $B a Matrix with as many rows as A and any number of columns
- *
- * @return Matrix matrix that minimizes the two norm of Q*R*X-B
- */
- public function solve($B)
- {
- if ($B->getRowDimension() == $this->m) {
- if ($this->isFullRank()) {
- // Copy right hand side
- $nx = $B->getColumnDimension();
- $X = $B->getArrayCopy();
- // Compute Y = transpose(Q)*B
- for ($k = 0; $k < $this->n; ++$k) {
- for ($j = 0; $j < $nx; ++$j) {
- $s = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $s += $this->QR[$i][$k] * $X[$i][$j];
- }
- $s = -$s / $this->QR[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $X[$i][$j] += $s * $this->QR[$i][$k];
- }
- }
- }
- // Solve R*X = Y;
- for ($k = $this->n - 1; $k >= 0; --$k) {
- for ($j = 0; $j < $nx; ++$j) {
- $X[$k][$j] /= $this->Rdiag[$k];
- }
- for ($i = 0; $i < $k; ++$i) {
- for ($j = 0; $j < $nx; ++$j) {
- $X[$i][$j] -= $X[$k][$j] * $this->QR[$i][$k];
- }
- }
- }
- $X = new Matrix($X);
-
- return $X->getMatrix(0, $this->n - 1, 0, $nx);
- }
-
- throw new CalculationException(self::MATRIX_RANK_EXCEPTION);
- }
-
- throw new CalculationException(Matrix::MATRIX_DIMENSION_EXCEPTION);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php b/vendor/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
deleted file mode 100644
index b997fb7..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
+++ /dev/null
@@ -1,528 +0,0 @@
-= n, the singular value decomposition is
- * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
- * an n-by-n orthogonal matrix V so that A = U*S*V'.
- *
- * The singular values, sigma[$k] = S[$k][$k], are ordered so that
- * sigma[0] >= sigma[1] >= ... >= sigma[n-1].
- *
- * The singular value decompostion always exists, so the constructor will
- * never fail. The matrix condition number and the effective numerical
- * rank can be computed from this decomposition.
- *
- * @author Paul Meagher
- *
- * @version 1.1
- */
-class SingularValueDecomposition
-{
- /**
- * Internal storage of U.
- *
- * @var array
- */
- private $U = [];
-
- /**
- * Internal storage of V.
- *
- * @var array
- */
- private $V = [];
-
- /**
- * Internal storage of singular values.
- *
- * @var array
- */
- private $s = [];
-
- /**
- * Row dimension.
- *
- * @var int
- */
- private $m;
-
- /**
- * Column dimension.
- *
- * @var int
- */
- private $n;
-
- /**
- * Construct the singular value decomposition.
- *
- * Derived from LINPACK code.
- *
- * @param mixed $Arg Rectangular matrix
- */
- public function __construct($Arg)
- {
- // Initialize.
- $A = $Arg->getArrayCopy();
- $this->m = $Arg->getRowDimension();
- $this->n = $Arg->getColumnDimension();
- $nu = min($this->m, $this->n);
- $e = [];
- $work = [];
- $wantu = true;
- $wantv = true;
- $nct = min($this->m - 1, $this->n);
- $nrt = max(0, min($this->n - 2, $this->m));
-
- // Reduce A to bidiagonal form, storing the diagonal elements
- // in s and the super-diagonal elements in e.
- $kMax = max($nct, $nrt);
- for ($k = 0; $k < $kMax; ++$k) {
- if ($k < $nct) {
- // Compute the transformation for the k-th column and
- // place the k-th diagonal in s[$k].
- // Compute 2-norm of k-th column without under/overflow.
- $this->s[$k] = 0;
- for ($i = $k; $i < $this->m; ++$i) {
- $this->s[$k] = hypo($this->s[$k], $A[$i][$k]);
- }
- if ($this->s[$k] != 0.0) {
- if ($A[$k][$k] < 0.0) {
- $this->s[$k] = -$this->s[$k];
- }
- for ($i = $k; $i < $this->m; ++$i) {
- $A[$i][$k] /= $this->s[$k];
- }
- $A[$k][$k] += 1.0;
- }
- $this->s[$k] = -$this->s[$k];
- }
-
- for ($j = $k + 1; $j < $this->n; ++$j) {
- if (($k < $nct) & ($this->s[$k] != 0.0)) {
- // Apply the transformation.
- $t = 0;
- for ($i = $k; $i < $this->m; ++$i) {
- $t += $A[$i][$k] * $A[$i][$j];
- }
- $t = -$t / $A[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $A[$i][$j] += $t * $A[$i][$k];
- }
- // Place the k-th row of A into e for the
- // subsequent calculation of the row transformation.
- $e[$j] = $A[$k][$j];
- }
- }
-
- if ($wantu && ($k < $nct)) {
- // Place the transformation in U for subsequent back
- // multiplication.
- for ($i = $k; $i < $this->m; ++$i) {
- $this->U[$i][$k] = $A[$i][$k];
- }
- }
-
- if ($k < $nrt) {
- // Compute the k-th row transformation and place the
- // k-th super-diagonal in e[$k].
- // Compute 2-norm without under/overflow.
- $e[$k] = 0;
- for ($i = $k + 1; $i < $this->n; ++$i) {
- $e[$k] = hypo($e[$k], $e[$i]);
- }
- if ($e[$k] != 0.0) {
- if ($e[$k + 1] < 0.0) {
- $e[$k] = -$e[$k];
- }
- for ($i = $k + 1; $i < $this->n; ++$i) {
- $e[$i] /= $e[$k];
- }
- $e[$k + 1] += 1.0;
- }
- $e[$k] = -$e[$k];
- if (($k + 1 < $this->m) && ($e[$k] != 0.0)) {
- // Apply the transformation.
- for ($i = $k + 1; $i < $this->m; ++$i) {
- $work[$i] = 0.0;
- }
- for ($j = $k + 1; $j < $this->n; ++$j) {
- for ($i = $k + 1; $i < $this->m; ++$i) {
- $work[$i] += $e[$j] * $A[$i][$j];
- }
- }
- for ($j = $k + 1; $j < $this->n; ++$j) {
- $t = -$e[$j] / $e[$k + 1];
- for ($i = $k + 1; $i < $this->m; ++$i) {
- $A[$i][$j] += $t * $work[$i];
- }
- }
- }
- if ($wantv) {
- // Place the transformation in V for subsequent
- // back multiplication.
- for ($i = $k + 1; $i < $this->n; ++$i) {
- $this->V[$i][$k] = $e[$i];
- }
- }
- }
- }
-
- // Set up the final bidiagonal matrix or order p.
- $p = min($this->n, $this->m + 1);
- if ($nct < $this->n) {
- $this->s[$nct] = $A[$nct][$nct];
- }
- if ($this->m < $p) {
- $this->s[$p - 1] = 0.0;
- }
- if ($nrt + 1 < $p) {
- $e[$nrt] = $A[$nrt][$p - 1];
- }
- $e[$p - 1] = 0.0;
- // If required, generate U.
- if ($wantu) {
- for ($j = $nct; $j < $nu; ++$j) {
- for ($i = 0; $i < $this->m; ++$i) {
- $this->U[$i][$j] = 0.0;
- }
- $this->U[$j][$j] = 1.0;
- }
- for ($k = $nct - 1; $k >= 0; --$k) {
- if ($this->s[$k] != 0.0) {
- for ($j = $k + 1; $j < $nu; ++$j) {
- $t = 0;
- for ($i = $k; $i < $this->m; ++$i) {
- $t += $this->U[$i][$k] * $this->U[$i][$j];
- }
- $t = -$t / $this->U[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $this->U[$i][$j] += $t * $this->U[$i][$k];
- }
- }
- for ($i = $k; $i < $this->m; ++$i) {
- $this->U[$i][$k] = -$this->U[$i][$k];
- }
- $this->U[$k][$k] = 1.0 + $this->U[$k][$k];
- for ($i = 0; $i < $k - 1; ++$i) {
- $this->U[$i][$k] = 0.0;
- }
- } else {
- for ($i = 0; $i < $this->m; ++$i) {
- $this->U[$i][$k] = 0.0;
- }
- $this->U[$k][$k] = 1.0;
- }
- }
- }
-
- // If required, generate V.
- if ($wantv) {
- for ($k = $this->n - 1; $k >= 0; --$k) {
- if (($k < $nrt) && ($e[$k] != 0.0)) {
- for ($j = $k + 1; $j < $nu; ++$j) {
- $t = 0;
- for ($i = $k + 1; $i < $this->n; ++$i) {
- $t += $this->V[$i][$k] * $this->V[$i][$j];
- }
- $t = -$t / $this->V[$k + 1][$k];
- for ($i = $k + 1; $i < $this->n; ++$i) {
- $this->V[$i][$j] += $t * $this->V[$i][$k];
- }
- }
- }
- for ($i = 0; $i < $this->n; ++$i) {
- $this->V[$i][$k] = 0.0;
- }
- $this->V[$k][$k] = 1.0;
- }
- }
-
- // Main iteration loop for the singular values.
- $pp = $p - 1;
- $iter = 0;
- $eps = 2.0 ** (-52.0);
-
- while ($p > 0) {
- // Here is where a test for too many iterations would go.
- // This section of the program inspects for negligible
- // elements in the s and e arrays. On completion the
- // variables kase and k are set as follows:
- // kase = 1 if s(p) and e[k-1] are negligible and k= -1; --$k) {
- if ($k == -1) {
- break;
- }
- if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k + 1]))) {
- $e[$k] = 0.0;
-
- break;
- }
- }
- if ($k == $p - 2) {
- $kase = 4;
- } else {
- for ($ks = $p - 1; $ks >= $k; --$ks) {
- if ($ks == $k) {
- break;
- }
- $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks - 1]) : 0.);
- if (abs($this->s[$ks]) <= $eps * $t) {
- $this->s[$ks] = 0.0;
-
- break;
- }
- }
- if ($ks == $k) {
- $kase = 3;
- } elseif ($ks == $p - 1) {
- $kase = 1;
- } else {
- $kase = 2;
- $k = $ks;
- }
- }
- ++$k;
-
- // Perform the task indicated by kase.
- switch ($kase) {
- // Deflate negligible s(p).
- case 1:
- $f = $e[$p - 2];
- $e[$p - 2] = 0.0;
- for ($j = $p - 2; $j >= $k; --$j) {
- $t = hypo($this->s[$j], $f);
- $cs = $this->s[$j] / $t;
- $sn = $f / $t;
- $this->s[$j] = $t;
- if ($j != $k) {
- $f = -$sn * $e[$j - 1];
- $e[$j - 1] = $cs * $e[$j - 1];
- }
- if ($wantv) {
- for ($i = 0; $i < $this->n; ++$i) {
- $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p - 1];
- $this->V[$i][$p - 1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p - 1];
- $this->V[$i][$j] = $t;
- }
- }
- }
-
- break;
- // Split at negligible s(k).
- case 2:
- $f = $e[$k - 1];
- $e[$k - 1] = 0.0;
- for ($j = $k; $j < $p; ++$j) {
- $t = hypo($this->s[$j], $f);
- $cs = $this->s[$j] / $t;
- $sn = $f / $t;
- $this->s[$j] = $t;
- $f = -$sn * $e[$j];
- $e[$j] = $cs * $e[$j];
- if ($wantu) {
- for ($i = 0; $i < $this->m; ++$i) {
- $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k - 1];
- $this->U[$i][$k - 1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k - 1];
- $this->U[$i][$j] = $t;
- }
- }
- }
-
- break;
- // Perform one qr step.
- case 3:
- // Calculate the shift.
- $scale = max(max(max(max(abs($this->s[$p - 1]), abs($this->s[$p - 2])), abs($e[$p - 2])), abs($this->s[$k])), abs($e[$k]));
- $sp = $this->s[$p - 1] / $scale;
- $spm1 = $this->s[$p - 2] / $scale;
- $epm1 = $e[$p - 2] / $scale;
- $sk = $this->s[$k] / $scale;
- $ek = $e[$k] / $scale;
- $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;
- $c = ($sp * $epm1) * ($sp * $epm1);
- $shift = 0.0;
- if (($b != 0.0) || ($c != 0.0)) {
- $shift = sqrt($b * $b + $c);
- if ($b < 0.0) {
- $shift = -$shift;
- }
- $shift = $c / ($b + $shift);
- }
- $f = ($sk + $sp) * ($sk - $sp) + $shift;
- $g = $sk * $ek;
- // Chase zeros.
- for ($j = $k; $j < $p - 1; ++$j) {
- $t = hypo($f, $g);
- $cs = $f / $t;
- $sn = $g / $t;
- if ($j != $k) {
- $e[$j - 1] = $t;
- }
- $f = $cs * $this->s[$j] + $sn * $e[$j];
- $e[$j] = $cs * $e[$j] - $sn * $this->s[$j];
- $g = $sn * $this->s[$j + 1];
- $this->s[$j + 1] = $cs * $this->s[$j + 1];
- if ($wantv) {
- for ($i = 0; $i < $this->n; ++$i) {
- $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j + 1];
- $this->V[$i][$j + 1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j + 1];
- $this->V[$i][$j] = $t;
- }
- }
- $t = hypo($f, $g);
- $cs = $f / $t;
- $sn = $g / $t;
- $this->s[$j] = $t;
- $f = $cs * $e[$j] + $sn * $this->s[$j + 1];
- $this->s[$j + 1] = -$sn * $e[$j] + $cs * $this->s[$j + 1];
- $g = $sn * $e[$j + 1];
- $e[$j + 1] = $cs * $e[$j + 1];
- if ($wantu && ($j < $this->m - 1)) {
- for ($i = 0; $i < $this->m; ++$i) {
- $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j + 1];
- $this->U[$i][$j + 1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j + 1];
- $this->U[$i][$j] = $t;
- }
- }
- }
- $e[$p - 2] = $f;
- $iter = $iter + 1;
-
- break;
- // Convergence.
- case 4:
- // Make the singular values positive.
- if ($this->s[$k] <= 0.0) {
- $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0);
- if ($wantv) {
- for ($i = 0; $i <= $pp; ++$i) {
- $this->V[$i][$k] = -$this->V[$i][$k];
- }
- }
- }
- // Order the singular values.
- while ($k < $pp) {
- if ($this->s[$k] >= $this->s[$k + 1]) {
- break;
- }
- $t = $this->s[$k];
- $this->s[$k] = $this->s[$k + 1];
- $this->s[$k + 1] = $t;
- if ($wantv && ($k < $this->n - 1)) {
- for ($i = 0; $i < $this->n; ++$i) {
- $t = $this->V[$i][$k + 1];
- $this->V[$i][$k + 1] = $this->V[$i][$k];
- $this->V[$i][$k] = $t;
- }
- }
- if ($wantu && ($k < $this->m - 1)) {
- for ($i = 0; $i < $this->m; ++$i) {
- $t = $this->U[$i][$k + 1];
- $this->U[$i][$k + 1] = $this->U[$i][$k];
- $this->U[$i][$k] = $t;
- }
- }
- ++$k;
- }
- $iter = 0;
- --$p;
-
- break;
- } // end switch
- } // end while
- }
-
- /**
- * Return the left singular vectors.
- *
- * @return Matrix U
- */
- public function getU()
- {
- return new Matrix($this->U, $this->m, min($this->m + 1, $this->n));
- }
-
- /**
- * Return the right singular vectors.
- *
- * @return Matrix V
- */
- public function getV()
- {
- return new Matrix($this->V);
- }
-
- /**
- * Return the one-dimensional array of singular values.
- *
- * @return array diagonal of S
- */
- public function getSingularValues()
- {
- return $this->s;
- }
-
- /**
- * Return the diagonal matrix of singular values.
- *
- * @return Matrix S
- */
- public function getS()
- {
- for ($i = 0; $i < $this->n; ++$i) {
- for ($j = 0; $j < $this->n; ++$j) {
- $S[$i][$j] = 0.0;
- }
- $S[$i][$i] = $this->s[$i];
- }
-
- return new Matrix($S);
- }
-
- /**
- * Two norm.
- *
- * @return float max(S)
- */
- public function norm2()
- {
- return $this->s[0];
- }
-
- /**
- * Two norm condition number.
- *
- * @return float max(S)/min(S)
- */
- public function cond()
- {
- return $this->s[0] / $this->s[min($this->m, $this->n) - 1];
- }
-
- /**
- * Effective numerical matrix rank.
- *
- * @return int Number of nonnegligible singular values
- */
- public function rank()
- {
- $eps = 2.0 ** (-52.0);
- $tol = max($this->m, $this->n) * $this->s[0] * $eps;
- $r = 0;
- $iMax = count($this->s);
- for ($i = 0; $i < $iMax; ++$i) {
- if ($this->s[$i] > $tol) {
- ++$r;
- }
- }
-
- return $r;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/JAMA/utils/Maths.php b/vendor/PhpSpreadsheet/Shared/JAMA/utils/Maths.php
deleted file mode 100644
index 49877b2..0000000
--- a/vendor/PhpSpreadsheet/Shared/JAMA/utils/Maths.php
+++ /dev/null
@@ -1,31 +0,0 @@
- abs($b)) {
- $r = $b / $a;
- $r = abs($a) * sqrt(1 + $r * $r);
- } elseif ($b != 0) {
- $r = $a / $b;
- $r = abs($b) * sqrt(1 + $r * $r);
- } else {
- $r = 0.0;
- }
-
- return $r;
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLE.php b/vendor/PhpSpreadsheet/Shared/OLE.php
deleted file mode 100644
index d380995..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLE.php
+++ /dev/null
@@ -1,566 +0,0 @@
- |
-// | Based on OLE::Storage_Lite by Kawai, Takanori |
-// +----------------------------------------------------------------------+
-//
-
-use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
-use PhpOffice\PhpSpreadsheet\Shared\OLE\ChainedBlockStream;
-use PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\Root;
-
-/*
- * Array for storing OLE instances that are accessed from
- * OLE_ChainedBlockStream::stream_open().
- *
- * @var array
- */
-$GLOBALS['_OLE_INSTANCES'] = [];
-
-/**
- * OLE package base class.
- *
- * @author Xavier Noguer
- * @author Christian Schmidt
- */
-class OLE
-{
- const OLE_PPS_TYPE_ROOT = 5;
- const OLE_PPS_TYPE_DIR = 1;
- const OLE_PPS_TYPE_FILE = 2;
- const OLE_DATA_SIZE_SMALL = 0x1000;
- const OLE_LONG_INT_SIZE = 4;
- const OLE_PPS_SIZE = 0x80;
-
- /**
- * The file handle for reading an OLE container.
- *
- * @var resource
- */
- public $_file_handle;
-
- /**
- * Array of PPS's found on the OLE container.
- *
- * @var array
- */
- public $_list = [];
-
- /**
- * Root directory of OLE container.
- *
- * @var Root
- */
- public $root;
-
- /**
- * Big Block Allocation Table.
- *
- * @var array (blockId => nextBlockId)
- */
- public $bbat;
-
- /**
- * Short Block Allocation Table.
- *
- * @var array (blockId => nextBlockId)
- */
- public $sbat;
-
- /**
- * Size of big blocks. This is usually 512.
- *
- * @var int number of octets per block
- */
- public $bigBlockSize;
-
- /**
- * Size of small blocks. This is usually 64.
- *
- * @var int number of octets per block
- */
- public $smallBlockSize;
-
- /**
- * Threshold for big blocks.
- *
- * @var int
- */
- public $bigBlockThreshold;
-
- /**
- * Reads an OLE container from the contents of the file given.
- *
- * @acces public
- *
- * @param string $file
- *
- * @return bool true on success, PEAR_Error on failure
- */
- public function read($file)
- {
- $fh = fopen($file, 'rb');
- if (!$fh) {
- throw new ReaderException("Can't open file $file");
- }
- $this->_file_handle = $fh;
-
- $signature = fread($fh, 8);
- if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
- throw new ReaderException("File doesn't seem to be an OLE container.");
- }
- fseek($fh, 28);
- if (fread($fh, 2) != "\xFE\xFF") {
- // This shouldn't be a problem in practice
- throw new ReaderException('Only Little-Endian encoding is supported.');
- }
- // Size of blocks and short blocks in bytes
- $this->bigBlockSize = 2 ** self::readInt2($fh);
- $this->smallBlockSize = 2 ** self::readInt2($fh);
-
- // Skip UID, revision number and version number
- fseek($fh, 44);
- // Number of blocks in Big Block Allocation Table
- $bbatBlockCount = self::readInt4($fh);
-
- // Root chain 1st block
- $directoryFirstBlockId = self::readInt4($fh);
-
- // Skip unused bytes
- fseek($fh, 56);
- // Streams shorter than this are stored using small blocks
- $this->bigBlockThreshold = self::readInt4($fh);
- // Block id of first sector in Short Block Allocation Table
- $sbatFirstBlockId = self::readInt4($fh);
- // Number of blocks in Short Block Allocation Table
- $sbbatBlockCount = self::readInt4($fh);
- // Block id of first sector in Master Block Allocation Table
- $mbatFirstBlockId = self::readInt4($fh);
- // Number of blocks in Master Block Allocation Table
- $mbbatBlockCount = self::readInt4($fh);
- $this->bbat = [];
-
- // Remaining 4 * 109 bytes of current block is beginning of Master
- // Block Allocation Table
- $mbatBlocks = [];
- for ($i = 0; $i < 109; ++$i) {
- $mbatBlocks[] = self::readInt4($fh);
- }
-
- // Read rest of Master Block Allocation Table (if any is left)
- $pos = $this->getBlockOffset($mbatFirstBlockId);
- for ($i = 0; $i < $mbbatBlockCount; ++$i) {
- fseek($fh, $pos);
- for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {
- $mbatBlocks[] = self::readInt4($fh);
- }
- // Last block id in each block points to next block
- $pos = $this->getBlockOffset(self::readInt4($fh));
- }
-
- // Read Big Block Allocation Table according to chain specified by $mbatBlocks
- for ($i = 0; $i < $bbatBlockCount; ++$i) {
- $pos = $this->getBlockOffset($mbatBlocks[$i]);
- fseek($fh, $pos);
- for ($j = 0; $j < $this->bigBlockSize / 4; ++$j) {
- $this->bbat[] = self::readInt4($fh);
- }
- }
-
- // Read short block allocation table (SBAT)
- $this->sbat = [];
- $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
- $sbatFh = $this->getStream($sbatFirstBlockId);
- for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {
- $this->sbat[$blockId] = self::readInt4($sbatFh);
- }
- fclose($sbatFh);
-
- $this->readPpsWks($directoryFirstBlockId);
-
- return true;
- }
-
- /**
- * @param int $blockId byte offset from beginning of file
- *
- * @return int
- */
- public function getBlockOffset($blockId)
- {
- return 512 + $blockId * $this->bigBlockSize;
- }
-
- /**
- * Returns a stream for use with fread() etc. External callers should
- * use \PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\File::getStream().
- *
- * @param int|OLE\PPS $blockIdOrPps block id or PPS
- *
- * @return resource read-only stream
- */
- public function getStream($blockIdOrPps)
- {
- static $isRegistered = false;
- if (!$isRegistered) {
- stream_wrapper_register('ole-chainedblockstream', ChainedBlockStream::class);
- $isRegistered = true;
- }
-
- // Store current instance in global array, so that it can be accessed
- // in OLE_ChainedBlockStream::stream_open().
- // Object is removed from self::$instances in OLE_Stream::close().
- $GLOBALS['_OLE_INSTANCES'][] = $this;
- $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES']));
-
- $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;
- if ($blockIdOrPps instanceof OLE\PPS) {
- $path .= '&blockId=' . $blockIdOrPps->startBlock;
- $path .= '&size=' . $blockIdOrPps->Size;
- } else {
- $path .= '&blockId=' . $blockIdOrPps;
- }
-
- return fopen($path, 'rb');
- }
-
- /**
- * Reads a signed char.
- *
- * @param resource $fh file handle
- *
- * @return int
- */
- private static function readInt1($fh)
- {
- [, $tmp] = unpack('c', fread($fh, 1));
-
- return $tmp;
- }
-
- /**
- * Reads an unsigned short (2 octets).
- *
- * @param resource $fh file handle
- *
- * @return int
- */
- private static function readInt2($fh)
- {
- [, $tmp] = unpack('v', fread($fh, 2));
-
- return $tmp;
- }
-
- /**
- * Reads an unsigned long (4 octets).
- *
- * @param resource $fh file handle
- *
- * @return int
- */
- private static function readInt4($fh)
- {
- [, $tmp] = unpack('V', fread($fh, 4));
-
- return $tmp;
- }
-
- /**
- * Gets information about all PPS's on the OLE container from the PPS WK's
- * creates an OLE_PPS object for each one.
- *
- * @param int $blockId the block id of the first block
- *
- * @return bool true on success, PEAR_Error on failure
- */
- public function readPpsWks($blockId)
- {
- $fh = $this->getStream($blockId);
- for ($pos = 0; true; $pos += 128) {
- fseek($fh, $pos, SEEK_SET);
- $nameUtf16 = fread($fh, 64);
- $nameLength = self::readInt2($fh);
- $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
- // Simple conversion from UTF-16LE to ISO-8859-1
- $name = str_replace("\x00", '', $nameUtf16);
- $type = self::readInt1($fh);
- switch ($type) {
- case self::OLE_PPS_TYPE_ROOT:
- $pps = new OLE\PPS\Root(null, null, []);
- $this->root = $pps;
-
- break;
- case self::OLE_PPS_TYPE_DIR:
- $pps = new OLE\PPS(null, null, null, null, null, null, null, null, null, []);
-
- break;
- case self::OLE_PPS_TYPE_FILE:
- $pps = new OLE\PPS\File($name);
-
- break;
- default:
- break;
- }
- fseek($fh, 1, SEEK_CUR);
- $pps->Type = $type;
- $pps->Name = $name;
- $pps->PrevPps = self::readInt4($fh);
- $pps->NextPps = self::readInt4($fh);
- $pps->DirPps = self::readInt4($fh);
- fseek($fh, 20, SEEK_CUR);
- $pps->Time1st = self::OLE2LocalDate(fread($fh, 8));
- $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8));
- $pps->startBlock = self::readInt4($fh);
- $pps->Size = self::readInt4($fh);
- $pps->No = count($this->_list);
- $this->_list[] = $pps;
-
- // check if the PPS tree (starting from root) is complete
- if (isset($this->root) && $this->ppsTreeComplete($this->root->No)) {
- break;
- }
- }
- fclose($fh);
-
- // Initialize $pps->children on directories
- foreach ($this->_list as $pps) {
- if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) {
- $nos = [$pps->DirPps];
- $pps->children = [];
- while ($nos) {
- $no = array_pop($nos);
- if ($no != -1) {
- $childPps = $this->_list[$no];
- $nos[] = $childPps->PrevPps;
- $nos[] = $childPps->NextPps;
- $pps->children[] = $childPps;
- }
- }
- }
- }
-
- return true;
- }
-
- /**
- * It checks whether the PPS tree is complete (all PPS's read)
- * starting with the given PPS (not necessarily root).
- *
- * @param int $index The index of the PPS from which we are checking
- *
- * @return bool Whether the PPS tree for the given PPS is complete
- */
- private function ppsTreeComplete($index)
- {
- return isset($this->_list[$index]) &&
- ($pps = $this->_list[$index]) &&
- ($pps->PrevPps == -1 ||
- $this->ppsTreeComplete($pps->PrevPps)) &&
- ($pps->NextPps == -1 ||
- $this->ppsTreeComplete($pps->NextPps)) &&
- ($pps->DirPps == -1 ||
- $this->ppsTreeComplete($pps->DirPps));
- }
-
- /**
- * Checks whether a PPS is a File PPS or not.
- * If there is no PPS for the index given, it will return false.
- *
- * @param int $index The index for the PPS
- *
- * @return bool true if it's a File PPS, false otherwise
- */
- public function isFile($index)
- {
- if (isset($this->_list[$index])) {
- return $this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE;
- }
-
- return false;
- }
-
- /**
- * Checks whether a PPS is a Root PPS or not.
- * If there is no PPS for the index given, it will return false.
- *
- * @param int $index the index for the PPS
- *
- * @return bool true if it's a Root PPS, false otherwise
- */
- public function isRoot($index)
- {
- if (isset($this->_list[$index])) {
- return $this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT;
- }
-
- return false;
- }
-
- /**
- * Gives the total number of PPS's found in the OLE container.
- *
- * @return int The total number of PPS's found in the OLE container
- */
- public function ppsTotal()
- {
- return count($this->_list);
- }
-
- /**
- * Gets data from a PPS
- * If there is no PPS for the index given, it will return an empty string.
- *
- * @param int $index The index for the PPS
- * @param int $position The position from which to start reading
- * (relative to the PPS)
- * @param int $length The amount of bytes to read (at most)
- *
- * @return string The binary string containing the data requested
- *
- * @see OLE_PPS_File::getStream()
- */
- public function getData($index, $position, $length)
- {
- // if position is not valid return empty string
- if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) {
- return '';
- }
- $fh = $this->getStream($this->_list[$index]);
- $data = stream_get_contents($fh, $length, $position);
- fclose($fh);
-
- return $data;
- }
-
- /**
- * Gets the data length from a PPS
- * If there is no PPS for the index given, it will return 0.
- *
- * @param int $index The index for the PPS
- *
- * @return int The amount of bytes in data the PPS has
- */
- public function getDataLength($index)
- {
- if (isset($this->_list[$index])) {
- return $this->_list[$index]->Size;
- }
-
- return 0;
- }
-
- /**
- * Utility function to transform ASCII text to Unicode.
- *
- * @param string $ascii The ASCII string to transform
- *
- * @return string The string in Unicode
- */
- public static function ascToUcs($ascii)
- {
- $rawname = '';
- $iMax = strlen($ascii);
- for ($i = 0; $i < $iMax; ++$i) {
- $rawname .= $ascii[$i]
- . "\x00";
- }
-
- return $rawname;
- }
-
- /**
- * Utility function
- * Returns a string for the OLE container with the date given.
- *
- * @param int $date A timestamp
- *
- * @return string The string for the OLE container
- */
- public static function localDateToOLE($date)
- {
- if (!isset($date)) {
- return "\x00\x00\x00\x00\x00\x00\x00\x00";
- }
-
- // factor used for separating numbers into 4 bytes parts
- $factor = 2 ** 32;
-
- // days from 1-1-1601 until the beggining of UNIX era
- $days = 134774;
- // calculate seconds
- $big_date = $days * 24 * 3600 + mktime((int) date('H', $date), (int) date('i', $date), (int) date('s', $date), (int) date('m', $date), (int) date('d', $date), (int) date('Y', $date));
- // multiply just to make MS happy
- $big_date *= 10000000;
-
- $high_part = floor($big_date / $factor);
- // lower 4 bytes
- $low_part = floor((($big_date / $factor) - $high_part) * $factor);
-
- // Make HEX string
- $res = '';
-
- for ($i = 0; $i < 4; ++$i) {
- $hex = $low_part % 0x100;
- $res .= pack('c', $hex);
- $low_part /= 0x100;
- }
- for ($i = 0; $i < 4; ++$i) {
- $hex = $high_part % 0x100;
- $res .= pack('c', $hex);
- $high_part /= 0x100;
- }
-
- return $res;
- }
-
- /**
- * Returns a timestamp from an OLE container's date.
- *
- * @param string $oleTimestamp A binary string with the encoded date
- *
- * @return int The Unix timestamp corresponding to the string
- */
- public static function OLE2LocalDate($oleTimestamp)
- {
- if (strlen($oleTimestamp) != 8) {
- throw new ReaderException('Expecting 8 byte string');
- }
-
- // convert to units of 100 ns since 1601:
- $unpackedTimestamp = unpack('v4', $oleTimestamp);
- $timestampHigh = (float) $unpackedTimestamp[4] * 65536 + (float) $unpackedTimestamp[3];
- $timestampLow = (float) $unpackedTimestamp[2] * 65536 + (float) $unpackedTimestamp[1];
-
- // translate to seconds since 1601:
- $timestampHigh /= 10000000;
- $timestampLow /= 10000000;
-
- // days from 1601 to 1970:
- $days = 134774;
-
- // translate to seconds since 1970:
- $unixTimestamp = floor(65536.0 * 65536.0 * $timestampHigh + $timestampLow - $days * 24 * 3600 + 0.5);
-
- $iTimestamp = (int) $unixTimestamp;
-
- // Overflow conditions can't happen on 64-bit system
- return ($iTimestamp == $unixTimestamp) ? $iTimestamp : ($unixTimestamp >= 0.0 ? PHP_INT_MAX : PHP_INT_MIN);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php b/vendor/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
deleted file mode 100644
index cee5cd9..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
+++ /dev/null
@@ -1,196 +0,0 @@
-params);
- if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) {
- if ($options & STREAM_REPORT_ERRORS) {
- trigger_error('OLE stream not found', E_USER_WARNING);
- }
-
- return false;
- }
- $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']];
-
- $blockId = $this->params['blockId'];
- $this->data = '';
- if (isset($this->params['size']) && $this->params['size'] < $this->ole->bigBlockThreshold && $blockId != $this->ole->root->startBlock) {
- // Block id refers to small blocks
- $rootPos = $this->ole->getBlockOffset($this->ole->root->startBlock);
- while ($blockId != -2) {
- $pos = $rootPos + $blockId * $this->ole->bigBlockSize;
- $blockId = $this->ole->sbat[$blockId];
- fseek($this->ole->_file_handle, $pos);
- $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
- }
- } else {
- // Block id refers to big blocks
- while ($blockId != -2) {
- $pos = $this->ole->getBlockOffset($blockId);
- fseek($this->ole->_file_handle, $pos);
- $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
- $blockId = $this->ole->bbat[$blockId];
- }
- }
- if (isset($this->params['size'])) {
- $this->data = substr($this->data, 0, $this->params['size']);
- }
-
- if ($options & STREAM_USE_PATH) {
- $openedPath = $path;
- }
-
- return true;
- }
-
- /**
- * Implements support for fclose().
- */
- public function stream_close(): void // @codingStandardsIgnoreLine
- {
- $this->ole = null;
- unset($GLOBALS['_OLE_INSTANCES']);
- }
-
- /**
- * Implements support for fread(), fgets() etc.
- *
- * @param int $count maximum number of bytes to read
- *
- * @return string
- */
- public function stream_read($count) // @codingStandardsIgnoreLine
- {
- if ($this->stream_eof()) {
- return false;
- }
- $s = substr($this->data, $this->pos, $count);
- $this->pos += $count;
-
- return $s;
- }
-
- /**
- * Implements support for feof().
- *
- * @return bool TRUE if the file pointer is at EOF; otherwise FALSE
- */
- public function stream_eof() // @codingStandardsIgnoreLine
- {
- return $this->pos >= strlen($this->data);
- }
-
- /**
- * Returns the position of the file pointer, i.e. its offset into the file
- * stream. Implements support for ftell().
- *
- * @return int
- */
- public function stream_tell() // @codingStandardsIgnoreLine
- {
- return $this->pos;
- }
-
- /**
- * Implements support for fseek().
- *
- * @param int $offset byte offset
- * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END
- *
- * @return bool
- */
- public function stream_seek($offset, $whence) // @codingStandardsIgnoreLine
- {
- if ($whence == SEEK_SET && $offset >= 0) {
- $this->pos = $offset;
- } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {
- $this->pos += $offset;
- } elseif ($whence == SEEK_END && -$offset <= count($this->data)) {
- $this->pos = strlen($this->data) + $offset;
- } else {
- return false;
- }
-
- return true;
- }
-
- /**
- * Implements support for fstat(). Currently the only supported field is
- * "size".
- *
- * @return array
- */
- public function stream_stat() // @codingStandardsIgnoreLine
- {
- return [
- 'size' => strlen($this->data),
- ];
- }
-
- // Methods used by stream_wrapper_register() that are not implemented:
- // bool stream_flush ( void )
- // int stream_write ( string data )
- // bool rename ( string path_from, string path_to )
- // bool mkdir ( string path, int mode, int options )
- // bool rmdir ( string path, int options )
- // bool dir_opendir ( string path, int options )
- // array url_stat ( string path, int flags )
- // string dir_readdir ( void )
- // bool dir_rewinddir ( void )
- // bool dir_closedir ( void )
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLE/PPS.php b/vendor/PhpSpreadsheet/Shared/OLE/PPS.php
deleted file mode 100644
index cf764d0..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLE/PPS.php
+++ /dev/null
@@ -1,237 +0,0 @@
- |
-// | Based on OLE::Storage_Lite by Kawai, Takanori |
-// +----------------------------------------------------------------------+
-//
-use PhpOffice\PhpSpreadsheet\Shared\OLE;
-
-/**
- * Class for creating PPS's for OLE containers.
- *
- * @author Xavier Noguer
- */
-class PPS
-{
- /**
- * The PPS index.
- *
- * @var int
- */
- public $No;
-
- /**
- * The PPS name (in Unicode).
- *
- * @var string
- */
- public $Name;
-
- /**
- * The PPS type. Dir, Root or File.
- *
- * @var int
- */
- public $Type;
-
- /**
- * The index of the previous PPS.
- *
- * @var int
- */
- public $PrevPps;
-
- /**
- * The index of the next PPS.
- *
- * @var int
- */
- public $NextPps;
-
- /**
- * The index of it's first child if this is a Dir or Root PPS.
- *
- * @var int
- */
- public $DirPps;
-
- /**
- * A timestamp.
- *
- * @var int
- */
- public $Time1st;
-
- /**
- * A timestamp.
- *
- * @var int
- */
- public $Time2nd;
-
- /**
- * Starting block (small or big) for this PPS's data inside the container.
- *
- * @var int
- */
- public $startBlock;
-
- /**
- * The size of the PPS's data (in bytes).
- *
- * @var int
- */
- public $Size;
-
- /**
- * The PPS's data (only used if it's not using a temporary file).
- *
- * @var string
- */
- public $_data;
-
- /**
- * Array of child PPS's (only used by Root and Dir PPS's).
- *
- * @var array
- */
- public $children = [];
-
- /**
- * Pointer to OLE container.
- *
- * @var OLE
- */
- public $ole;
-
- /**
- * The constructor.
- *
- * @param int $No The PPS index
- * @param string $name The PPS name
- * @param int $type The PPS type. Dir, Root or File
- * @param int $prev The index of the previous PPS
- * @param int $next The index of the next PPS
- * @param int $dir The index of it's first child if this is a Dir or Root PPS
- * @param int $time_1st A timestamp
- * @param int $time_2nd A timestamp
- * @param string $data The (usually binary) source data of the PPS
- * @param array $children Array containing children PPS for this PPS
- */
- public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)
- {
- $this->No = $No;
- $this->Name = $name;
- $this->Type = $type;
- $this->PrevPps = $prev;
- $this->NextPps = $next;
- $this->DirPps = $dir;
- $this->Time1st = $time_1st;
- $this->Time2nd = $time_2nd;
- $this->_data = $data;
- $this->children = $children;
- if ($data != '') {
- $this->Size = strlen($data);
- } else {
- $this->Size = 0;
- }
- }
-
- /**
- * Returns the amount of data saved for this PPS.
- *
- * @return int The amount of data (in bytes)
- */
- public function getDataLen()
- {
- if (!isset($this->_data)) {
- return 0;
- }
-
- return strlen($this->_data);
- }
-
- /**
- * Returns a string with the PPS's WK (What is a WK?).
- *
- * @return string The binary string
- */
- public function getPpsWk()
- {
- $ret = str_pad($this->Name, 64, "\x00");
-
- $ret .= pack('v', strlen($this->Name) + 2) // 66
- . pack('c', $this->Type) // 67
- . pack('c', 0x00) //UK // 68
- . pack('V', $this->PrevPps) //Prev // 72
- . pack('V', $this->NextPps) //Next // 76
- . pack('V', $this->DirPps) //Dir // 80
- . "\x00\x09\x02\x00" // 84
- . "\x00\x00\x00\x00" // 88
- . "\xc0\x00\x00\x00" // 92
- . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root
- . "\x00\x00\x00\x00" // 100
- . OLE::localDateToOLE($this->Time1st) // 108
- . OLE::localDateToOLE($this->Time2nd) // 116
- . pack('V', isset($this->startBlock) ? $this->startBlock : 0) // 120
- . pack('V', $this->Size) // 124
- . pack('V', 0); // 128
-
- return $ret;
- }
-
- /**
- * Updates index and pointers to previous, next and children PPS's for this
- * PPS. I don't think it'll work with Dir PPS's.
- *
- * @param array &$raList Reference to the array of PPS's for the whole OLE
- * container
- * @param mixed $to_save
- * @param mixed $depth
- *
- * @return int The index for this PPS
- */
- public static function savePpsSetPnt(&$raList, $to_save, $depth = 0)
- {
- if (!is_array($to_save) || (empty($to_save))) {
- return 0xFFFFFFFF;
- } elseif (count($to_save) == 1) {
- $cnt = count($raList);
- // If the first entry, it's the root... Don't clone it!
- $raList[$cnt] = ($depth == 0) ? $to_save[0] : clone $to_save[0];
- $raList[$cnt]->No = $cnt;
- $raList[$cnt]->PrevPps = 0xFFFFFFFF;
- $raList[$cnt]->NextPps = 0xFFFFFFFF;
- $raList[$cnt]->DirPps = self::savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
- } else {
- $iPos = floor(count($to_save) / 2);
- $aPrev = array_slice($to_save, 0, $iPos);
- $aNext = array_slice($to_save, $iPos + 1);
- $cnt = count($raList);
- // If the first entry, it's the root... Don't clone it!
- $raList[$cnt] = ($depth == 0) ? $to_save[$iPos] : clone $to_save[$iPos];
- $raList[$cnt]->No = $cnt;
- $raList[$cnt]->PrevPps = self::savePpsSetPnt($raList, $aPrev, $depth++);
- $raList[$cnt]->NextPps = self::savePpsSetPnt($raList, $aNext, $depth++);
- $raList[$cnt]->DirPps = self::savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
- }
-
- return $cnt;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLE/PPS/File.php b/vendor/PhpSpreadsheet/Shared/OLE/PPS/File.php
deleted file mode 100644
index dd1cda2..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLE/PPS/File.php
+++ /dev/null
@@ -1,64 +0,0 @@
- |
-// | Based on OLE::Storage_Lite by Kawai, Takanori |
-// +----------------------------------------------------------------------+
-//
-use PhpOffice\PhpSpreadsheet\Shared\OLE;
-use PhpOffice\PhpSpreadsheet\Shared\OLE\PPS;
-
-/**
- * Class for creating File PPS's for OLE containers.
- *
- * @author Xavier Noguer
- */
-class File extends PPS
-{
- /**
- * The constructor.
- *
- * @param string $name The name of the file (in Unicode)
- *
- * @see OLE::ascToUcs()
- */
- public function __construct($name)
- {
- parent::__construct(null, $name, OLE::OLE_PPS_TYPE_FILE, null, null, null, null, null, '', []);
- }
-
- /**
- * Initialization method. Has to be called right after OLE_PPS_File().
- *
- * @return mixed true on success
- */
- public function init()
- {
- return true;
- }
-
- /**
- * Append data to PPS.
- *
- * @param string $data The data to append
- */
- public function append($data): void
- {
- $this->_data .= $data;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLE/PPS/Root.php b/vendor/PhpSpreadsheet/Shared/OLE/PPS/Root.php
deleted file mode 100644
index 5466d2b..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+++ /dev/null
@@ -1,426 +0,0 @@
- |
-// | Based on OLE::Storage_Lite by Kawai, Takanori |
-// +----------------------------------------------------------------------+
-//
-use PhpOffice\PhpSpreadsheet\Shared\OLE;
-use PhpOffice\PhpSpreadsheet\Shared\OLE\PPS;
-
-/**
- * Class for creating Root PPS's for OLE containers.
- *
- * @author Xavier Noguer
- */
-class Root extends PPS
-{
- /**
- * @var resource
- */
- private $fileHandle;
-
- /**
- * @var int
- */
- private $smallBlockSize;
-
- /**
- * @var int
- */
- private $bigBlockSize;
-
- /**
- * @param int $time_1st A timestamp
- * @param int $time_2nd A timestamp
- * @param File[] $raChild
- */
- public function __construct($time_1st, $time_2nd, $raChild)
- {
- parent::__construct(null, OLE::ascToUcs('Root Entry'), OLE::OLE_PPS_TYPE_ROOT, null, null, null, $time_1st, $time_2nd, null, $raChild);
- }
-
- /**
- * Method for saving the whole OLE container (including files).
- * In fact, if called with an empty argument (or '-'), it saves to a
- * temporary file and then outputs it's contents to stdout.
- * If a resource pointer to a stream created by fopen() is passed
- * it will be used, but you have to close such stream by yourself.
- *
- * @param resource $fileHandle the name of the file or stream where to save the OLE container
- *
- * @return bool true on success
- */
- public function save($fileHandle)
- {
- $this->fileHandle = $fileHandle;
-
- // Initial Setting for saving
- $this->bigBlockSize = 2 ** (
- (isset($this->bigBlockSize)) ? self::adjust2($this->bigBlockSize) : 9
- );
- $this->smallBlockSize = 2 ** (
- (isset($this->smallBlockSize)) ? self::adjust2($this->smallBlockSize) : 6
- );
-
- // Make an array of PPS's (for Save)
- $aList = [];
- PPS::savePpsSetPnt($aList, [$this]);
- // calculate values for header
- [$iSBDcnt, $iBBcnt, $iPPScnt] = $this->calcSize($aList); //, $rhInfo);
- // Save Header
- $this->saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
-
- // Make Small Data string (write SBD)
- $this->_data = $this->makeSmallData($aList);
-
- // Write BB
- $this->saveBigData($iSBDcnt, $aList);
- // Write PPS
- $this->savePps($aList);
- // Write Big Block Depot and BDList and Adding Header informations
- $this->saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
-
- return true;
- }
-
- /**
- * Calculate some numbers.
- *
- * @param array $raList Reference to an array of PPS's
- *
- * @return float[] The array of numbers
- */
- private function calcSize(&$raList)
- {
- // Calculate Basic Setting
- [$iSBDcnt, $iBBcnt, $iPPScnt] = [0, 0, 0];
- $iSmallLen = 0;
- $iSBcnt = 0;
- $iCount = count($raList);
- for ($i = 0; $i < $iCount; ++$i) {
- if ($raList[$i]->Type == OLE::OLE_PPS_TYPE_FILE) {
- $raList[$i]->Size = $raList[$i]->getDataLen();
- if ($raList[$i]->Size < OLE::OLE_DATA_SIZE_SMALL) {
- $iSBcnt += floor($raList[$i]->Size / $this->smallBlockSize)
- + (($raList[$i]->Size % $this->smallBlockSize) ? 1 : 0);
- } else {
- $iBBcnt += (floor($raList[$i]->Size / $this->bigBlockSize) +
- (($raList[$i]->Size % $this->bigBlockSize) ? 1 : 0));
- }
- }
- }
- $iSmallLen = $iSBcnt * $this->smallBlockSize;
- $iSlCnt = floor($this->bigBlockSize / OLE::OLE_LONG_INT_SIZE);
- $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt) ? 1 : 0);
- $iBBcnt += (floor($iSmallLen / $this->bigBlockSize) +
- (($iSmallLen % $this->bigBlockSize) ? 1 : 0));
- $iCnt = count($raList);
- $iBdCnt = $this->bigBlockSize / OLE::OLE_PPS_SIZE;
- $iPPScnt = (floor($iCnt / $iBdCnt) + (($iCnt % $iBdCnt) ? 1 : 0));
-
- return [$iSBDcnt, $iBBcnt, $iPPScnt];
- }
-
- /**
- * Helper function for caculating a magic value for block sizes.
- *
- * @param int $i2 The argument
- *
- * @return float
- *
- * @see save()
- */
- private static function adjust2($i2)
- {
- $iWk = log($i2) / log(2);
-
- return ($iWk > floor($iWk)) ? floor($iWk) + 1 : $iWk;
- }
-
- /**
- * Save OLE header.
- *
- * @param int $iSBDcnt
- * @param int $iBBcnt
- * @param int $iPPScnt
- */
- private function saveHeader($iSBDcnt, $iBBcnt, $iPPScnt): void
- {
- $FILE = $this->fileHandle;
-
- // Calculate Basic Setting
- $iBlCnt = $this->bigBlockSize / OLE::OLE_LONG_INT_SIZE;
- $i1stBdL = ($this->bigBlockSize - 0x4C) / OLE::OLE_LONG_INT_SIZE;
-
- $iBdExL = 0;
- $iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
- $iAllW = $iAll;
- $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt) ? 1 : 0);
- $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW + $iBdCntW) % $iBlCnt) ? 1 : 0);
-
- // Calculate BD count
- if ($iBdCnt > $i1stBdL) {
- while (1) {
- ++$iBdExL;
- ++$iAllW;
- $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt) ? 1 : 0);
- $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW + $iBdCntW) % $iBlCnt) ? 1 : 0);
- if ($iBdCnt <= ($iBdExL * $iBlCnt + $i1stBdL)) {
- break;
- }
- }
- }
-
- // Save Header
- fwrite(
- $FILE,
- "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
- . "\x00\x00\x00\x00"
- . "\x00\x00\x00\x00"
- . "\x00\x00\x00\x00"
- . "\x00\x00\x00\x00"
- . pack('v', 0x3b)
- . pack('v', 0x03)
- . pack('v', -2)
- . pack('v', 9)
- . pack('v', 6)
- . pack('v', 0)
- . "\x00\x00\x00\x00"
- . "\x00\x00\x00\x00"
- . pack('V', $iBdCnt)
- . pack('V', $iBBcnt + $iSBDcnt) //ROOT START
- . pack('V', 0)
- . pack('V', 0x1000)
- . pack('V', $iSBDcnt ? 0 : -2) //Small Block Depot
- . pack('V', $iSBDcnt)
- );
- // Extra BDList Start, Count
- if ($iBdCnt < $i1stBdL) {
- fwrite(
- $FILE,
- pack('V', -2) // Extra BDList Start
- . pack('V', 0)// Extra BDList Count
- );
- } else {
- fwrite($FILE, pack('V', $iAll + $iBdCnt) . pack('V', $iBdExL));
- }
-
- // BDList
- for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) {
- fwrite($FILE, pack('V', $iAll + $i));
- }
- if ($i < $i1stBdL) {
- $jB = $i1stBdL - $i;
- for ($j = 0; $j < $jB; ++$j) {
- fwrite($FILE, (pack('V', -1)));
- }
- }
- }
-
- /**
- * Saving big data (PPS's with data bigger than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
- *
- * @param int $iStBlk
- * @param array &$raList Reference to array of PPS's
- */
- private function saveBigData($iStBlk, &$raList): void
- {
- $FILE = $this->fileHandle;
-
- // cycle through PPS's
- $iCount = count($raList);
- for ($i = 0; $i < $iCount; ++$i) {
- if ($raList[$i]->Type != OLE::OLE_PPS_TYPE_DIR) {
- $raList[$i]->Size = $raList[$i]->getDataLen();
- if (($raList[$i]->Size >= OLE::OLE_DATA_SIZE_SMALL) || (($raList[$i]->Type == OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) {
- fwrite($FILE, $raList[$i]->_data);
-
- if ($raList[$i]->Size % $this->bigBlockSize) {
- fwrite($FILE, str_repeat("\x00", $this->bigBlockSize - ($raList[$i]->Size % $this->bigBlockSize)));
- }
- // Set For PPS
- $raList[$i]->startBlock = $iStBlk;
- $iStBlk +=
- (floor($raList[$i]->Size / $this->bigBlockSize) +
- (($raList[$i]->Size % $this->bigBlockSize) ? 1 : 0));
- }
- }
- }
- }
-
- /**
- * get small data (PPS's with data smaller than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
- *
- * @param array &$raList Reference to array of PPS's
- *
- * @return string
- */
- private function makeSmallData(&$raList)
- {
- $sRes = '';
- $FILE = $this->fileHandle;
- $iSmBlk = 0;
-
- $iCount = count($raList);
- for ($i = 0; $i < $iCount; ++$i) {
- // Make SBD, small data string
- if ($raList[$i]->Type == OLE::OLE_PPS_TYPE_FILE) {
- if ($raList[$i]->Size <= 0) {
- continue;
- }
- if ($raList[$i]->Size < OLE::OLE_DATA_SIZE_SMALL) {
- $iSmbCnt = floor($raList[$i]->Size / $this->smallBlockSize)
- + (($raList[$i]->Size % $this->smallBlockSize) ? 1 : 0);
- // Add to SBD
- $jB = $iSmbCnt - 1;
- for ($j = 0; $j < $jB; ++$j) {
- fwrite($FILE, pack('V', $j + $iSmBlk + 1));
- }
- fwrite($FILE, pack('V', -2));
-
- // Add to Data String(this will be written for RootEntry)
- $sRes .= $raList[$i]->_data;
- if ($raList[$i]->Size % $this->smallBlockSize) {
- $sRes .= str_repeat("\x00", $this->smallBlockSize - ($raList[$i]->Size % $this->smallBlockSize));
- }
- // Set for PPS
- $raList[$i]->startBlock = $iSmBlk;
- $iSmBlk += $iSmbCnt;
- }
- }
- }
- $iSbCnt = floor($this->bigBlockSize / OLE::OLE_LONG_INT_SIZE);
- if ($iSmBlk % $iSbCnt) {
- $iB = $iSbCnt - ($iSmBlk % $iSbCnt);
- for ($i = 0; $i < $iB; ++$i) {
- fwrite($FILE, pack('V', -1));
- }
- }
-
- return $sRes;
- }
-
- /**
- * Saves all the PPS's WKs.
- *
- * @param array $raList Reference to an array with all PPS's
- */
- private function savePps(&$raList): void
- {
- // Save each PPS WK
- $iC = count($raList);
- for ($i = 0; $i < $iC; ++$i) {
- fwrite($this->fileHandle, $raList[$i]->getPpsWk());
- }
- // Adjust for Block
- $iCnt = count($raList);
- $iBCnt = $this->bigBlockSize / OLE::OLE_PPS_SIZE;
- if ($iCnt % $iBCnt) {
- fwrite($this->fileHandle, str_repeat("\x00", ($iBCnt - ($iCnt % $iBCnt)) * OLE::OLE_PPS_SIZE));
- }
- }
-
- /**
- * Saving Big Block Depot.
- *
- * @param int $iSbdSize
- * @param int $iBsize
- * @param int $iPpsCnt
- */
- private function saveBbd($iSbdSize, $iBsize, $iPpsCnt): void
- {
- $FILE = $this->fileHandle;
- // Calculate Basic Setting
- $iBbCnt = $this->bigBlockSize / OLE::OLE_LONG_INT_SIZE;
- $i1stBdL = ($this->bigBlockSize - 0x4C) / OLE::OLE_LONG_INT_SIZE;
-
- $iBdExL = 0;
- $iAll = $iBsize + $iPpsCnt + $iSbdSize;
- $iAllW = $iAll;
- $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt) ? 1 : 0);
- $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW + $iBdCntW) % $iBbCnt) ? 1 : 0);
- // Calculate BD count
- if ($iBdCnt > $i1stBdL) {
- while (1) {
- ++$iBdExL;
- ++$iAllW;
- $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt) ? 1 : 0);
- $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW + $iBdCntW) % $iBbCnt) ? 1 : 0);
- if ($iBdCnt <= ($iBdExL * $iBbCnt + $i1stBdL)) {
- break;
- }
- }
- }
-
- // Making BD
- // Set for SBD
- if ($iSbdSize > 0) {
- for ($i = 0; $i < ($iSbdSize - 1); ++$i) {
- fwrite($FILE, pack('V', $i + 1));
- }
- fwrite($FILE, pack('V', -2));
- }
- // Set for B
- for ($i = 0; $i < ($iBsize - 1); ++$i) {
- fwrite($FILE, pack('V', $i + $iSbdSize + 1));
- }
- fwrite($FILE, pack('V', -2));
-
- // Set for PPS
- for ($i = 0; $i < ($iPpsCnt - 1); ++$i) {
- fwrite($FILE, pack('V', $i + $iSbdSize + $iBsize + 1));
- }
- fwrite($FILE, pack('V', -2));
- // Set for BBD itself ( 0xFFFFFFFD : BBD)
- for ($i = 0; $i < $iBdCnt; ++$i) {
- fwrite($FILE, pack('V', 0xFFFFFFFD));
- }
- // Set for ExtraBDList
- for ($i = 0; $i < $iBdExL; ++$i) {
- fwrite($FILE, pack('V', 0xFFFFFFFC));
- }
- // Adjust for Block
- if (($iAllW + $iBdCnt) % $iBbCnt) {
- $iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt));
- for ($i = 0; $i < $iBlock; ++$i) {
- fwrite($FILE, pack('V', -1));
- }
- }
- // Extra BDList
- if ($iBdCnt > $i1stBdL) {
- $iN = 0;
- $iNb = 0;
- for ($i = $i1stBdL; $i < $iBdCnt; $i++, ++$iN) {
- if ($iN >= ($iBbCnt - 1)) {
- $iN = 0;
- ++$iNb;
- fwrite($FILE, pack('V', $iAll + $iBdCnt + $iNb));
- }
- fwrite($FILE, pack('V', $iBsize + $iSbdSize + $iPpsCnt + $i));
- }
- if (($iBdCnt - $i1stBdL) % ($iBbCnt - 1)) {
- $iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1));
- for ($i = 0; $i < $iB; ++$i) {
- fwrite($FILE, pack('V', -1));
- }
- }
- fwrite($FILE, pack('V', -2));
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/OLERead.php b/vendor/PhpSpreadsheet/Shared/OLERead.php
deleted file mode 100644
index 7112b09..0000000
--- a/vendor/PhpSpreadsheet/Shared/OLERead.php
+++ /dev/null
@@ -1,350 +0,0 @@
-data = file_get_contents($pFilename, false, null, 0, 8);
-
- // Check OLE identifier
- $identifierOle = pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1);
- if ($this->data != $identifierOle) {
- throw new ReaderException('The filename ' . $pFilename . ' is not recognised as an OLE file');
- }
-
- // Get the file data
- $this->data = file_get_contents($pFilename);
-
- // Total number of sectors used for the SAT
- $this->numBigBlockDepotBlocks = self::getInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
-
- // SecID of the first sector of the directory stream
- $this->rootStartBlock = self::getInt4d($this->data, self::ROOT_START_BLOCK_POS);
-
- // SecID of the first sector of the SSAT (or -2 if not extant)
- $this->sbdStartBlock = self::getInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
-
- // SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
- $this->extensionBlock = self::getInt4d($this->data, self::EXTENSION_BLOCK_POS);
-
- // Total number of sectors used by MSAT
- $this->numExtensionBlocks = self::getInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
-
- $bigBlockDepotBlocks = [];
- $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
-
- $bbdBlocks = $this->numBigBlockDepotBlocks;
-
- if ($this->numExtensionBlocks != 0) {
- $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS) / 4;
- }
-
- for ($i = 0; $i < $bbdBlocks; ++$i) {
- $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos);
- $pos += 4;
- }
-
- for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
- $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
- $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
-
- for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
- $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos);
- $pos += 4;
- }
-
- $bbdBlocks += $blocksToRead;
- if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
- $this->extensionBlock = self::getInt4d($this->data, $pos);
- }
- }
-
- $pos = 0;
- $this->bigBlockChain = '';
- $bbs = self::BIG_BLOCK_SIZE / 4;
- for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
- $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
-
- $this->bigBlockChain .= substr($this->data, $pos, 4 * $bbs);
- $pos += 4 * $bbs;
- }
-
- $pos = 0;
- $sbdBlock = $this->sbdStartBlock;
- $this->smallBlockChain = '';
- while ($sbdBlock != -2) {
- $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
-
- $this->smallBlockChain .= substr($this->data, $pos, 4 * $bbs);
- $pos += 4 * $bbs;
-
- $sbdBlock = self::getInt4d($this->bigBlockChain, $sbdBlock * 4);
- }
-
- // read the directory stream
- $block = $this->rootStartBlock;
- $this->entry = $this->readData($block);
-
- $this->readPropertySets();
- }
-
- /**
- * Extract binary stream data.
- *
- * @param int $stream
- *
- * @return string
- */
- public function getStream($stream)
- {
- if ($stream === null) {
- return null;
- }
-
- $streamData = '';
-
- if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {
- $rootdata = $this->readData($this->props[$this->rootentry]['startBlock']);
-
- $block = $this->props[$stream]['startBlock'];
-
- while ($block != -2) {
- $pos = $block * self::SMALL_BLOCK_SIZE;
- $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
-
- $block = self::getInt4d($this->smallBlockChain, $block * 4);
- }
-
- return $streamData;
- }
- $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;
- if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {
- ++$numBlocks;
- }
-
- if ($numBlocks == 0) {
- return '';
- }
-
- $block = $this->props[$stream]['startBlock'];
-
- while ($block != -2) {
- $pos = ($block + 1) * self::BIG_BLOCK_SIZE;
- $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
- $block = self::getInt4d($this->bigBlockChain, $block * 4);
- }
-
- return $streamData;
- }
-
- /**
- * Read a standard stream (by joining sectors using information from SAT).
- *
- * @param int $bl Sector ID where the stream starts
- *
- * @return string Data for standard stream
- */
- private function readData($bl)
- {
- $block = $bl;
- $data = '';
-
- while ($block != -2) {
- $pos = ($block + 1) * self::BIG_BLOCK_SIZE;
- $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
- $block = self::getInt4d($this->bigBlockChain, $block * 4);
- }
-
- return $data;
- }
-
- /**
- * Read entries in the directory stream.
- */
- private function readPropertySets(): void
- {
- $offset = 0;
-
- // loop through entires, each entry is 128 bytes
- $entryLen = strlen($this->entry);
- while ($offset < $entryLen) {
- // entry data (128 bytes)
- $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);
-
- // size in bytes of name
- $nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS + 1]) << 8);
-
- // type of entry
- $type = ord($d[self::TYPE_POS]);
-
- // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook)
- // sectorID of first sector of the short-stream container stream, if this entry is root entry
- $startBlock = self::getInt4d($d, self::START_BLOCK_POS);
-
- $size = self::getInt4d($d, self::SIZE_POS);
-
- $name = str_replace("\x00", '', substr($d, 0, $nameSize));
-
- $this->props[] = [
- 'name' => $name,
- 'type' => $type,
- 'startBlock' => $startBlock,
- 'size' => $size,
- ];
-
- // tmp helper to simplify checks
- $upName = strtoupper($name);
-
- // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook)
- if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) {
- $this->wrkbook = count($this->props) - 1;
- } elseif ($upName === 'ROOT ENTRY' || $upName === 'R') {
- // Root entry
- $this->rootentry = count($this->props) - 1;
- }
-
- // Summary information
- if ($name == chr(5) . 'SummaryInformation') {
- $this->summaryInformation = count($this->props) - 1;
- }
-
- // Additional Document Summary information
- if ($name == chr(5) . 'DocumentSummaryInformation') {
- $this->documentSummaryInformation = count($this->props) - 1;
- }
-
- $offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
- }
- }
-
- /**
- * Read 4 bytes of data at specified position.
- *
- * @param string $data
- * @param int $pos
- *
- * @return int
- */
- private static function getInt4d($data, $pos)
- {
- if ($pos < 0) {
- // Invalid position
- throw new ReaderException('Parameter pos=' . $pos . ' is invalid.');
- }
-
- $len = strlen($data);
- if ($len < $pos + 4) {
- $data .= str_repeat("\0", $pos + 4 - $len);
- }
-
- // FIX: represent numbers correctly on 64-bit system
- // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
- // Changed by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
- $_or_24 = ord($data[$pos + 3]);
- if ($_or_24 >= 128) {
- // negative number
- $_ord_24 = -abs((256 - $_or_24) << 24);
- } else {
- $_ord_24 = ($_or_24 & 127) << 24;
- }
-
- return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/PasswordHasher.php b/vendor/PhpSpreadsheet/Shared/PasswordHasher.php
deleted file mode 100644
index 9fefe88..0000000
--- a/vendor/PhpSpreadsheet/Shared/PasswordHasher.php
+++ /dev/null
@@ -1,100 +0,0 @@
- 'md2',
- Protection::ALGORITHM_MD4 => 'md4',
- Protection::ALGORITHM_MD5 => 'md5',
- Protection::ALGORITHM_SHA_1 => 'sha1',
- Protection::ALGORITHM_SHA_256 => 'sha256',
- Protection::ALGORITHM_SHA_384 => 'sha384',
- Protection::ALGORITHM_SHA_512 => 'sha512',
- Protection::ALGORITHM_RIPEMD_128 => 'ripemd128',
- Protection::ALGORITHM_RIPEMD_160 => 'ripemd160',
- Protection::ALGORITHM_WHIRLPOOL => 'whirlpool',
- ];
-
- if (array_key_exists($algorithmName, $mapping)) {
- return $mapping[$algorithmName];
- }
-
- throw new Exception('Unsupported password algorithm: ' . $algorithmName);
- }
-
- /**
- * Create a password hash from a given string.
- *
- * This method is based on the algorithm provided by
- * Daniel Rentz of OpenOffice and the PEAR package
- * Spreadsheet_Excel_Writer by Xavier Noguer .
- *
- * @param string $pPassword Password to hash
- */
- private static function defaultHashPassword(string $pPassword): string
- {
- $password = 0x0000;
- $charPos = 1; // char position
-
- // split the plain text password in its component characters
- $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY);
- foreach ($chars as $char) {
- $value = ord($char) << $charPos++; // shifted ASCII value
- $rotated_bits = $value >> 15; // rotated bits beyond bit 15
- $value &= 0x7fff; // first 15 bits
- $password ^= ($value | $rotated_bits);
- }
-
- $password ^= strlen($pPassword);
- $password ^= 0xCE4B;
-
- return strtoupper(dechex($password));
- }
-
- /**
- * Create a password hash from a given string by a specific algorithm.
- *
- * 2.4.2.4 ISO Write Protection Method
- *
- * @see https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/1357ea58-646e-4483-92ef-95d718079d6f
- *
- * @param string $password Password to hash
- * @param string $algorithm Hash algorithm used to compute the password hash value
- * @param string $salt Pseudorandom string
- * @param int $spinCount Number of times to iterate on a hash of a password
- *
- * @return string Hashed password
- */
- public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string
- {
- $phpAlgorithm = self::getAlgorithm($algorithm);
- if (!$phpAlgorithm) {
- return self::defaultHashPassword($password);
- }
-
- $saltValue = base64_decode($salt);
- $encodedPassword = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8');
-
- $hashValue = hash($phpAlgorithm, $saltValue . $encodedPassword, true);
- for ($i = 0; $i < $spinCount; ++$i) {
- $hashValue = hash($phpAlgorithm, $hashValue . pack('L', $i), true);
- }
-
- return base64_encode($hashValue);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/StringHelper.php b/vendor/PhpSpreadsheet/Shared/StringHelper.php
deleted file mode 100644
index 9ae3241..0000000
--- a/vendor/PhpSpreadsheet/Shared/StringHelper.php
+++ /dev/null
@@ -1,722 +0,0 @@
- chr(0),
- "\x1B 1" => chr(1),
- "\x1B 2" => chr(2),
- "\x1B 3" => chr(3),
- "\x1B 4" => chr(4),
- "\x1B 5" => chr(5),
- "\x1B 6" => chr(6),
- "\x1B 7" => chr(7),
- "\x1B 8" => chr(8),
- "\x1B 9" => chr(9),
- "\x1B :" => chr(10),
- "\x1B ;" => chr(11),
- "\x1B <" => chr(12),
- "\x1B =" => chr(13),
- "\x1B >" => chr(14),
- "\x1B ?" => chr(15),
- "\x1B!0" => chr(16),
- "\x1B!1" => chr(17),
- "\x1B!2" => chr(18),
- "\x1B!3" => chr(19),
- "\x1B!4" => chr(20),
- "\x1B!5" => chr(21),
- "\x1B!6" => chr(22),
- "\x1B!7" => chr(23),
- "\x1B!8" => chr(24),
- "\x1B!9" => chr(25),
- "\x1B!:" => chr(26),
- "\x1B!;" => chr(27),
- "\x1B!<" => chr(28),
- "\x1B!=" => chr(29),
- "\x1B!>" => chr(30),
- "\x1B!?" => chr(31),
- "\x1B'?" => chr(127),
- "\x1B(0" => '€', // 128 in CP1252
- "\x1B(2" => '‚', // 130 in CP1252
- "\x1B(3" => 'ƒ', // 131 in CP1252
- "\x1B(4" => '„', // 132 in CP1252
- "\x1B(5" => '…', // 133 in CP1252
- "\x1B(6" => '†', // 134 in CP1252
- "\x1B(7" => '‡', // 135 in CP1252
- "\x1B(8" => 'ˆ', // 136 in CP1252
- "\x1B(9" => '‰', // 137 in CP1252
- "\x1B(:" => 'Š', // 138 in CP1252
- "\x1B(;" => '‹', // 139 in CP1252
- "\x1BNj" => 'Œ', // 140 in CP1252
- "\x1B(>" => 'Ž', // 142 in CP1252
- "\x1B)1" => '‘', // 145 in CP1252
- "\x1B)2" => '’', // 146 in CP1252
- "\x1B)3" => '“', // 147 in CP1252
- "\x1B)4" => '”', // 148 in CP1252
- "\x1B)5" => '•', // 149 in CP1252
- "\x1B)6" => '–', // 150 in CP1252
- "\x1B)7" => '—', // 151 in CP1252
- "\x1B)8" => '˜', // 152 in CP1252
- "\x1B)9" => '™', // 153 in CP1252
- "\x1B):" => 'š', // 154 in CP1252
- "\x1B);" => '›', // 155 in CP1252
- "\x1BNz" => 'œ', // 156 in CP1252
- "\x1B)>" => 'ž', // 158 in CP1252
- "\x1B)?" => 'Ÿ', // 159 in CP1252
- "\x1B*0" => ' ', // 160 in CP1252
- "\x1BN!" => '¡', // 161 in CP1252
- "\x1BN\"" => '¢', // 162 in CP1252
- "\x1BN#" => '£', // 163 in CP1252
- "\x1BN(" => '¤', // 164 in CP1252
- "\x1BN%" => '¥', // 165 in CP1252
- "\x1B*6" => '¦', // 166 in CP1252
- "\x1BN'" => '§', // 167 in CP1252
- "\x1BNH " => '¨', // 168 in CP1252
- "\x1BNS" => '©', // 169 in CP1252
- "\x1BNc" => 'ª', // 170 in CP1252
- "\x1BN+" => '«', // 171 in CP1252
- "\x1B*<" => '¬', // 172 in CP1252
- "\x1B*=" => '', // 173 in CP1252
- "\x1BNR" => '®', // 174 in CP1252
- "\x1B*?" => '¯', // 175 in CP1252
- "\x1BN0" => '°', // 176 in CP1252
- "\x1BN1" => '±', // 177 in CP1252
- "\x1BN2" => '²', // 178 in CP1252
- "\x1BN3" => '³', // 179 in CP1252
- "\x1BNB " => '´', // 180 in CP1252
- "\x1BN5" => 'µ', // 181 in CP1252
- "\x1BN6" => '¶', // 182 in CP1252
- "\x1BN7" => '·', // 183 in CP1252
- "\x1B+8" => '¸', // 184 in CP1252
- "\x1BNQ" => '¹', // 185 in CP1252
- "\x1BNk" => 'º', // 186 in CP1252
- "\x1BN;" => '»', // 187 in CP1252
- "\x1BN<" => '¼', // 188 in CP1252
- "\x1BN=" => '½', // 189 in CP1252
- "\x1BN>" => '¾', // 190 in CP1252
- "\x1BN?" => '¿', // 191 in CP1252
- "\x1BNAA" => 'À', // 192 in CP1252
- "\x1BNBA" => 'Á', // 193 in CP1252
- "\x1BNCA" => 'Â', // 194 in CP1252
- "\x1BNDA" => 'Ã', // 195 in CP1252
- "\x1BNHA" => 'Ä', // 196 in CP1252
- "\x1BNJA" => 'Å', // 197 in CP1252
- "\x1BNa" => 'Æ', // 198 in CP1252
- "\x1BNKC" => 'Ç', // 199 in CP1252
- "\x1BNAE" => 'È', // 200 in CP1252
- "\x1BNBE" => 'É', // 201 in CP1252
- "\x1BNCE" => 'Ê', // 202 in CP1252
- "\x1BNHE" => 'Ë', // 203 in CP1252
- "\x1BNAI" => 'Ì', // 204 in CP1252
- "\x1BNBI" => 'Í', // 205 in CP1252
- "\x1BNCI" => 'Î', // 206 in CP1252
- "\x1BNHI" => 'Ï', // 207 in CP1252
- "\x1BNb" => 'Ð', // 208 in CP1252
- "\x1BNDN" => 'Ñ', // 209 in CP1252
- "\x1BNAO" => 'Ò', // 210 in CP1252
- "\x1BNBO" => 'Ó', // 211 in CP1252
- "\x1BNCO" => 'Ô', // 212 in CP1252
- "\x1BNDO" => 'Õ', // 213 in CP1252
- "\x1BNHO" => 'Ö', // 214 in CP1252
- "\x1B-7" => '×', // 215 in CP1252
- "\x1BNi" => 'Ø', // 216 in CP1252
- "\x1BNAU" => 'Ù', // 217 in CP1252
- "\x1BNBU" => 'Ú', // 218 in CP1252
- "\x1BNCU" => 'Û', // 219 in CP1252
- "\x1BNHU" => 'Ü', // 220 in CP1252
- "\x1B-=" => 'Ý', // 221 in CP1252
- "\x1BNl" => 'Þ', // 222 in CP1252
- "\x1BN{" => 'ß', // 223 in CP1252
- "\x1BNAa" => 'à', // 224 in CP1252
- "\x1BNBa" => 'á', // 225 in CP1252
- "\x1BNCa" => 'â', // 226 in CP1252
- "\x1BNDa" => 'ã', // 227 in CP1252
- "\x1BNHa" => 'ä', // 228 in CP1252
- "\x1BNJa" => 'å', // 229 in CP1252
- "\x1BNq" => 'æ', // 230 in CP1252
- "\x1BNKc" => 'ç', // 231 in CP1252
- "\x1BNAe" => 'è', // 232 in CP1252
- "\x1BNBe" => 'é', // 233 in CP1252
- "\x1BNCe" => 'ê', // 234 in CP1252
- "\x1BNHe" => 'ë', // 235 in CP1252
- "\x1BNAi" => 'ì', // 236 in CP1252
- "\x1BNBi" => 'í', // 237 in CP1252
- "\x1BNCi" => 'î', // 238 in CP1252
- "\x1BNHi" => 'ï', // 239 in CP1252
- "\x1BNs" => 'ð', // 240 in CP1252
- "\x1BNDn" => 'ñ', // 241 in CP1252
- "\x1BNAo" => 'ò', // 242 in CP1252
- "\x1BNBo" => 'ó', // 243 in CP1252
- "\x1BNCo" => 'ô', // 244 in CP1252
- "\x1BNDo" => 'õ', // 245 in CP1252
- "\x1BNHo" => 'ö', // 246 in CP1252
- "\x1B/7" => '÷', // 247 in CP1252
- "\x1BNy" => 'ø', // 248 in CP1252
- "\x1BNAu" => 'ù', // 249 in CP1252
- "\x1BNBu" => 'ú', // 250 in CP1252
- "\x1BNCu" => 'û', // 251 in CP1252
- "\x1BNHu" => 'ü', // 252 in CP1252
- "\x1B/=" => 'ý', // 253 in CP1252
- "\x1BN|" => 'þ', // 254 in CP1252
- "\x1BNHy" => 'ÿ', // 255 in CP1252
- ];
- }
-
- /**
- * Get whether iconv extension is available.
- *
- * @return bool
- */
- public static function getIsIconvEnabled()
- {
- if (isset(self::$isIconvEnabled)) {
- return self::$isIconvEnabled;
- }
-
- // Assume no problems with iconv
- self::$isIconvEnabled = true;
-
- // Fail if iconv doesn't exist
- if (!function_exists('iconv')) {
- self::$isIconvEnabled = false;
- } elseif (!@iconv('UTF-8', 'UTF-16LE', 'x')) {
- // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false,
- self::$isIconvEnabled = false;
- } elseif (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) {
- // CUSTOM: IBM AIX iconv() does not work
- self::$isIconvEnabled = false;
- }
-
- // Deactivate iconv default options if they fail (as seen on IMB i)
- if (self::$isIconvEnabled && !@iconv('UTF-8', 'UTF-16LE' . self::$iconvOptions, 'x')) {
- self::$iconvOptions = '';
- }
-
- return self::$isIconvEnabled;
- }
-
- private static function buildCharacterSets(): void
- {
- if (empty(self::$controlCharacters)) {
- self::buildControlCharacters();
- }
-
- if (empty(self::$SYLKCharacters)) {
- self::buildSYLKCharacters();
- }
- }
-
- /**
- * Convert from OpenXML escaped control character to PHP control character.
- *
- * Excel 2007 team:
- * ----------------
- * That's correct, control characters are stored directly in the shared-strings table.
- * We do encode characters that cannot be represented in XML using the following escape sequence:
- * _xHHHH_ where H represents a hexadecimal character in the character's value...
- * So you could end up with something like _x0008_ in a string (either in a cell value ()
- * element or in the shared string element.
- *
- * @param string $value Value to unescape
- *
- * @return string
- */
- public static function controlCharacterOOXML2PHP($value)
- {
- self::buildCharacterSets();
-
- return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $value);
- }
-
- /**
- * Convert from PHP control character to OpenXML escaped control character.
- *
- * Excel 2007 team:
- * ----------------
- * That's correct, control characters are stored directly in the shared-strings table.
- * We do encode characters that cannot be represented in XML using the following escape sequence:
- * _xHHHH_ where H represents a hexadecimal character in the character's value...
- * So you could end up with something like _x0008_ in a string (either in a cell value ()
- * element or in the shared string element.
- *
- * @param string $value Value to escape
- *
- * @return string
- */
- public static function controlCharacterPHP2OOXML($value)
- {
- self::buildCharacterSets();
-
- return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value);
- }
-
- /**
- * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters.
- *
- * @param string $value
- *
- * @return string
- */
- public static function sanitizeUTF8($value)
- {
- if (self::getIsIconvEnabled()) {
- $value = @iconv('UTF-8', 'UTF-8', $value);
-
- return $value;
- }
-
- $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
-
- return $value;
- }
-
- /**
- * Check if a string contains UTF8 data.
- *
- * @param string $value
- *
- * @return bool
- */
- public static function isUTF8($value)
- {
- return $value === '' || preg_match('/^./su', $value) === 1;
- }
-
- /**
- * Formats a numeric value as a string for output in various output writers forcing
- * point as decimal separator in case locale is other than English.
- *
- * @param mixed $value
- *
- * @return string
- */
- public static function formatNumber($value)
- {
- if (is_float($value)) {
- return str_replace(',', '.', $value);
- }
-
- return (string) $value;
- }
-
- /**
- * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length)
- * Writes the string using uncompressed notation, no rich text, no Asian phonetics
- * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
- * although this will give wrong results for non-ASCII strings
- * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
- *
- * @param string $value UTF-8 encoded string
- * @param mixed[] $arrcRuns Details of rich text runs in $value
- *
- * @return string
- */
- public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = [])
- {
- // character count
- $ln = self::countCharacters($value, 'UTF-8');
- // option flags
- if (empty($arrcRuns)) {
- $data = pack('CC', $ln, 0x0001);
- // characters
- $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
- } else {
- $data = pack('vC', $ln, 0x09);
- $data .= pack('v', count($arrcRuns));
- // characters
- $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
- foreach ($arrcRuns as $cRun) {
- $data .= pack('v', $cRun['strlen']);
- $data .= pack('v', $cRun['fontidx']);
- }
- }
-
- return $data;
- }
-
- /**
- * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length)
- * Writes the string using uncompressed notation, no rich text, no Asian phonetics
- * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
- * although this will give wrong results for non-ASCII strings
- * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
- *
- * @param string $value UTF-8 encoded string
- *
- * @return string
- */
- public static function UTF8toBIFF8UnicodeLong($value)
- {
- // character count
- $ln = self::countCharacters($value, 'UTF-8');
-
- // characters
- $chars = self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
-
- return pack('vC', $ln, 0x0001) . $chars;
- }
-
- /**
- * Convert string from one encoding to another.
- *
- * @param string $value
- * @param string $to Encoding to convert to, e.g. 'UTF-8'
- * @param string $from Encoding to convert from, e.g. 'UTF-16LE'
- *
- * @return string
- */
- public static function convertEncoding($value, $to, $from)
- {
- if (self::getIsIconvEnabled()) {
- $result = iconv($from, $to . self::$iconvOptions, $value);
- if (false !== $result) {
- return $result;
- }
- }
-
- return mb_convert_encoding($value, $to, $from);
- }
-
- /**
- * Get character count.
- *
- * @param string $value
- * @param string $enc Encoding
- *
- * @return int Character count
- */
- public static function countCharacters($value, $enc = 'UTF-8')
- {
- return mb_strlen($value, $enc);
- }
-
- /**
- * Get a substring of a UTF-8 encoded string.
- *
- * @param string $pValue UTF-8 encoded string
- * @param int $pStart Start offset
- * @param int $pLength Maximum number of characters in substring
- *
- * @return string
- */
- public static function substring($pValue, $pStart, $pLength = 0)
- {
- return mb_substr($pValue, $pStart, $pLength, 'UTF-8');
- }
-
- /**
- * Convert a UTF-8 encoded string to upper case.
- *
- * @param string $pValue UTF-8 encoded string
- *
- * @return string
- */
- public static function strToUpper($pValue)
- {
- return mb_convert_case($pValue, MB_CASE_UPPER, 'UTF-8');
- }
-
- /**
- * Convert a UTF-8 encoded string to lower case.
- *
- * @param string $pValue UTF-8 encoded string
- *
- * @return string
- */
- public static function strToLower($pValue)
- {
- return mb_convert_case($pValue, MB_CASE_LOWER, 'UTF-8');
- }
-
- /**
- * Convert a UTF-8 encoded string to title/proper case
- * (uppercase every first character in each word, lower case all other characters).
- *
- * @param string $pValue UTF-8 encoded string
- *
- * @return string
- */
- public static function strToTitle($pValue)
- {
- return mb_convert_case($pValue, MB_CASE_TITLE, 'UTF-8');
- }
-
- public static function mbIsUpper($char)
- {
- return mb_strtolower($char, 'UTF-8') != $char;
- }
-
- public static function mbStrSplit($string)
- {
- // Split at all position not after the start: ^
- // and not before the end: $
- return preg_split('/(?_calculateFormulaValue($fractionFormula);
-
- return true;
- }
-
- return false;
- }
-
- // function convertToNumberIfFraction()
-
- /**
- * Get the decimal separator. If it has not yet been set explicitly, try to obtain number
- * formatting information from locale.
- *
- * @return string
- */
- public static function getDecimalSeparator()
- {
- if (!isset(self::$decimalSeparator)) {
- $localeconv = localeconv();
- self::$decimalSeparator = ($localeconv['decimal_point'] != '')
- ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point'];
-
- if (self::$decimalSeparator == '') {
- // Default to .
- self::$decimalSeparator = '.';
- }
- }
-
- return self::$decimalSeparator;
- }
-
- /**
- * Set the decimal separator. Only used by NumberFormat::toFormattedString()
- * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
- *
- * @param string $pValue Character for decimal separator
- */
- public static function setDecimalSeparator($pValue): void
- {
- self::$decimalSeparator = $pValue;
- }
-
- /**
- * Get the thousands separator. If it has not yet been set explicitly, try to obtain number
- * formatting information from locale.
- *
- * @return string
- */
- public static function getThousandsSeparator()
- {
- if (!isset(self::$thousandsSeparator)) {
- $localeconv = localeconv();
- self::$thousandsSeparator = ($localeconv['thousands_sep'] != '')
- ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep'];
-
- if (self::$thousandsSeparator == '') {
- // Default to .
- self::$thousandsSeparator = ',';
- }
- }
-
- return self::$thousandsSeparator;
- }
-
- /**
- * Set the thousands separator. Only used by NumberFormat::toFormattedString()
- * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
- *
- * @param string $pValue Character for thousands separator
- */
- public static function setThousandsSeparator($pValue): void
- {
- self::$thousandsSeparator = $pValue;
- }
-
- /**
- * Get the currency code. If it has not yet been set explicitly, try to obtain the
- * symbol information from locale.
- *
- * @return string
- */
- public static function getCurrencyCode()
- {
- if (!empty(self::$currencyCode)) {
- return self::$currencyCode;
- }
- self::$currencyCode = '$';
- $localeconv = localeconv();
- if (!empty($localeconv['currency_symbol'])) {
- self::$currencyCode = $localeconv['currency_symbol'];
-
- return self::$currencyCode;
- }
- if (!empty($localeconv['int_curr_symbol'])) {
- self::$currencyCode = $localeconv['int_curr_symbol'];
-
- return self::$currencyCode;
- }
-
- return self::$currencyCode;
- }
-
- /**
- * Set the currency code. Only used by NumberFormat::toFormattedString()
- * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
- *
- * @param string $pValue Character for currency code
- */
- public static function setCurrencyCode($pValue): void
- {
- self::$currencyCode = $pValue;
- }
-
- /**
- * Convert SYLK encoded string to UTF-8.
- *
- * @param string $pValue
- *
- * @return string UTF-8 encoded string
- */
- public static function SYLKtoUTF8($pValue)
- {
- self::buildCharacterSets();
-
- // If there is no escape character in the string there is nothing to do
- if (strpos($pValue, '') === false) {
- return $pValue;
- }
-
- foreach (self::$SYLKCharacters as $k => $v) {
- $pValue = str_replace($k, $v, $pValue);
- }
-
- return $pValue;
- }
-
- /**
- * Retrieve any leading numeric part of a string, or return the full string if no leading numeric
- * (handles basic integer or float, but not exponent or non decimal).
- *
- * @param string $value
- *
- * @return mixed string or only the leading numeric part of the string
- */
- public static function testStringAsNumeric($value)
- {
- if (is_numeric($value)) {
- return $value;
- }
- $v = (float) $value;
-
- return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/TimeZone.php b/vendor/PhpSpreadsheet/Shared/TimeZone.php
deleted file mode 100644
index 43fd365..0000000
--- a/vendor/PhpSpreadsheet/Shared/TimeZone.php
+++ /dev/null
@@ -1,81 +0,0 @@
-getTransitions($timestamp, $timestamp);
-
- return (count($transitions) > 0) ? $transitions[0]['offset'] : 0;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/BestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/BestFit.php
deleted file mode 100644
index c949972..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/BestFit.php
+++ /dev/null
@@ -1,463 +0,0 @@
-error;
- }
-
- public function getBestFitType()
- {
- return $this->bestFitType;
- }
-
- /**
- * Return the Y-Value for a specified value of X.
- *
- * @param float $xValue X-Value
- *
- * @return bool Y-Value
- */
- public function getValueOfYForX($xValue)
- {
- return false;
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return bool X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return false;
- }
-
- /**
- * Return the original set of X-Values.
- *
- * @return float[] X-Values
- */
- public function getXValues()
- {
- return $this->xValues;
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return bool
- */
- public function getEquation($dp = 0)
- {
- return false;
- }
-
- /**
- * Return the Slope of the line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getSlope($dp = 0)
- {
- if ($dp != 0) {
- return round($this->slope, $dp);
- }
-
- return $this->slope;
- }
-
- /**
- * Return the standard error of the Slope.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getSlopeSE($dp = 0)
- {
- if ($dp != 0) {
- return round($this->slopeSE, $dp);
- }
-
- return $this->slopeSE;
- }
-
- /**
- * Return the Value of X where it intersects Y = 0.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getIntersect($dp = 0)
- {
- if ($dp != 0) {
- return round($this->intersect, $dp);
- }
-
- return $this->intersect;
- }
-
- /**
- * Return the standard error of the Intersect.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getIntersectSE($dp = 0)
- {
- if ($dp != 0) {
- return round($this->intersectSE, $dp);
- }
-
- return $this->intersectSE;
- }
-
- /**
- * Return the goodness of fit for this regression.
- *
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getGoodnessOfFit($dp = 0)
- {
- if ($dp != 0) {
- return round($this->goodnessOfFit, $dp);
- }
-
- return $this->goodnessOfFit;
- }
-
- /**
- * Return the goodness of fit for this regression.
- *
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getGoodnessOfFitPercent($dp = 0)
- {
- if ($dp != 0) {
- return round($this->goodnessOfFit * 100, $dp);
- }
-
- return $this->goodnessOfFit * 100;
- }
-
- /**
- * Return the standard deviation of the residuals for this regression.
- *
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getStdevOfResiduals($dp = 0)
- {
- if ($dp != 0) {
- return round($this->stdevOfResiduals, $dp);
- }
-
- return $this->stdevOfResiduals;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getSSRegression($dp = 0)
- {
- if ($dp != 0) {
- return round($this->SSRegression, $dp);
- }
-
- return $this->SSRegression;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getSSResiduals($dp = 0)
- {
- if ($dp != 0) {
- return round($this->SSResiduals, $dp);
- }
-
- return $this->SSResiduals;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getDFResiduals($dp = 0)
- {
- if ($dp != 0) {
- return round($this->DFResiduals, $dp);
- }
-
- return $this->DFResiduals;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getF($dp = 0)
- {
- if ($dp != 0) {
- return round($this->f, $dp);
- }
-
- return $this->f;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getCovariance($dp = 0)
- {
- if ($dp != 0) {
- return round($this->covariance, $dp);
- }
-
- return $this->covariance;
- }
-
- /**
- * @param int $dp Number of places of decimal precision to return
- *
- * @return float
- */
- public function getCorrelation($dp = 0)
- {
- if ($dp != 0) {
- return round($this->correlation, $dp);
- }
-
- return $this->correlation;
- }
-
- /**
- * @return float[]
- */
- public function getYBestFitValues()
- {
- return $this->yBestFitValues;
- }
-
- protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const): void
- {
- $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0;
- foreach ($this->xValues as $xKey => $xValue) {
- $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
-
- $SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY);
- if ($const) {
- $SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY);
- } else {
- $SStot += $this->yValues[$xKey] * $this->yValues[$xKey];
- }
- $SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY);
- if ($const) {
- $SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX);
- } else {
- $SSsex += $this->xValues[$xKey] * $this->xValues[$xKey];
- }
- }
-
- $this->SSResiduals = $SSres;
- $this->DFResiduals = $this->valueCount - 1 - $const;
-
- if ($this->DFResiduals == 0.0) {
- $this->stdevOfResiduals = 0.0;
- } else {
- $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals);
- }
- if (($SStot == 0.0) || ($SSres == $SStot)) {
- $this->goodnessOfFit = 1;
- } else {
- $this->goodnessOfFit = 1 - ($SSres / $SStot);
- }
-
- $this->SSRegression = $this->goodnessOfFit * $SStot;
- $this->covariance = $SScov / $this->valueCount;
- $this->correlation = ($this->valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->valueCount * $sumX2 - $sumX ** 2) * ($this->valueCount * $sumY2 - $sumY ** 2));
- $this->slopeSE = $this->stdevOfResiduals / sqrt($SSsex);
- $this->intersectSE = $this->stdevOfResiduals * sqrt(1 / ($this->valueCount - ($sumX * $sumX) / $sumX2));
- if ($this->SSResiduals != 0.0) {
- if ($this->DFResiduals == 0.0) {
- $this->f = 0.0;
- } else {
- $this->f = $this->SSRegression / ($this->SSResiduals / $this->DFResiduals);
- }
- } else {
- if ($this->DFResiduals == 0.0) {
- $this->f = 0.0;
- } else {
- $this->f = $this->SSRegression / $this->DFResiduals;
- }
- }
- }
-
- /**
- * @param float[] $yValues
- * @param float[] $xValues
- * @param bool $const
- */
- protected function leastSquareFit(array $yValues, array $xValues, $const): void
- {
- // calculate sums
- $x_sum = array_sum($xValues);
- $y_sum = array_sum($yValues);
- $meanX = $x_sum / $this->valueCount;
- $meanY = $y_sum / $this->valueCount;
- $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0;
- for ($i = 0; $i < $this->valueCount; ++$i) {
- $xy_sum += $xValues[$i] * $yValues[$i];
- $xx_sum += $xValues[$i] * $xValues[$i];
- $yy_sum += $yValues[$i] * $yValues[$i];
-
- if ($const) {
- $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY);
- $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX);
- } else {
- $mBase += $xValues[$i] * $yValues[$i];
- $mDivisor += $xValues[$i] * $xValues[$i];
- }
- }
-
- // calculate slope
- $this->slope = $mBase / $mDivisor;
-
- // calculate intersect
- if ($const) {
- $this->intersect = $meanY - ($this->slope * $meanX);
- } else {
- $this->intersect = 0;
- }
-
- $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const);
- }
-
- /**
- * Define the regression.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($yValues, $xValues = [], $const = true)
- {
- // Calculate number of points
- $nY = count($yValues);
- $nX = count($xValues);
-
- // Define X Values if necessary
- if ($nX == 0) {
- $xValues = range(1, $nY);
- } elseif ($nY != $nX) {
- // Ensure both arrays of points are the same size
- $this->error = true;
- }
-
- $this->valueCount = $nY;
- $this->xValues = $xValues;
- $this->yValues = $yValues;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php
deleted file mode 100644
index 82866de..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php
+++ /dev/null
@@ -1,122 +0,0 @@
-getIntersect() * $this->getSlope() ** ($xValue - $this->xOffset);
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return float X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return log(($yValue + $this->yOffset) / $this->getIntersect()) / log($this->getSlope());
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getEquation($dp = 0)
- {
- $slope = $this->getSlope($dp);
- $intersect = $this->getIntersect($dp);
-
- return 'Y = ' . $intersect . ' * ' . $slope . '^X';
- }
-
- /**
- * Return the Slope of the line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getSlope($dp = 0)
- {
- if ($dp != 0) {
- return round(exp($this->slope), $dp);
- }
-
- return exp($this->slope);
- }
-
- /**
- * Return the Value of X where it intersects Y = 0.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getIntersect($dp = 0)
- {
- if ($dp != 0) {
- return round(exp($this->intersect), $dp);
- }
-
- return exp($this->intersect);
- }
-
- /**
- * Execute the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- private function exponentialRegression($yValues, $xValues, $const): void
- {
- foreach ($yValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
-
- $this->leastSquareFit($yValues, $xValues, $const);
- }
-
- /**
- * Define the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($yValues, $xValues = [], $const = true)
- {
- parent::__construct($yValues, $xValues);
-
- if (!$this->error) {
- $this->exponentialRegression($yValues, $xValues, $const);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/LinearBestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/LinearBestFit.php
deleted file mode 100644
index 26a562c..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/LinearBestFit.php
+++ /dev/null
@@ -1,81 +0,0 @@
-getIntersect() + $this->getSlope() * $xValue;
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return float X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return ($yValue - $this->getIntersect()) / $this->getSlope();
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getEquation($dp = 0)
- {
- $slope = $this->getSlope($dp);
- $intersect = $this->getIntersect($dp);
-
- return 'Y = ' . $intersect . ' + ' . $slope . ' * X';
- }
-
- /**
- * Execute the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- private function linearRegression($yValues, $xValues, $const): void
- {
- $this->leastSquareFit($yValues, $xValues, $const);
- }
-
- /**
- * Define the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($yValues, $xValues = [], $const = true)
- {
- parent::__construct($yValues, $xValues);
-
- if (!$this->error) {
- $this->linearRegression($yValues, $xValues, $const);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php
deleted file mode 100644
index c469067..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php
+++ /dev/null
@@ -1,90 +0,0 @@
-getIntersect() + $this->getSlope() * log($xValue - $this->xOffset);
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return float X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return exp(($yValue - $this->getIntersect()) / $this->getSlope());
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getEquation($dp = 0)
- {
- $slope = $this->getSlope($dp);
- $intersect = $this->getIntersect($dp);
-
- return 'Y = ' . $intersect . ' + ' . $slope . ' * log(X)';
- }
-
- /**
- * Execute the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- private function logarithmicRegression($yValues, $xValues, $const): void
- {
- foreach ($xValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
-
- $this->leastSquareFit($yValues, $xValues, $const);
- }
-
- /**
- * Define the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($yValues, $xValues = [], $const = true)
- {
- parent::__construct($yValues, $xValues);
-
- if (!$this->error) {
- $this->logarithmicRegression($yValues, $xValues, $const);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
deleted file mode 100644
index d959edd..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
+++ /dev/null
@@ -1,200 +0,0 @@
-order;
- }
-
- /**
- * Return the Y-Value for a specified value of X.
- *
- * @param float $xValue X-Value
- *
- * @return float Y-Value
- */
- public function getValueOfYForX($xValue)
- {
- $retVal = $this->getIntersect();
- $slope = $this->getSlope();
- foreach ($slope as $key => $value) {
- if ($value != 0.0) {
- $retVal += $value * $xValue ** ($key + 1);
- }
- }
-
- return $retVal;
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return float X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return ($yValue - $this->getIntersect()) / $this->getSlope();
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getEquation($dp = 0)
- {
- $slope = $this->getSlope($dp);
- $intersect = $this->getIntersect($dp);
-
- $equation = 'Y = ' . $intersect;
- foreach ($slope as $key => $value) {
- if ($value != 0.0) {
- $equation .= ' + ' . $value . ' * X';
- if ($key > 0) {
- $equation .= '^' . ($key + 1);
- }
- }
- }
-
- return $equation;
- }
-
- /**
- * Return the Slope of the line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getSlope($dp = 0)
- {
- if ($dp != 0) {
- $coefficients = [];
- foreach ($this->slope as $coefficient) {
- $coefficients[] = round($coefficient, $dp);
- }
-
- return $coefficients;
- }
-
- return $this->slope;
- }
-
- public function getCoefficients($dp = 0)
- {
- return array_merge([$this->getIntersect($dp)], $this->getSlope($dp));
- }
-
- /**
- * Execute the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param int $order Order of Polynomial for this regression
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- */
- private function polynomialRegression($order, $yValues, $xValues): void
- {
- // calculate sums
- $x_sum = array_sum($xValues);
- $y_sum = array_sum($yValues);
- $xx_sum = $xy_sum = $yy_sum = 0;
- for ($i = 0; $i < $this->valueCount; ++$i) {
- $xy_sum += $xValues[$i] * $yValues[$i];
- $xx_sum += $xValues[$i] * $xValues[$i];
- $yy_sum += $yValues[$i] * $yValues[$i];
- }
- /*
- * This routine uses logic from the PHP port of polyfit version 0.1
- * written by Michael Bommarito and Paul Meagher
- *
- * The function fits a polynomial function of order $order through
- * a series of x-y data points using least squares.
- *
- */
- $A = [];
- $B = [];
- for ($i = 0; $i < $this->valueCount; ++$i) {
- for ($j = 0; $j <= $order; ++$j) {
- $A[$i][$j] = $xValues[$i] ** $j;
- }
- }
- for ($i = 0; $i < $this->valueCount; ++$i) {
- $B[$i] = [$yValues[$i]];
- }
- $matrixA = new Matrix($A);
- $matrixB = new Matrix($B);
- $C = $matrixA->solve($matrixB);
-
- $coefficients = [];
- for ($i = 0; $i < $C->getRowDimension(); ++$i) {
- $r = $C->get($i, 0);
- if (abs($r) <= 10 ** (-9)) {
- $r = 0;
- }
- $coefficients[] = $r;
- }
-
- $this->intersect = array_shift($coefficients);
- $this->slope = $coefficients;
-
- $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0);
- foreach ($this->xValues as $xKey => $xValue) {
- $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
- }
- }
-
- /**
- * Define the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param int $order Order of Polynomial for this regression
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($order, $yValues, $xValues = [], $const = true)
- {
- parent::__construct($yValues, $xValues);
-
- if (!$this->error) {
- if ($order < $this->valueCount) {
- $this->bestFitType .= '_' . $order;
- $this->order = $order;
- $this->polynomialRegression($order, $yValues, $xValues);
- if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) {
- $this->error = true;
- }
- } else {
- $this->error = true;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/PowerBestFit.php b/vendor/PhpSpreadsheet/Shared/Trend/PowerBestFit.php
deleted file mode 100644
index c53eab6..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/PowerBestFit.php
+++ /dev/null
@@ -1,114 +0,0 @@
-getIntersect() * ($xValue - $this->xOffset) ** $this->getSlope();
- }
-
- /**
- * Return the X-Value for a specified value of Y.
- *
- * @param float $yValue Y-Value
- *
- * @return float X-Value
- */
- public function getValueOfXForY($yValue)
- {
- return (($yValue + $this->yOffset) / $this->getIntersect()) ** (1 / $this->getSlope());
- }
-
- /**
- * Return the Equation of the best-fit line.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return string
- */
- public function getEquation($dp = 0)
- {
- $slope = $this->getSlope($dp);
- $intersect = $this->getIntersect($dp);
-
- return 'Y = ' . $intersect . ' * X^' . $slope;
- }
-
- /**
- * Return the Value of X where it intersects Y = 0.
- *
- * @param int $dp Number of places of decimal precision to display
- *
- * @return float
- */
- public function getIntersect($dp = 0)
- {
- if ($dp != 0) {
- return round(exp($this->intersect), $dp);
- }
-
- return exp($this->intersect);
- }
-
- /**
- * Execute the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- private function powerRegression($yValues, $xValues, $const): void
- {
- foreach ($xValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
- foreach ($yValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
-
- $this->leastSquareFit($yValues, $xValues, $const);
- }
-
- /**
- * Define the regression and calculate the goodness of fit for a set of X and Y data values.
- *
- * @param float[] $yValues The set of Y-values for this regression
- * @param float[] $xValues The set of X-values for this regression
- * @param bool $const
- */
- public function __construct($yValues, $xValues = [], $const = true)
- {
- parent::__construct($yValues, $xValues);
-
- if (!$this->error) {
- $this->powerRegression($yValues, $xValues, $const);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Trend/Trend.php b/vendor/PhpSpreadsheet/Shared/Trend/Trend.php
deleted file mode 100644
index 1b7b390..0000000
--- a/vendor/PhpSpreadsheet/Shared/Trend/Trend.php
+++ /dev/null
@@ -1,120 +0,0 @@
-getGoodnessOfFit();
- }
- if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
- foreach (self::$trendTypePolynomialOrders as $trendMethod) {
- $order = substr($trendMethod, -1);
- $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues, $const);
- if ($bestFit[$trendMethod]->getError()) {
- unset($bestFit[$trendMethod]);
- } else {
- $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
- }
- }
- }
- // Determine which of our Trend lines is the best fit, and then we return the instance of that Trend class
- arsort($bestFitValue);
- $bestFitType = key($bestFitValue);
-
- return $bestFit[$bestFitType];
- default:
- return false;
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/XMLWriter.php b/vendor/PhpSpreadsheet/Shared/XMLWriter.php
deleted file mode 100644
index 4f7a6a0..0000000
--- a/vendor/PhpSpreadsheet/Shared/XMLWriter.php
+++ /dev/null
@@ -1,92 +0,0 @@
-openMemory();
- } else {
- // Create temporary filename
- if ($pTemporaryStorageFolder === null) {
- $pTemporaryStorageFolder = File::sysGetTempDir();
- }
- $this->tempFileName = @tempnam($pTemporaryStorageFolder, 'xml');
-
- // Open storage
- if ($this->openUri($this->tempFileName) === false) {
- // Fallback to memory...
- $this->openMemory();
- }
- }
-
- // Set default values
- if (self::$debugEnabled) {
- $this->setIndent(true);
- }
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- // Unlink temporary files
- if ($this->tempFileName != '') {
- @unlink($this->tempFileName);
- }
- }
-
- /**
- * Get written data.
- *
- * @return string
- */
- public function getData()
- {
- if ($this->tempFileName == '') {
- return $this->outputMemory(true);
- }
- $this->flush();
-
- return file_get_contents($this->tempFileName);
- }
-
- /**
- * Wrapper method for writeRaw.
- *
- * @param string|string[] $text
- *
- * @return bool
- */
- public function writeRawData($text)
- {
- if (is_array($text)) {
- $text = implode("\n", $text);
- }
-
- return $this->writeRaw(htmlspecialchars($text));
- }
-}
diff --git a/vendor/PhpSpreadsheet/Shared/Xls.php b/vendor/PhpSpreadsheet/Shared/Xls.php
deleted file mode 100644
index c9eaf37..0000000
--- a/vendor/PhpSpreadsheet/Shared/Xls.php
+++ /dev/null
@@ -1,279 +0,0 @@
-getParent()->getDefaultStyle()->getFont();
-
- $columnDimensions = $sheet->getColumnDimensions();
-
- // first find the true column width in pixels (uncollapsed and unhidden)
- if (isset($columnDimensions[$col]) && $columnDimensions[$col]->getWidth() != -1) {
- // then we have column dimension with explicit width
- $columnDimension = $columnDimensions[$col];
- $width = $columnDimension->getWidth();
- $pixelWidth = Drawing::cellDimensionToPixels($width, $font);
- } elseif ($sheet->getDefaultColumnDimension()->getWidth() != -1) {
- // then we have default column dimension with explicit width
- $defaultColumnDimension = $sheet->getDefaultColumnDimension();
- $width = $defaultColumnDimension->getWidth();
- $pixelWidth = Drawing::cellDimensionToPixels($width, $font);
- } else {
- // we don't even have any default column dimension. Width depends on default font
- $pixelWidth = Font::getDefaultColumnWidthByFont($font, true);
- }
-
- // now find the effective column width in pixels
- if (isset($columnDimensions[$col]) && !$columnDimensions[$col]->getVisible()) {
- $effectivePixelWidth = 0;
- } else {
- $effectivePixelWidth = $pixelWidth;
- }
-
- return $effectivePixelWidth;
- }
-
- /**
- * Convert the height of a cell from user's units to pixels. By interpolation
- * the relationship is: y = 4/3x. If the height hasn't been set by the user we
- * use the default value. If the row is hidden we use a value of zero.
- *
- * @param Worksheet $sheet The sheet
- * @param int $row The row index (1-based)
- *
- * @return int The width in pixels
- */
- public static function sizeRow($sheet, $row = 1)
- {
- // default font of the workbook
- $font = $sheet->getParent()->getDefaultStyle()->getFont();
-
- $rowDimensions = $sheet->getRowDimensions();
-
- // first find the true row height in pixels (uncollapsed and unhidden)
- if (isset($rowDimensions[$row]) && $rowDimensions[$row]->getRowHeight() != -1) {
- // then we have a row dimension
- $rowDimension = $rowDimensions[$row];
- $rowHeight = $rowDimension->getRowHeight();
- $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10
- } elseif ($sheet->getDefaultRowDimension()->getRowHeight() != -1) {
- // then we have a default row dimension with explicit height
- $defaultRowDimension = $sheet->getDefaultRowDimension();
- $rowHeight = $defaultRowDimension->getRowHeight();
- $pixelRowHeight = Drawing::pointsToPixels($rowHeight);
- } else {
- // we don't even have any default row dimension. Height depends on default font
- $pointRowHeight = Font::getDefaultRowHeightByFont($font);
- $pixelRowHeight = Font::fontSizeToPixels($pointRowHeight);
- }
-
- // now find the effective row height in pixels
- if (isset($rowDimensions[$row]) && !$rowDimensions[$row]->getVisible()) {
- $effectivePixelRowHeight = 0;
- } else {
- $effectivePixelRowHeight = $pixelRowHeight;
- }
-
- return $effectivePixelRowHeight;
- }
-
- /**
- * Get the horizontal distance in pixels between two anchors
- * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets.
- *
- * @param string $startColumn
- * @param int $startOffsetX Offset within start cell measured in 1/1024 of the cell width
- * @param string $endColumn
- * @param int $endOffsetX Offset within end cell measured in 1/1024 of the cell width
- *
- * @return int Horizontal measured in pixels
- */
- public static function getDistanceX(Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0)
- {
- $distanceX = 0;
-
- // add the widths of the spanning columns
- $startColumnIndex = Coordinate::columnIndexFromString($startColumn);
- $endColumnIndex = Coordinate::columnIndexFromString($endColumn);
- for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) {
- $distanceX += self::sizeCol($sheet, Coordinate::stringFromColumnIndex($i));
- }
-
- // correct for offsetX in startcell
- $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024);
-
- // correct for offsetX in endcell
- $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024));
-
- return $distanceX;
- }
-
- /**
- * Get the vertical distance in pixels between two anchors
- * The distanceY is found as sum of all the spanning rows minus two offsets.
- *
- * @param int $startRow (1-based)
- * @param int $startOffsetY Offset within start cell measured in 1/256 of the cell height
- * @param int $endRow (1-based)
- * @param int $endOffsetY Offset within end cell measured in 1/256 of the cell height
- *
- * @return int Vertical distance measured in pixels
- */
- public static function getDistanceY(Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0)
- {
- $distanceY = 0;
-
- // add the widths of the spanning rows
- for ($row = $startRow; $row <= $endRow; ++$row) {
- $distanceY += self::sizeRow($sheet, $row);
- }
-
- // correct for offsetX in startcell
- $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256);
-
- // correct for offsetX in endcell
- $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256));
-
- return $distanceY;
- }
-
- /**
- * Convert 1-cell anchor coordinates to 2-cell anchor coordinates
- * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications.
- *
- * Calculate the vertices that define the position of the image as required by
- * the OBJ record.
- *
- * +------------+------------+
- * | A | B |
- * +-----+------------+------------+
- * | |(x1,y1) | |
- * | 1 |(A1)._______|______ |
- * | | | | |
- * | | | | |
- * +-----+----| BITMAP |-----+
- * | | | | |
- * | 2 | |______________. |
- * | | | (B2)|
- * | | | (x2,y2)|
- * +---- +------------+------------+
- *
- * Example of a bitmap that covers some of the area from cell A1 to cell B2.
- *
- * Based on the width and height of the bitmap we need to calculate 8 vars:
- * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.
- * The width and height of the cells are also variable and have to be taken into
- * account.
- * The values of $col_start and $row_start are passed in from the calling
- * function. The values of $col_end and $row_end are calculated by subtracting
- * the width and height of the bitmap from the width and height of the
- * underlying cells.
- * The vertices are expressed as a percentage of the underlying cell width as
- * follows (rhs values are in pixels):
- *
- * x1 = X / W *1024
- * y1 = Y / H *256
- * x2 = (X-1) / W *1024
- * y2 = (Y-1) / H *256
- *
- * Where: X is distance from the left side of the underlying cell
- * Y is distance from the top of the underlying cell
- * W is the width of the cell
- * H is the height of the cell
- *
- * @param Worksheet $sheet
- * @param string $coordinates E.g. 'A1'
- * @param int $offsetX Horizontal offset in pixels
- * @param int $offsetY Vertical offset in pixels
- * @param int $width Width in pixels
- * @param int $height Height in pixels
- *
- * @return array
- */
- public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
- {
- [$column, $row] = Coordinate::coordinateFromString($coordinates);
- $col_start = Coordinate::columnIndexFromString($column);
- $row_start = $row - 1;
-
- $x1 = $offsetX;
- $y1 = $offsetY;
-
- // Initialise end cell to the same as the start cell
- $col_end = $col_start; // Col containing lower right corner of object
- $row_end = $row_start; // Row containing bottom right corner of object
-
- // Zero the specified offset if greater than the cell dimensions
- if ($x1 >= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start))) {
- $x1 = 0;
- }
- if ($y1 >= self::sizeRow($sheet, $row_start + 1)) {
- $y1 = 0;
- }
-
- $width = $width + $x1 - 1;
- $height = $height + $y1 - 1;
-
- // Subtract the underlying cell widths to find the end cell of the image
- while ($width >= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end))) {
- $width -= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end));
- ++$col_end;
- }
-
- // Subtract the underlying cell heights to find the end cell of the image
- while ($height >= self::sizeRow($sheet, $row_end + 1)) {
- $height -= self::sizeRow($sheet, $row_end + 1);
- ++$row_end;
- }
-
- // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
- // with zero height or width.
- if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start)) == 0) {
- return;
- }
- if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end)) == 0) {
- return;
- }
- if (self::sizeRow($sheet, $row_start + 1) == 0) {
- return;
- }
- if (self::sizeRow($sheet, $row_end + 1) == 0) {
- return;
- }
-
- // Convert the pixel values to the percentage value expected by Excel
- $x1 = $x1 / self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start)) * 1024;
- $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256;
- $x2 = ($width + 1) / self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object
- $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object
-
- $startCoordinates = Coordinate::stringFromColumnIndex($col_start) . ($row_start + 1);
- $endCoordinates = Coordinate::stringFromColumnIndex($col_end) . ($row_end + 1);
-
- return [
- 'startCoordinates' => $startCoordinates,
- 'startOffsetX' => $x1,
- 'startOffsetY' => $y1,
- 'endCoordinates' => $endCoordinates,
- 'endOffsetX' => $x2,
- 'endOffsetY' => $y2,
- ];
- }
-}
diff --git a/vendor/PhpSpreadsheet/Spreadsheet.php b/vendor/PhpSpreadsheet/Spreadsheet.php
deleted file mode 100644
index 19c1152..0000000
--- a/vendor/PhpSpreadsheet/Spreadsheet.php
+++ /dev/null
@@ -1,1591 +0,0 @@
-hasMacros;
- }
-
- /**
- * Define if a workbook has macros.
- *
- * @param bool $hasMacros true|false
- */
- public function setHasMacros($hasMacros): void
- {
- $this->hasMacros = (bool) $hasMacros;
- }
-
- /**
- * Set the macros code.
- *
- * @param string $macroCode string|null
- */
- public function setMacrosCode($macroCode): void
- {
- $this->macrosCode = $macroCode;
- $this->setHasMacros($macroCode !== null);
- }
-
- /**
- * Return the macros code.
- *
- * @return null|string
- */
- public function getMacrosCode()
- {
- return $this->macrosCode;
- }
-
- /**
- * Set the macros certificate.
- *
- * @param null|string $certificate
- */
- public function setMacrosCertificate($certificate): void
- {
- $this->macrosCertificate = $certificate;
- }
-
- /**
- * Is the project signed ?
- *
- * @return bool true|false
- */
- public function hasMacrosCertificate()
- {
- return $this->macrosCertificate !== null;
- }
-
- /**
- * Return the macros certificate.
- *
- * @return null|string
- */
- public function getMacrosCertificate()
- {
- return $this->macrosCertificate;
- }
-
- /**
- * Remove all macros, certificate from spreadsheet.
- */
- public function discardMacros(): void
- {
- $this->hasMacros = false;
- $this->macrosCode = null;
- $this->macrosCertificate = null;
- }
-
- /**
- * set ribbon XML data.
- *
- * @param null|mixed $target
- * @param null|mixed $xmlData
- */
- public function setRibbonXMLData($target, $xmlData): void
- {
- if ($target !== null && $xmlData !== null) {
- $this->ribbonXMLData = ['target' => $target, 'data' => $xmlData];
- } else {
- $this->ribbonXMLData = null;
- }
- }
-
- /**
- * retrieve ribbon XML Data.
- *
- * return string|null|array
- *
- * @param string $what
- *
- * @return string
- */
- public function getRibbonXMLData($what = 'all') //we need some constants here...
- {
- $returnData = null;
- $what = strtolower($what);
- switch ($what) {
- case 'all':
- $returnData = $this->ribbonXMLData;
-
- break;
- case 'target':
- case 'data':
- if (is_array($this->ribbonXMLData) && isset($this->ribbonXMLData[$what])) {
- $returnData = $this->ribbonXMLData[$what];
- }
-
- break;
- }
-
- return $returnData;
- }
-
- /**
- * store binaries ribbon objects (pictures).
- *
- * @param null|mixed $BinObjectsNames
- * @param null|mixed $BinObjectsData
- */
- public function setRibbonBinObjects($BinObjectsNames, $BinObjectsData): void
- {
- if ($BinObjectsNames !== null && $BinObjectsData !== null) {
- $this->ribbonBinObjects = ['names' => $BinObjectsNames, 'data' => $BinObjectsData];
- } else {
- $this->ribbonBinObjects = null;
- }
- }
-
- /**
- * List of unparsed loaded data for export to same format with better compatibility.
- * It has to be minimized when the library start to support currently unparsed data.
- *
- * @internal
- *
- * @return array
- */
- public function getUnparsedLoadedData()
- {
- return $this->unparsedLoadedData;
- }
-
- /**
- * List of unparsed loaded data for export to same format with better compatibility.
- * It has to be minimized when the library start to support currently unparsed data.
- *
- * @internal
- */
- public function setUnparsedLoadedData(array $unparsedLoadedData): void
- {
- $this->unparsedLoadedData = $unparsedLoadedData;
- }
-
- /**
- * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function).
- *
- * @param mixed $path
- *
- * @return string
- */
- private function getExtensionOnly($path)
- {
- return pathinfo($path, PATHINFO_EXTENSION);
- }
-
- /**
- * retrieve Binaries Ribbon Objects.
- *
- * @param string $what
- *
- * @return null|array
- */
- public function getRibbonBinObjects($what = 'all')
- {
- $ReturnData = null;
- $what = strtolower($what);
- switch ($what) {
- case 'all':
- return $this->ribbonBinObjects;
-
- break;
- case 'names':
- case 'data':
- if (is_array($this->ribbonBinObjects) && isset($this->ribbonBinObjects[$what])) {
- $ReturnData = $this->ribbonBinObjects[$what];
- }
-
- break;
- case 'types':
- if (
- is_array($this->ribbonBinObjects) &&
- isset($this->ribbonBinObjects['data']) && is_array($this->ribbonBinObjects['data'])
- ) {
- $tmpTypes = array_keys($this->ribbonBinObjects['data']);
- $ReturnData = array_unique(array_map([$this, 'getExtensionOnly'], $tmpTypes));
- } else {
- $ReturnData = []; // the caller want an array... not null if empty
- }
-
- break;
- }
-
- return $ReturnData;
- }
-
- /**
- * This workbook have a custom UI ?
- *
- * @return bool
- */
- public function hasRibbon()
- {
- return $this->ribbonXMLData !== null;
- }
-
- /**
- * This workbook have additionnal object for the ribbon ?
- *
- * @return bool
- */
- public function hasRibbonBinObjects()
- {
- return $this->ribbonBinObjects !== null;
- }
-
- /**
- * Check if a sheet with a specified code name already exists.
- *
- * @param string $pSheetCodeName Name of the worksheet to check
- *
- * @return bool
- */
- public function sheetCodeNameExists($pSheetCodeName)
- {
- return $this->getSheetByCodeName($pSheetCodeName) !== null;
- }
-
- /**
- * Get sheet by code name. Warning : sheet don't have always a code name !
- *
- * @param string $pName Sheet name
- *
- * @return Worksheet
- */
- public function getSheetByCodeName($pName)
- {
- $worksheetCount = count($this->workSheetCollection);
- for ($i = 0; $i < $worksheetCount; ++$i) {
- if ($this->workSheetCollection[$i]->getCodeName() == $pName) {
- return $this->workSheetCollection[$i];
- }
- }
-
- return null;
- }
-
- /**
- * Create a new PhpSpreadsheet with one Worksheet.
- */
- public function __construct()
- {
- $this->uniqueID = uniqid('', true);
- $this->calculationEngine = new Calculation($this);
-
- // Initialise worksheet collection and add one worksheet
- $this->workSheetCollection = [];
- $this->workSheetCollection[] = new Worksheet($this);
- $this->activeSheetIndex = 0;
-
- // Create document properties
- $this->properties = new Document\Properties();
-
- // Create document security
- $this->security = new Document\Security();
-
- // Set defined names
- $this->definedNames = [];
-
- // Create the cellXf supervisor
- $this->cellXfSupervisor = new Style(true);
- $this->cellXfSupervisor->bindParent($this);
-
- // Create the default style
- $this->addCellXf(new Style());
- $this->addCellStyleXf(new Style());
- }
-
- /**
- * Code to execute when this worksheet is unset().
- */
- public function __destruct()
- {
- $this->calculationEngine = null;
- $this->disconnectWorksheets();
- }
-
- /**
- * Disconnect all worksheets from this PhpSpreadsheet workbook object,
- * typically so that the PhpSpreadsheet object can be unset.
- */
- public function disconnectWorksheets(): void
- {
- $worksheet = null;
- foreach ($this->workSheetCollection as $k => &$worksheet) {
- $worksheet->disconnectCells();
- $this->workSheetCollection[$k] = null;
- }
- unset($worksheet);
- $this->workSheetCollection = [];
- }
-
- /**
- * Return the calculation engine for this worksheet.
- *
- * @return Calculation
- */
- public function getCalculationEngine()
- {
- return $this->calculationEngine;
- }
-
- /**
- * Get properties.
- *
- * @return Document\Properties
- */
- public function getProperties()
- {
- return $this->properties;
- }
-
- /**
- * Set properties.
- */
- public function setProperties(Document\Properties $pValue): void
- {
- $this->properties = $pValue;
- }
-
- /**
- * Get security.
- *
- * @return Document\Security
- */
- public function getSecurity()
- {
- return $this->security;
- }
-
- /**
- * Set security.
- */
- public function setSecurity(Document\Security $pValue): void
- {
- $this->security = $pValue;
- }
-
- /**
- * Get active sheet.
- *
- * @return Worksheet
- */
- public function getActiveSheet()
- {
- return $this->getSheet($this->activeSheetIndex);
- }
-
- /**
- * Create sheet and add it to this workbook.
- *
- * @param null|int $sheetIndex Index where sheet should go (0,1,..., or null for last)
- *
- * @return Worksheet
- */
- public function createSheet($sheetIndex = null)
- {
- $newSheet = new Worksheet($this);
- $this->addSheet($newSheet, $sheetIndex);
-
- return $newSheet;
- }
-
- /**
- * Check if a sheet with a specified name already exists.
- *
- * @param string $pSheetName Name of the worksheet to check
- *
- * @return bool
- */
- public function sheetNameExists($pSheetName)
- {
- return $this->getSheetByName($pSheetName) !== null;
- }
-
- /**
- * Add sheet.
- *
- * @param null|int $iSheetIndex Index where sheet should go (0,1,..., or null for last)
- *
- * @return Worksheet
- */
- public function addSheet(Worksheet $pSheet, $iSheetIndex = null)
- {
- if ($this->sheetNameExists($pSheet->getTitle())) {
- throw new Exception(
- "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
- );
- }
-
- if ($iSheetIndex === null) {
- if ($this->activeSheetIndex < 0) {
- $this->activeSheetIndex = 0;
- }
- $this->workSheetCollection[] = $pSheet;
- } else {
- // Insert the sheet at the requested index
- array_splice(
- $this->workSheetCollection,
- $iSheetIndex,
- 0,
- [$pSheet]
- );
-
- // Adjust active sheet index if necessary
- if ($this->activeSheetIndex >= $iSheetIndex) {
- ++$this->activeSheetIndex;
- }
- }
-
- if ($pSheet->getParent() === null) {
- $pSheet->rebindParent($this);
- }
-
- return $pSheet;
- }
-
- /**
- * Remove sheet by index.
- *
- * @param int $pIndex Active sheet index
- */
- public function removeSheetByIndex($pIndex): void
- {
- $numSheets = count($this->workSheetCollection);
- if ($pIndex > $numSheets - 1) {
- throw new Exception(
- "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
- );
- }
- array_splice($this->workSheetCollection, $pIndex, 1);
-
- // Adjust active sheet index if necessary
- if (
- ($this->activeSheetIndex >= $pIndex) &&
- ($pIndex > count($this->workSheetCollection) - 1)
- ) {
- --$this->activeSheetIndex;
- }
- }
-
- /**
- * Get sheet by index.
- *
- * @param int $pIndex Sheet index
- *
- * @return Worksheet
- */
- public function getSheet($pIndex)
- {
- if (!isset($this->workSheetCollection[$pIndex])) {
- $numSheets = $this->getSheetCount();
-
- throw new Exception(
- "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}."
- );
- }
-
- return $this->workSheetCollection[$pIndex];
- }
-
- /**
- * Get all sheets.
- *
- * @return Worksheet[]
- */
- public function getAllSheets()
- {
- return $this->workSheetCollection;
- }
-
- /**
- * Get sheet by name.
- *
- * @param string $pName Sheet name
- *
- * @return null|Worksheet
- */
- public function getSheetByName($pName)
- {
- $worksheetCount = count($this->workSheetCollection);
- for ($i = 0; $i < $worksheetCount; ++$i) {
- if ($this->workSheetCollection[$i]->getTitle() === trim($pName, "'")) {
- return $this->workSheetCollection[$i];
- }
- }
-
- return null;
- }
-
- /**
- * Get index for sheet.
- *
- * @return int index
- */
- public function getIndex(Worksheet $pSheet)
- {
- foreach ($this->workSheetCollection as $key => $value) {
- if ($value->getHashCode() === $pSheet->getHashCode()) {
- return $key;
- }
- }
-
- throw new Exception('Sheet does not exist.');
- }
-
- /**
- * Set index for sheet by sheet name.
- *
- * @param string $sheetName Sheet name to modify index for
- * @param int $newIndex New index for the sheet
- *
- * @return int New sheet index
- */
- public function setIndexByName($sheetName, $newIndex)
- {
- $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
- $pSheet = array_splice(
- $this->workSheetCollection,
- $oldIndex,
- 1
- );
- array_splice(
- $this->workSheetCollection,
- $newIndex,
- 0,
- $pSheet
- );
-
- return $newIndex;
- }
-
- /**
- * Get sheet count.
- *
- * @return int
- */
- public function getSheetCount()
- {
- return count($this->workSheetCollection);
- }
-
- /**
- * Get active sheet index.
- *
- * @return int Active sheet index
- */
- public function getActiveSheetIndex()
- {
- return $this->activeSheetIndex;
- }
-
- /**
- * Set active sheet index.
- *
- * @param int $pIndex Active sheet index
- *
- * @return Worksheet
- */
- public function setActiveSheetIndex($pIndex)
- {
- $numSheets = count($this->workSheetCollection);
-
- if ($pIndex > $numSheets - 1) {
- throw new Exception(
- "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
- );
- }
- $this->activeSheetIndex = $pIndex;
-
- return $this->getActiveSheet();
- }
-
- /**
- * Set active sheet index by name.
- *
- * @param string $pValue Sheet title
- *
- * @return Worksheet
- */
- public function setActiveSheetIndexByName($pValue)
- {
- if (($worksheet = $this->getSheetByName($pValue)) instanceof Worksheet) {
- $this->setActiveSheetIndex($this->getIndex($worksheet));
-
- return $worksheet;
- }
-
- throw new Exception('Workbook does not contain sheet:' . $pValue);
- }
-
- /**
- * Get sheet names.
- *
- * @return string[]
- */
- public function getSheetNames()
- {
- $returnValue = [];
- $worksheetCount = $this->getSheetCount();
- for ($i = 0; $i < $worksheetCount; ++$i) {
- $returnValue[] = $this->getSheet($i)->getTitle();
- }
-
- return $returnValue;
- }
-
- /**
- * Add external sheet.
- *
- * @param Worksheet $pSheet External sheet to add
- * @param null|int $iSheetIndex Index where sheet should go (0,1,..., or null for last)
- *
- * @return Worksheet
- */
- public function addExternalSheet(Worksheet $pSheet, $iSheetIndex = null)
- {
- if ($this->sheetNameExists($pSheet->getTitle())) {
- throw new Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
- }
-
- // count how many cellXfs there are in this workbook currently, we will need this below
- $countCellXfs = count($this->cellXfCollection);
-
- // copy all the shared cellXfs from the external workbook and append them to the current
- foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
- $this->addCellXf(clone $cellXf);
- }
-
- // move sheet to this workbook
- $pSheet->rebindParent($this);
-
- // update the cellXfs
- foreach ($pSheet->getCoordinates(false) as $coordinate) {
- $cell = $pSheet->getCell($coordinate);
- $cell->setXfIndex($cell->getXfIndex() + $countCellXfs);
- }
-
- return $this->addSheet($pSheet, $iSheetIndex);
- }
-
- /**
- * Get an array of all Named Ranges.
- *
- * @return NamedRange[]
- */
- public function getNamedRanges(): array
- {
- return array_filter(
- $this->definedNames,
- function (DefinedName $definedName) {
- return $definedName->isFormula() === self::DEFINED_NAME_IS_RANGE;
- }
- );
- }
-
- /**
- * Get an array of all Named Formulae.
- *
- * @return NamedFormula[]
- */
- public function getNamedFormulae(): array
- {
- return array_filter(
- $this->definedNames,
- function (DefinedName $definedName) {
- return $definedName->isFormula() === self::DEFINED_NAME_IS_FORMULA;
- }
- );
- }
-
- /**
- * Get an array of all Defined Names (both named ranges and named formulae).
- *
- * @return DefinedName[]
- */
- public function getDefinedNames(): array
- {
- return $this->definedNames;
- }
-
- /**
- * Add a named range.
- * If a named range with this name already exists, then this will replace the existing value.
- */
- public function addNamedRange(NamedRange $namedRange): void
- {
- $this->addDefinedName($namedRange);
- }
-
- /**
- * Add a named formula.
- * If a named formula with this name already exists, then this will replace the existing value.
- */
- public function addNamedFormula(NamedFormula $namedFormula): void
- {
- $this->addDefinedName($namedFormula);
- }
-
- /**
- * Add a defined name (either a named range or a named formula).
- * If a defined named with this name already exists, then this will replace the existing value.
- */
- public function addDefinedName(DefinedName $definedName): void
- {
- $upperCaseName = StringHelper::strToUpper($definedName->getName());
- if ($definedName->getScope() == null) {
- // global scope
- $this->definedNames[$upperCaseName] = $definedName;
- } else {
- // local scope
- $this->definedNames[$definedName->getScope()->getTitle() . '!' . $upperCaseName] = $definedName;
- }
- }
-
- /**
- * Get named range.
- *
- * @param null|Worksheet $pSheet Scope. Use null for global scope
- */
- public function getNamedRange(string $namedRange, ?Worksheet $pSheet = null): ?NamedRange
- {
- $returnValue = null;
-
- if ($namedRange !== '') {
- $namedRange = StringHelper::strToUpper($namedRange);
- // first look for global named range
- $returnValue = $this->getGlobalDefinedNameByType($namedRange, self::DEFINED_NAME_IS_RANGE);
- // then look for local named range (has priority over global named range if both names exist)
- $returnValue = $this->getLocalDefinedNameByType($namedRange, self::DEFINED_NAME_IS_RANGE, $pSheet) ?: $returnValue;
- }
-
- return $returnValue instanceof NamedRange ? $returnValue : null;
- }
-
- /**
- * Get named formula.
- *
- * @param null|Worksheet $pSheet Scope. Use null for global scope
- */
- public function getNamedFormula(string $namedFormula, ?Worksheet $pSheet = null): ?NamedFormula
- {
- $returnValue = null;
-
- if ($namedFormula !== '') {
- $namedFormula = StringHelper::strToUpper($namedFormula);
- // first look for global named formula
- $returnValue = $this->getGlobalDefinedNameByType($namedFormula, self::DEFINED_NAME_IS_FORMULA);
- // then look for local named formula (has priority over global named formula if both names exist)
- $returnValue = $this->getLocalDefinedNameByType($namedFormula, self::DEFINED_NAME_IS_FORMULA, $pSheet) ?: $returnValue;
- }
-
- return $returnValue instanceof NamedFormula ? $returnValue : null;
- }
-
- private function getGlobalDefinedNameByType(string $name, bool $type): ?DefinedName
- {
- if (isset($this->definedNames[$name]) && $this->definedNames[$name]->isFormula() === $type) {
- return $this->definedNames[$name];
- }
-
- return null;
- }
-
- private function getLocalDefinedNameByType(string $name, bool $type, ?Worksheet $pSheet = null): ?DefinedName
- {
- if (
- ($pSheet !== null) && isset($this->definedNames[$pSheet->getTitle() . '!' . $name])
- && $this->definedNames[$pSheet->getTitle() . '!' . $name]->isFormula() === $type
- ) {
- return $this->definedNames[$pSheet->getTitle() . '!' . $name];
- }
-
- return null;
- }
-
- /**
- * Get named range.
- *
- * @param null|Worksheet $pSheet Scope. Use null for global scope
- */
- public function getDefinedName(string $definedName, ?Worksheet $pSheet = null): ?DefinedName
- {
- $returnValue = null;
-
- if ($definedName !== '') {
- $definedName = StringHelper::strToUpper($definedName);
- // first look for global defined name
- if (isset($this->definedNames[$definedName])) {
- $returnValue = $this->definedNames[$definedName];
- }
-
- // then look for local defined name (has priority over global defined name if both names exist)
- if (($pSheet !== null) && isset($this->definedNames[$pSheet->getTitle() . '!' . $definedName])) {
- $returnValue = $this->definedNames[$pSheet->getTitle() . '!' . $definedName];
- }
- }
-
- return $returnValue;
- }
-
- /**
- * Remove named range.
- *
- * @param null|Worksheet $pSheet scope: use null for global scope
- *
- * @return $this
- */
- public function removeNamedRange(string $namedRange, ?Worksheet $pSheet = null): self
- {
- if ($this->getNamedRange($namedRange, $pSheet) === null) {
- return $this;
- }
-
- return $this->removeDefinedName($namedRange, $pSheet);
- }
-
- /**
- * Remove named formula.
- *
- * @param null|Worksheet $pSheet scope: use null for global scope
- *
- * @return $this
- */
- public function removeNamedFormula(string $namedFormula, ?Worksheet $pSheet = null): self
- {
- if ($this->getNamedFormula($namedFormula, $pSheet) === null) {
- return $this;
- }
-
- return $this->removeDefinedName($namedFormula, $pSheet);
- }
-
- /**
- * Remove defined name.
- *
- * @param null|Worksheet $pSheet scope: use null for global scope
- *
- * @return $this
- */
- public function removeDefinedName(string $definedName, ?Worksheet $pSheet = null): self
- {
- $definedName = StringHelper::strToUpper($definedName);
-
- if ($pSheet === null) {
- if (isset($this->definedNames[$definedName])) {
- unset($this->definedNames[$definedName]);
- }
- } else {
- if (isset($this->definedNames[$pSheet->getTitle() . '!' . $definedName])) {
- unset($this->definedNames[$pSheet->getTitle() . '!' . $definedName]);
- } elseif (isset($this->definedNames[$definedName])) {
- unset($this->definedNames[$definedName]);
- }
- }
-
- return $this;
- }
-
- /**
- * Get worksheet iterator.
- *
- * @return Iterator
- */
- public function getWorksheetIterator()
- {
- return new Iterator($this);
- }
-
- /**
- * Copy workbook (!= clone!).
- *
- * @return Spreadsheet
- */
- public function copy()
- {
- $copied = clone $this;
-
- $worksheetCount = count($this->workSheetCollection);
- for ($i = 0; $i < $worksheetCount; ++$i) {
- $this->workSheetCollection[$i] = $this->workSheetCollection[$i]->copy();
- $this->workSheetCollection[$i]->rebindParent($this);
- }
-
- return $copied;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- foreach ($this as $key => $val) {
- if (is_object($val) || (is_array($val))) {
- $this->{$key} = unserialize(serialize($val));
- }
- }
- }
-
- /**
- * Get the workbook collection of cellXfs.
- *
- * @return Style[]
- */
- public function getCellXfCollection()
- {
- return $this->cellXfCollection;
- }
-
- /**
- * Get cellXf by index.
- *
- * @param int $pIndex
- *
- * @return Style
- */
- public function getCellXfByIndex($pIndex)
- {
- return $this->cellXfCollection[$pIndex];
- }
-
- /**
- * Get cellXf by hash code.
- *
- * @param string $pValue
- *
- * @return false|Style
- */
- public function getCellXfByHashCode($pValue)
- {
- foreach ($this->cellXfCollection as $cellXf) {
- if ($cellXf->getHashCode() === $pValue) {
- return $cellXf;
- }
- }
-
- return false;
- }
-
- /**
- * Check if style exists in style collection.
- *
- * @param Style $pCellStyle
- *
- * @return bool
- */
- public function cellXfExists($pCellStyle)
- {
- return in_array($pCellStyle, $this->cellXfCollection, true);
- }
-
- /**
- * Get default style.
- *
- * @return Style
- */
- public function getDefaultStyle()
- {
- if (isset($this->cellXfCollection[0])) {
- return $this->cellXfCollection[0];
- }
-
- throw new Exception('No default style found for this workbook');
- }
-
- /**
- * Add a cellXf to the workbook.
- */
- public function addCellXf(Style $style): void
- {
- $this->cellXfCollection[] = $style;
- $style->setIndex(count($this->cellXfCollection) - 1);
- }
-
- /**
- * Remove cellXf by index. It is ensured that all cells get their xf index updated.
- *
- * @param int $pIndex Index to cellXf
- */
- public function removeCellXfByIndex($pIndex): void
- {
- if ($pIndex > count($this->cellXfCollection) - 1) {
- throw new Exception('CellXf index is out of bounds.');
- }
-
- // first remove the cellXf
- array_splice($this->cellXfCollection, $pIndex, 1);
-
- // then update cellXf indexes for cells
- foreach ($this->workSheetCollection as $worksheet) {
- foreach ($worksheet->getCoordinates(false) as $coordinate) {
- $cell = $worksheet->getCell($coordinate);
- $xfIndex = $cell->getXfIndex();
- if ($xfIndex > $pIndex) {
- // decrease xf index by 1
- $cell->setXfIndex($xfIndex - 1);
- } elseif ($xfIndex == $pIndex) {
- // set to default xf index 0
- $cell->setXfIndex(0);
- }
- }
- }
- }
-
- /**
- * Get the cellXf supervisor.
- *
- * @return Style
- */
- public function getCellXfSupervisor()
- {
- return $this->cellXfSupervisor;
- }
-
- /**
- * Get the workbook collection of cellStyleXfs.
- *
- * @return Style[]
- */
- public function getCellStyleXfCollection()
- {
- return $this->cellStyleXfCollection;
- }
-
- /**
- * Get cellStyleXf by index.
- *
- * @param int $pIndex Index to cellXf
- *
- * @return Style
- */
- public function getCellStyleXfByIndex($pIndex)
- {
- return $this->cellStyleXfCollection[$pIndex];
- }
-
- /**
- * Get cellStyleXf by hash code.
- *
- * @param string $pValue
- *
- * @return false|Style
- */
- public function getCellStyleXfByHashCode($pValue)
- {
- foreach ($this->cellStyleXfCollection as $cellStyleXf) {
- if ($cellStyleXf->getHashCode() === $pValue) {
- return $cellStyleXf;
- }
- }
-
- return false;
- }
-
- /**
- * Add a cellStyleXf to the workbook.
- */
- public function addCellStyleXf(Style $pStyle): void
- {
- $this->cellStyleXfCollection[] = $pStyle;
- $pStyle->setIndex(count($this->cellStyleXfCollection) - 1);
- }
-
- /**
- * Remove cellStyleXf by index.
- *
- * @param int $pIndex Index to cellXf
- */
- public function removeCellStyleXfByIndex($pIndex): void
- {
- if ($pIndex > count($this->cellStyleXfCollection) - 1) {
- throw new Exception('CellStyleXf index is out of bounds.');
- }
- array_splice($this->cellStyleXfCollection, $pIndex, 1);
- }
-
- /**
- * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells
- * and columns in the workbook.
- */
- public function garbageCollect(): void
- {
- // how many references are there to each cellXf ?
- $countReferencesCellXf = [];
- foreach ($this->cellXfCollection as $index => $cellXf) {
- $countReferencesCellXf[$index] = 0;
- }
-
- foreach ($this->getWorksheetIterator() as $sheet) {
- // from cells
- foreach ($sheet->getCoordinates(false) as $coordinate) {
- $cell = $sheet->getCell($coordinate);
- ++$countReferencesCellXf[$cell->getXfIndex()];
- }
-
- // from row dimensions
- foreach ($sheet->getRowDimensions() as $rowDimension) {
- if ($rowDimension->getXfIndex() !== null) {
- ++$countReferencesCellXf[$rowDimension->getXfIndex()];
- }
- }
-
- // from column dimensions
- foreach ($sheet->getColumnDimensions() as $columnDimension) {
- ++$countReferencesCellXf[$columnDimension->getXfIndex()];
- }
- }
-
- // remove cellXfs without references and create mapping so we can update xfIndex
- // for all cells and columns
- $countNeededCellXfs = 0;
- foreach ($this->cellXfCollection as $index => $cellXf) {
- if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
- ++$countNeededCellXfs;
- } else {
- unset($this->cellXfCollection[$index]);
- }
- $map[$index] = $countNeededCellXfs - 1;
- }
- $this->cellXfCollection = array_values($this->cellXfCollection);
-
- // update the index for all cellXfs
- foreach ($this->cellXfCollection as $i => $cellXf) {
- $cellXf->setIndex($i);
- }
-
- // make sure there is always at least one cellXf (there should be)
- if (empty($this->cellXfCollection)) {
- $this->cellXfCollection[] = new Style();
- }
-
- // update the xfIndex for all cells, row dimensions, column dimensions
- foreach ($this->getWorksheetIterator() as $sheet) {
- // for all cells
- foreach ($sheet->getCoordinates(false) as $coordinate) {
- $cell = $sheet->getCell($coordinate);
- $cell->setXfIndex($map[$cell->getXfIndex()]);
- }
-
- // for all row dimensions
- foreach ($sheet->getRowDimensions() as $rowDimension) {
- if ($rowDimension->getXfIndex() !== null) {
- $rowDimension->setXfIndex($map[$rowDimension->getXfIndex()]);
- }
- }
-
- // for all column dimensions
- foreach ($sheet->getColumnDimensions() as $columnDimension) {
- $columnDimension->setXfIndex($map[$columnDimension->getXfIndex()]);
- }
-
- // also do garbage collection for all the sheets
- $sheet->garbageCollect();
- }
- }
-
- /**
- * Return the unique ID value assigned to this spreadsheet workbook.
- *
- * @return string
- */
- public function getID()
- {
- return $this->uniqueID;
- }
-
- /**
- * Get the visibility of the horizonal scroll bar in the application.
- *
- * @return bool True if horizonal scroll bar is visible
- */
- public function getShowHorizontalScroll()
- {
- return $this->showHorizontalScroll;
- }
-
- /**
- * Set the visibility of the horizonal scroll bar in the application.
- *
- * @param bool $showHorizontalScroll True if horizonal scroll bar is visible
- */
- public function setShowHorizontalScroll($showHorizontalScroll): void
- {
- $this->showHorizontalScroll = (bool) $showHorizontalScroll;
- }
-
- /**
- * Get the visibility of the vertical scroll bar in the application.
- *
- * @return bool True if vertical scroll bar is visible
- */
- public function getShowVerticalScroll()
- {
- return $this->showVerticalScroll;
- }
-
- /**
- * Set the visibility of the vertical scroll bar in the application.
- *
- * @param bool $showVerticalScroll True if vertical scroll bar is visible
- */
- public function setShowVerticalScroll($showVerticalScroll): void
- {
- $this->showVerticalScroll = (bool) $showVerticalScroll;
- }
-
- /**
- * Get the visibility of the sheet tabs in the application.
- *
- * @return bool True if the sheet tabs are visible
- */
- public function getShowSheetTabs()
- {
- return $this->showSheetTabs;
- }
-
- /**
- * Set the visibility of the sheet tabs in the application.
- *
- * @param bool $showSheetTabs True if sheet tabs are visible
- */
- public function setShowSheetTabs($showSheetTabs): void
- {
- $this->showSheetTabs = (bool) $showSheetTabs;
- }
-
- /**
- * Return whether the workbook window is minimized.
- *
- * @return bool true if workbook window is minimized
- */
- public function getMinimized()
- {
- return $this->minimized;
- }
-
- /**
- * Set whether the workbook window is minimized.
- *
- * @param bool $minimized true if workbook window is minimized
- */
- public function setMinimized($minimized): void
- {
- $this->minimized = (bool) $minimized;
- }
-
- /**
- * Return whether to group dates when presenting the user with
- * filtering optiomd in the user interface.
- *
- * @return bool true if workbook window is minimized
- */
- public function getAutoFilterDateGrouping()
- {
- return $this->autoFilterDateGrouping;
- }
-
- /**
- * Set whether to group dates when presenting the user with
- * filtering optiomd in the user interface.
- *
- * @param bool $autoFilterDateGrouping true if workbook window is minimized
- */
- public function setAutoFilterDateGrouping($autoFilterDateGrouping): void
- {
- $this->autoFilterDateGrouping = (bool) $autoFilterDateGrouping;
- }
-
- /**
- * Return the first sheet in the book view.
- *
- * @return int First sheet in book view
- */
- public function getFirstSheetIndex()
- {
- return $this->firstSheetIndex;
- }
-
- /**
- * Set the first sheet in the book view.
- *
- * @param int $firstSheetIndex First sheet in book view
- */
- public function setFirstSheetIndex($firstSheetIndex): void
- {
- if ($firstSheetIndex >= 0) {
- $this->firstSheetIndex = (int) $firstSheetIndex;
- } else {
- throw new Exception('First sheet index must be a positive integer.');
- }
- }
-
- /**
- * Return the visibility status of the workbook.
- *
- * This may be one of the following three values:
- * - visibile
- *
- * @return string Visible status
- */
- public function getVisibility()
- {
- return $this->visibility;
- }
-
- /**
- * Set the visibility status of the workbook.
- *
- * Valid values are:
- * - 'visible' (self::VISIBILITY_VISIBLE):
- * Workbook window is visible
- * - 'hidden' (self::VISIBILITY_HIDDEN):
- * Workbook window is hidden, but can be shown by the user
- * via the user interface
- * - 'veryHidden' (self::VISIBILITY_VERY_HIDDEN):
- * Workbook window is hidden and cannot be shown in the
- * user interface.
- *
- * @param string $visibility visibility status of the workbook
- */
- public function setVisibility($visibility): void
- {
- if ($visibility === null) {
- $visibility = self::VISIBILITY_VISIBLE;
- }
-
- if (in_array($visibility, self::$workbookViewVisibilityValues)) {
- $this->visibility = $visibility;
- } else {
- throw new Exception('Invalid visibility value.');
- }
- }
-
- /**
- * Get the ratio between the workbook tabs bar and the horizontal scroll bar.
- * TabRatio is assumed to be out of 1000 of the horizontal window width.
- *
- * @return int Ratio between the workbook tabs bar and the horizontal scroll bar
- */
- public function getTabRatio()
- {
- return $this->tabRatio;
- }
-
- /**
- * Set the ratio between the workbook tabs bar and the horizontal scroll bar
- * TabRatio is assumed to be out of 1000 of the horizontal window width.
- *
- * @param int $tabRatio Ratio between the tabs bar and the horizontal scroll bar
- */
- public function setTabRatio($tabRatio): void
- {
- if ($tabRatio >= 0 || $tabRatio <= 1000) {
- $this->tabRatio = (int) $tabRatio;
- } else {
- throw new Exception('Tab ratio must be between 0 and 1000.');
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Alignment.php b/vendor/PhpSpreadsheet/Style/Alignment.php
deleted file mode 100644
index 4d97dd2..0000000
--- a/vendor/PhpSpreadsheet/Style/Alignment.php
+++ /dev/null
@@ -1,464 +0,0 @@
-horizontal = null;
- $this->vertical = null;
- $this->textRotation = null;
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Alignment
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getAlignment();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['alignment' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(
- * [
- * 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
- * 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
- * 'textRotation' => 0,
- * 'wrapText' => TRUE
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())
- ->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['horizontal'])) {
- $this->setHorizontal($pStyles['horizontal']);
- }
- if (isset($pStyles['vertical'])) {
- $this->setVertical($pStyles['vertical']);
- }
- if (isset($pStyles['textRotation'])) {
- $this->setTextRotation($pStyles['textRotation']);
- }
- if (isset($pStyles['wrapText'])) {
- $this->setWrapText($pStyles['wrapText']);
- }
- if (isset($pStyles['shrinkToFit'])) {
- $this->setShrinkToFit($pStyles['shrinkToFit']);
- }
- if (isset($pStyles['indent'])) {
- $this->setIndent($pStyles['indent']);
- }
- if (isset($pStyles['readOrder'])) {
- $this->setReadOrder($pStyles['readOrder']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Horizontal.
- *
- * @return string
- */
- public function getHorizontal()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHorizontal();
- }
-
- return $this->horizontal;
- }
-
- /**
- * Set Horizontal.
- *
- * @param string $pValue see self::HORIZONTAL_*
- *
- * @return $this
- */
- public function setHorizontal($pValue)
- {
- if ($pValue == '') {
- $pValue = self::HORIZONTAL_GENERAL;
- }
-
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['horizontal' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->horizontal = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Vertical.
- *
- * @return string
- */
- public function getVertical()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getVertical();
- }
-
- return $this->vertical;
- }
-
- /**
- * Set Vertical.
- *
- * @param string $pValue see self::VERTICAL_*
- *
- * @return $this
- */
- public function setVertical($pValue)
- {
- if ($pValue == '') {
- $pValue = self::VERTICAL_BOTTOM;
- }
-
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['vertical' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->vertical = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get TextRotation.
- *
- * @return int
- */
- public function getTextRotation()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getTextRotation();
- }
-
- return $this->textRotation;
- }
-
- /**
- * Set TextRotation.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setTextRotation($pValue)
- {
- // Excel2007 value 255 => PhpSpreadsheet value -165
- if ($pValue == 255) {
- $pValue = -165;
- }
-
- // Set rotation
- if (($pValue >= -90 && $pValue <= 90) || $pValue == -165) {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['textRotation' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->textRotation = $pValue;
- }
- } else {
- throw new PhpSpreadsheetException('Text rotation should be a value between -90 and 90.');
- }
-
- return $this;
- }
-
- /**
- * Get Wrap Text.
- *
- * @return bool
- */
- public function getWrapText()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getWrapText();
- }
-
- return $this->wrapText;
- }
-
- /**
- * Set Wrap Text.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setWrapText($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['wrapText' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->wrapText = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Shrink to fit.
- *
- * @return bool
- */
- public function getShrinkToFit()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getShrinkToFit();
- }
-
- return $this->shrinkToFit;
- }
-
- /**
- * Set Shrink to fit.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setShrinkToFit($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['shrinkToFit' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->shrinkToFit = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get indent.
- *
- * @return int
- */
- public function getIndent()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getIndent();
- }
-
- return $this->indent;
- }
-
- /**
- * Set indent.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setIndent($pValue)
- {
- if ($pValue > 0) {
- if (
- $this->getHorizontal() != self::HORIZONTAL_GENERAL &&
- $this->getHorizontal() != self::HORIZONTAL_LEFT &&
- $this->getHorizontal() != self::HORIZONTAL_RIGHT
- ) {
- $pValue = 0; // indent not supported
- }
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['indent' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->indent = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get read order.
- *
- * @return int
- */
- public function getReadOrder()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getReadOrder();
- }
-
- return $this->readOrder;
- }
-
- /**
- * Set read order.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setReadOrder($pValue)
- {
- if ($pValue < 0 || $pValue > 2) {
- $pValue = 0;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['readOrder' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->readOrder = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->horizontal .
- $this->vertical .
- $this->textRotation .
- ($this->wrapText ? 't' : 'f') .
- ($this->shrinkToFit ? 't' : 'f') .
- $this->indent .
- $this->readOrder .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Border.php b/vendor/PhpSpreadsheet/Style/Border.php
deleted file mode 100644
index 78ad8b2..0000000
--- a/vendor/PhpSpreadsheet/Style/Border.php
+++ /dev/null
@@ -1,231 +0,0 @@
-color = new Color(Color::COLOR_BLACK, $isSupervisor);
-
- // bind parent if we are a supervisor
- if ($isSupervisor) {
- $this->color->bindParent($this, 'color');
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Border
- */
- public function getSharedComponent()
- {
- switch ($this->parentPropertyName) {
- case 'allBorders':
- case 'horizontal':
- case 'inside':
- case 'outline':
- case 'vertical':
- throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.');
-
- break;
- case 'bottom':
- return $this->parent->getSharedComponent()->getBottom();
- case 'diagonal':
- return $this->parent->getSharedComponent()->getDiagonal();
- case 'left':
- return $this->parent->getSharedComponent()->getLeft();
- case 'right':
- return $this->parent->getSharedComponent()->getRight();
- case 'top':
- return $this->parent->getSharedComponent()->getTop();
- }
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return $this->parent->getStyleArray([$this->parentPropertyName => $array]);
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(
- * [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['borderStyle'])) {
- $this->setBorderStyle($pStyles['borderStyle']);
- }
- if (isset($pStyles['color'])) {
- $this->getColor()->applyFromArray($pStyles['color']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Border style.
- *
- * @return string
- */
- public function getBorderStyle()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getBorderStyle();
- }
-
- return $this->borderStyle;
- }
-
- /**
- * Set Border style.
- *
- * @param bool|string $pValue
- * When passing a boolean, FALSE equates Border::BORDER_NONE
- * and TRUE to Border::BORDER_MEDIUM
- *
- * @return $this
- */
- public function setBorderStyle($pValue)
- {
- if (empty($pValue)) {
- $pValue = self::BORDER_NONE;
- } elseif (is_bool($pValue) && $pValue) {
- $pValue = self::BORDER_MEDIUM;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['borderStyle' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->borderStyle = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Border Color.
- *
- * @return Color
- */
- public function getColor()
- {
- return $this->color;
- }
-
- /**
- * Set Border Color.
- *
- * @return $this
- */
- public function setColor(Color $pValue)
- {
- // make sure parameter is a real color and not a supervisor
- $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
-
- if ($this->isSupervisor) {
- $styleArray = $this->getColor()->getStyleArray(['argb' => $color->getARGB()]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->color = $color;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->borderStyle .
- $this->color->getHashCode() .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Borders.php b/vendor/PhpSpreadsheet/Style/Borders.php
deleted file mode 100644
index e75d7ee..0000000
--- a/vendor/PhpSpreadsheet/Style/Borders.php
+++ /dev/null
@@ -1,411 +0,0 @@
-left = new Border($isSupervisor, $isConditional);
- $this->right = new Border($isSupervisor, $isConditional);
- $this->top = new Border($isSupervisor, $isConditional);
- $this->bottom = new Border($isSupervisor, $isConditional);
- $this->diagonal = new Border($isSupervisor, $isConditional);
- $this->diagonalDirection = self::DIAGONAL_NONE;
-
- // Specially for supervisor
- if ($isSupervisor) {
- // Initialize pseudo-borders
- $this->allBorders = new Border(true);
- $this->outline = new Border(true);
- $this->inside = new Border(true);
- $this->vertical = new Border(true);
- $this->horizontal = new Border(true);
-
- // bind parent if we are a supervisor
- $this->left->bindParent($this, 'left');
- $this->right->bindParent($this, 'right');
- $this->top->bindParent($this, 'top');
- $this->bottom->bindParent($this, 'bottom');
- $this->diagonal->bindParent($this, 'diagonal');
- $this->allBorders->bindParent($this, 'allBorders');
- $this->outline->bindParent($this, 'outline');
- $this->inside->bindParent($this, 'inside');
- $this->vertical->bindParent($this, 'vertical');
- $this->horizontal->bindParent($this, 'horizontal');
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Borders
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getBorders();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['borders' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
- * [
- * 'bottom' => [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ],
- * 'top' => [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ]
- * ]
- * );
- *
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(
- * [
- * 'allBorders' => [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ]
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['left'])) {
- $this->getLeft()->applyFromArray($pStyles['left']);
- }
- if (isset($pStyles['right'])) {
- $this->getRight()->applyFromArray($pStyles['right']);
- }
- if (isset($pStyles['top'])) {
- $this->getTop()->applyFromArray($pStyles['top']);
- }
- if (isset($pStyles['bottom'])) {
- $this->getBottom()->applyFromArray($pStyles['bottom']);
- }
- if (isset($pStyles['diagonal'])) {
- $this->getDiagonal()->applyFromArray($pStyles['diagonal']);
- }
- if (isset($pStyles['diagonalDirection'])) {
- $this->setDiagonalDirection($pStyles['diagonalDirection']);
- }
- if (isset($pStyles['allBorders'])) {
- $this->getLeft()->applyFromArray($pStyles['allBorders']);
- $this->getRight()->applyFromArray($pStyles['allBorders']);
- $this->getTop()->applyFromArray($pStyles['allBorders']);
- $this->getBottom()->applyFromArray($pStyles['allBorders']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Left.
- *
- * @return Border
- */
- public function getLeft()
- {
- return $this->left;
- }
-
- /**
- * Get Right.
- *
- * @return Border
- */
- public function getRight()
- {
- return $this->right;
- }
-
- /**
- * Get Top.
- *
- * @return Border
- */
- public function getTop()
- {
- return $this->top;
- }
-
- /**
- * Get Bottom.
- *
- * @return Border
- */
- public function getBottom()
- {
- return $this->bottom;
- }
-
- /**
- * Get Diagonal.
- *
- * @return Border
- */
- public function getDiagonal()
- {
- return $this->diagonal;
- }
-
- /**
- * Get AllBorders (pseudo-border). Only applies to supervisor.
- *
- * @return Border
- */
- public function getAllBorders()
- {
- if (!$this->isSupervisor) {
- throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.');
- }
-
- return $this->allBorders;
- }
-
- /**
- * Get Outline (pseudo-border). Only applies to supervisor.
- *
- * @return Border
- */
- public function getOutline()
- {
- if (!$this->isSupervisor) {
- throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.');
- }
-
- return $this->outline;
- }
-
- /**
- * Get Inside (pseudo-border). Only applies to supervisor.
- *
- * @return Border
- */
- public function getInside()
- {
- if (!$this->isSupervisor) {
- throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.');
- }
-
- return $this->inside;
- }
-
- /**
- * Get Vertical (pseudo-border). Only applies to supervisor.
- *
- * @return Border
- */
- public function getVertical()
- {
- if (!$this->isSupervisor) {
- throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.');
- }
-
- return $this->vertical;
- }
-
- /**
- * Get Horizontal (pseudo-border). Only applies to supervisor.
- *
- * @return Border
- */
- public function getHorizontal()
- {
- if (!$this->isSupervisor) {
- throw new PhpSpreadsheetException('Can only get pseudo-border for supervisor.');
- }
-
- return $this->horizontal;
- }
-
- /**
- * Get DiagonalDirection.
- *
- * @return int
- */
- public function getDiagonalDirection()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getDiagonalDirection();
- }
-
- return $this->diagonalDirection;
- }
-
- /**
- * Set DiagonalDirection.
- *
- * @param int $pValue see self::DIAGONAL_*
- *
- * @return $this
- */
- public function setDiagonalDirection($pValue)
- {
- if ($pValue == '') {
- $pValue = self::DIAGONAL_NONE;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['diagonalDirection' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->diagonalDirection = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashcode();
- }
-
- return md5(
- $this->getLeft()->getHashCode() .
- $this->getRight()->getHashCode() .
- $this->getTop()->getHashCode() .
- $this->getBottom()->getHashCode() .
- $this->getDiagonal()->getHashCode() .
- $this->getDiagonalDirection() .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Color.php b/vendor/PhpSpreadsheet/Style/Color.php
deleted file mode 100644
index d8ba08b..0000000
--- a/vendor/PhpSpreadsheet/Style/Color.php
+++ /dev/null
@@ -1,407 +0,0 @@
-argb = $pARGB;
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Color
- */
- public function getSharedComponent()
- {
- switch ($this->parentPropertyName) {
- case 'endColor':
- return $this->parent->getSharedComponent()->getEndColor();
- case 'color':
- return $this->parent->getSharedComponent()->getColor();
- case 'startColor':
- return $this->parent->getSharedComponent()->getStartColor();
- }
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return $this->parent->getStyleArray([$this->parentPropertyName => $array]);
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray(['rgb' => '808080']);
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['rgb'])) {
- $this->setRGB($pStyles['rgb']);
- }
- if (isset($pStyles['argb'])) {
- $this->setARGB($pStyles['argb']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get ARGB.
- *
- * @return string
- */
- public function getARGB()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getARGB();
- }
-
- return $this->argb;
- }
-
- /**
- * Set ARGB.
- *
- * @param string $pValue see self::COLOR_*
- *
- * @return $this
- */
- public function setARGB($pValue)
- {
- if ($pValue == '') {
- $pValue = self::COLOR_BLACK;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['argb' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->argb = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get RGB.
- *
- * @return string
- */
- public function getRGB()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getRGB();
- }
-
- return substr($this->argb, 2);
- }
-
- /**
- * Set RGB.
- *
- * @param string $pValue RGB value
- *
- * @return $this
- */
- public function setRGB($pValue)
- {
- if ($pValue == '') {
- $pValue = '000000';
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['argb' => 'FF' . $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->argb = 'FF' . $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get a specified colour component of an RGB value.
- *
- * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
- * @param int $offset Position within the RGB value to extract
- * @param bool $hex Flag indicating whether the component should be returned as a hex or a
- * decimal value
- *
- * @return string The extracted colour component
- */
- private static function getColourComponent($RGB, $offset, $hex = true)
- {
- $colour = substr($RGB, $offset, 2);
-
- return ($hex) ? $colour : hexdec($colour);
- }
-
- /**
- * Get the red colour component of an RGB value.
- *
- * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
- * @param bool $hex Flag indicating whether the component should be returned as a hex or a
- * decimal value
- *
- * @return string The red colour component
- */
- public static function getRed($RGB, $hex = true)
- {
- return self::getColourComponent($RGB, strlen($RGB) - 6, $hex);
- }
-
- /**
- * Get the green colour component of an RGB value.
- *
- * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
- * @param bool $hex Flag indicating whether the component should be returned as a hex or a
- * decimal value
- *
- * @return string The green colour component
- */
- public static function getGreen($RGB, $hex = true)
- {
- return self::getColourComponent($RGB, strlen($RGB) - 4, $hex);
- }
-
- /**
- * Get the blue colour component of an RGB value.
- *
- * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE
- * @param bool $hex Flag indicating whether the component should be returned as a hex or a
- * decimal value
- *
- * @return string The blue colour component
- */
- public static function getBlue($RGB, $hex = true)
- {
- return self::getColourComponent($RGB, strlen($RGB) - 2, $hex);
- }
-
- /**
- * Adjust the brightness of a color.
- *
- * @param string $hex The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
- * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1
- *
- * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
- */
- public static function changeBrightness($hex, $adjustPercentage)
- {
- $rgba = (strlen($hex) === 8);
-
- $red = self::getRed($hex, false);
- $green = self::getGreen($hex, false);
- $blue = self::getBlue($hex, false);
- if ($adjustPercentage > 0) {
- $red += (255 - $red) * $adjustPercentage;
- $green += (255 - $green) * $adjustPercentage;
- $blue += (255 - $blue) * $adjustPercentage;
- } else {
- $red += $red * $adjustPercentage;
- $green += $green * $adjustPercentage;
- $blue += $blue * $adjustPercentage;
- }
-
- if ($red < 0) {
- $red = 0;
- } elseif ($red > 255) {
- $red = 255;
- }
- if ($green < 0) {
- $green = 0;
- } elseif ($green > 255) {
- $green = 255;
- }
- if ($blue < 0) {
- $blue = 0;
- } elseif ($blue > 255) {
- $blue = 255;
- }
-
- $rgb = strtoupper(
- str_pad(dechex((int) $red), 2, '0', 0) .
- str_pad(dechex((int) $green), 2, '0', 0) .
- str_pad(dechex((int) $blue), 2, '0', 0)
- );
-
- return (($rgba) ? 'FF' : '') . $rgb;
- }
-
- /**
- * Get indexed color.
- *
- * @param int $pIndex Index entry point into the colour array
- * @param bool $background Flag to indicate whether default background or foreground colour
- * should be returned if the indexed colour doesn't exist
- *
- * @return self
- */
- public static function indexedColor($pIndex, $background = false)
- {
- // Clean parameter
- $pIndex = (int) $pIndex;
-
- // Indexed colors
- if (self::$indexedColors === null) {
- self::$indexedColors = [
- 1 => 'FF000000', // System Colour #1 - Black
- 2 => 'FFFFFFFF', // System Colour #2 - White
- 3 => 'FFFF0000', // System Colour #3 - Red
- 4 => 'FF00FF00', // System Colour #4 - Green
- 5 => 'FF0000FF', // System Colour #5 - Blue
- 6 => 'FFFFFF00', // System Colour #6 - Yellow
- 7 => 'FFFF00FF', // System Colour #7- Magenta
- 8 => 'FF00FFFF', // System Colour #8- Cyan
- 9 => 'FF800000', // Standard Colour #9
- 10 => 'FF008000', // Standard Colour #10
- 11 => 'FF000080', // Standard Colour #11
- 12 => 'FF808000', // Standard Colour #12
- 13 => 'FF800080', // Standard Colour #13
- 14 => 'FF008080', // Standard Colour #14
- 15 => 'FFC0C0C0', // Standard Colour #15
- 16 => 'FF808080', // Standard Colour #16
- 17 => 'FF9999FF', // Chart Fill Colour #17
- 18 => 'FF993366', // Chart Fill Colour #18
- 19 => 'FFFFFFCC', // Chart Fill Colour #19
- 20 => 'FFCCFFFF', // Chart Fill Colour #20
- 21 => 'FF660066', // Chart Fill Colour #21
- 22 => 'FFFF8080', // Chart Fill Colour #22
- 23 => 'FF0066CC', // Chart Fill Colour #23
- 24 => 'FFCCCCFF', // Chart Fill Colour #24
- 25 => 'FF000080', // Chart Line Colour #25
- 26 => 'FFFF00FF', // Chart Line Colour #26
- 27 => 'FFFFFF00', // Chart Line Colour #27
- 28 => 'FF00FFFF', // Chart Line Colour #28
- 29 => 'FF800080', // Chart Line Colour #29
- 30 => 'FF800000', // Chart Line Colour #30
- 31 => 'FF008080', // Chart Line Colour #31
- 32 => 'FF0000FF', // Chart Line Colour #32
- 33 => 'FF00CCFF', // Standard Colour #33
- 34 => 'FFCCFFFF', // Standard Colour #34
- 35 => 'FFCCFFCC', // Standard Colour #35
- 36 => 'FFFFFF99', // Standard Colour #36
- 37 => 'FF99CCFF', // Standard Colour #37
- 38 => 'FFFF99CC', // Standard Colour #38
- 39 => 'FFCC99FF', // Standard Colour #39
- 40 => 'FFFFCC99', // Standard Colour #40
- 41 => 'FF3366FF', // Standard Colour #41
- 42 => 'FF33CCCC', // Standard Colour #42
- 43 => 'FF99CC00', // Standard Colour #43
- 44 => 'FFFFCC00', // Standard Colour #44
- 45 => 'FFFF9900', // Standard Colour #45
- 46 => 'FFFF6600', // Standard Colour #46
- 47 => 'FF666699', // Standard Colour #47
- 48 => 'FF969696', // Standard Colour #48
- 49 => 'FF003366', // Standard Colour #49
- 50 => 'FF339966', // Standard Colour #50
- 51 => 'FF003300', // Standard Colour #51
- 52 => 'FF333300', // Standard Colour #52
- 53 => 'FF993300', // Standard Colour #53
- 54 => 'FF993366', // Standard Colour #54
- 55 => 'FF333399', // Standard Colour #55
- 56 => 'FF333333', // Standard Colour #56
- ];
- }
-
- if (isset(self::$indexedColors[$pIndex])) {
- return new self(self::$indexedColors[$pIndex]);
- }
-
- if ($background) {
- return new self(self::COLOR_WHITE);
- }
-
- return new self(self::COLOR_BLACK);
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->argb .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Conditional.php b/vendor/PhpSpreadsheet/Style/Conditional.php
deleted file mode 100644
index 35ec479..0000000
--- a/vendor/PhpSpreadsheet/Style/Conditional.php
+++ /dev/null
@@ -1,274 +0,0 @@
-style = new Style(false, true);
- }
-
- /**
- * Get Condition type.
- *
- * @return string
- */
- public function getConditionType()
- {
- return $this->conditionType;
- }
-
- /**
- * Set Condition type.
- *
- * @param string $pValue Condition type, see self::CONDITION_*
- *
- * @return $this
- */
- public function setConditionType($pValue)
- {
- $this->conditionType = $pValue;
-
- return $this;
- }
-
- /**
- * Get Operator type.
- *
- * @return string
- */
- public function getOperatorType()
- {
- return $this->operatorType;
- }
-
- /**
- * Set Operator type.
- *
- * @param string $pValue Conditional operator type, see self::OPERATOR_*
- *
- * @return $this
- */
- public function setOperatorType($pValue)
- {
- $this->operatorType = $pValue;
-
- return $this;
- }
-
- /**
- * Get text.
- *
- * @return string
- */
- public function getText()
- {
- return $this->text;
- }
-
- /**
- * Set text.
- *
- * @param string $value
- *
- * @return $this
- */
- public function setText($value)
- {
- $this->text = $value;
-
- return $this;
- }
-
- /**
- * Get StopIfTrue.
- *
- * @return bool
- */
- public function getStopIfTrue()
- {
- return $this->stopIfTrue;
- }
-
- /**
- * Set StopIfTrue.
- *
- * @param bool $value
- *
- * @return $this
- */
- public function setStopIfTrue($value)
- {
- $this->stopIfTrue = $value;
-
- return $this;
- }
-
- /**
- * Get Conditions.
- *
- * @return string[]
- */
- public function getConditions()
- {
- return $this->condition;
- }
-
- /**
- * Set Conditions.
- *
- * @param string[] $pValue Condition
- *
- * @return $this
- */
- public function setConditions($pValue)
- {
- if (!is_array($pValue)) {
- $pValue = [$pValue];
- }
- $this->condition = $pValue;
-
- return $this;
- }
-
- /**
- * Add Condition.
- *
- * @param string $pValue Condition
- *
- * @return $this
- */
- public function addCondition($pValue)
- {
- $this->condition[] = $pValue;
-
- return $this;
- }
-
- /**
- * Get Style.
- *
- * @return Style
- */
- public function getStyle()
- {
- return $this->style;
- }
-
- /**
- * Set Style.
- *
- * @param Style $pValue
- *
- * @return $this
- */
- public function setStyle(?Style $pValue = null)
- {
- $this->style = $pValue;
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- return md5(
- $this->conditionType .
- $this->operatorType .
- implode(';', $this->condition) .
- $this->style->getHashCode() .
- __CLASS__
- );
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Fill.php b/vendor/PhpSpreadsheet/Style/Fill.php
deleted file mode 100644
index c6baeed..0000000
--- a/vendor/PhpSpreadsheet/Style/Fill.php
+++ /dev/null
@@ -1,314 +0,0 @@
-fillType = null;
- }
- $this->startColor = new Color(Color::COLOR_WHITE, $isSupervisor, $isConditional);
- $this->endColor = new Color(Color::COLOR_BLACK, $isSupervisor, $isConditional);
-
- // bind parent if we are a supervisor
- if ($isSupervisor) {
- $this->startColor->bindParent($this, 'startColor');
- $this->endColor->bindParent($this, 'endColor');
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Fill
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getFill();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['fill' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray(
- * [
- * 'fillType' => Fill::FILL_GRADIENT_LINEAR,
- * 'rotation' => 0,
- * 'startColor' => [
- * 'rgb' => '000000'
- * ],
- * 'endColor' => [
- * 'argb' => 'FFFFFFFF'
- * ]
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['fillType'])) {
- $this->setFillType($pStyles['fillType']);
- }
- if (isset($pStyles['rotation'])) {
- $this->setRotation($pStyles['rotation']);
- }
- if (isset($pStyles['startColor'])) {
- $this->getStartColor()->applyFromArray($pStyles['startColor']);
- }
- if (isset($pStyles['endColor'])) {
- $this->getEndColor()->applyFromArray($pStyles['endColor']);
- }
- if (isset($pStyles['color'])) {
- $this->getStartColor()->applyFromArray($pStyles['color']);
- $this->getEndColor()->applyFromArray($pStyles['color']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Fill Type.
- *
- * @return string
- */
- public function getFillType()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getFillType();
- }
-
- return $this->fillType;
- }
-
- /**
- * Set Fill Type.
- *
- * @param string $pValue Fill type, see self::FILL_*
- *
- * @return $this
- */
- public function setFillType($pValue)
- {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['fillType' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->fillType = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Rotation.
- *
- * @return float
- */
- public function getRotation()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getRotation();
- }
-
- return $this->rotation;
- }
-
- /**
- * Set Rotation.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setRotation($pValue)
- {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['rotation' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->rotation = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Start Color.
- *
- * @return Color
- */
- public function getStartColor()
- {
- return $this->startColor;
- }
-
- /**
- * Set Start Color.
- *
- * @return $this
- */
- public function setStartColor(Color $pValue)
- {
- // make sure parameter is a real color and not a supervisor
- $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
-
- if ($this->isSupervisor) {
- $styleArray = $this->getStartColor()->getStyleArray(['argb' => $color->getARGB()]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->startColor = $color;
- }
-
- return $this;
- }
-
- /**
- * Get End Color.
- *
- * @return Color
- */
- public function getEndColor()
- {
- return $this->endColor;
- }
-
- /**
- * Set End Color.
- *
- * @return $this
- */
- public function setEndColor(Color $pValue)
- {
- // make sure parameter is a real color and not a supervisor
- $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
-
- if ($this->isSupervisor) {
- $styleArray = $this->getEndColor()->getStyleArray(['argb' => $color->getARGB()]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->endColor = $color;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
- // Note that we don't care about colours for fill type NONE, but could have duplicate NONEs with
- // different hashes if we don't explicitly prevent this
- return md5(
- $this->getFillType() .
- $this->getRotation() .
- ($this->getFillType() !== self::FILL_NONE ? $this->getStartColor()->getHashCode() : '') .
- ($this->getFillType() !== self::FILL_NONE ? $this->getEndColor()->getHashCode() : '') .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Font.php b/vendor/PhpSpreadsheet/Style/Font.php
deleted file mode 100644
index eee7df0..0000000
--- a/vendor/PhpSpreadsheet/Style/Font.php
+++ /dev/null
@@ -1,548 +0,0 @@
-name = null;
- $this->size = null;
- $this->bold = null;
- $this->italic = null;
- $this->superscript = null;
- $this->subscript = null;
- $this->underline = null;
- $this->strikethrough = null;
- $this->color = new Color(Color::COLOR_BLACK, $isSupervisor, $isConditional);
- } else {
- $this->color = new Color(Color::COLOR_BLACK, $isSupervisor);
- }
- // bind parent if we are a supervisor
- if ($isSupervisor) {
- $this->color->bindParent($this, 'color');
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Font
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getFont();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['font' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray(
- * [
- * 'name' => 'Arial',
- * 'bold' => TRUE,
- * 'italic' => FALSE,
- * 'underline' => \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE,
- * 'strikethrough' => FALSE,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['name'])) {
- $this->setName($pStyles['name']);
- }
- if (isset($pStyles['bold'])) {
- $this->setBold($pStyles['bold']);
- }
- if (isset($pStyles['italic'])) {
- $this->setItalic($pStyles['italic']);
- }
- if (isset($pStyles['superscript'])) {
- $this->setSuperscript($pStyles['superscript']);
- }
- if (isset($pStyles['subscript'])) {
- $this->setSubscript($pStyles['subscript']);
- }
- if (isset($pStyles['underline'])) {
- $this->setUnderline($pStyles['underline']);
- }
- if (isset($pStyles['strikethrough'])) {
- $this->setStrikethrough($pStyles['strikethrough']);
- }
- if (isset($pStyles['color'])) {
- $this->getColor()->applyFromArray($pStyles['color']);
- }
- if (isset($pStyles['size'])) {
- $this->setSize($pStyles['size']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Name.
- *
- * @return string
- */
- public function getName()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getName();
- }
-
- return $this->name;
- }
-
- /**
- * Set Name.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setName($pValue)
- {
- if ($pValue == '') {
- $pValue = 'Calibri';
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['name' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->name = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Size.
- *
- * @return float
- */
- public function getSize()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getSize();
- }
-
- return $this->size;
- }
-
- /**
- * Set Size.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setSize($pValue)
- {
- if ($pValue == '') {
- $pValue = 10;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['size' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->size = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Bold.
- *
- * @return bool
- */
- public function getBold()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getBold();
- }
-
- return $this->bold;
- }
-
- /**
- * Set Bold.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setBold($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['bold' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->bold = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Italic.
- *
- * @return bool
- */
- public function getItalic()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getItalic();
- }
-
- return $this->italic;
- }
-
- /**
- * Set Italic.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setItalic($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['italic' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->italic = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Superscript.
- *
- * @return bool
- */
- public function getSuperscript()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getSuperscript();
- }
-
- return $this->superscript;
- }
-
- /**
- * Set Superscript.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSuperscript($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['superscript' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->superscript = $pValue;
- $this->subscript = !$pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Subscript.
- *
- * @return bool
- */
- public function getSubscript()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getSubscript();
- }
-
- return $this->subscript;
- }
-
- /**
- * Set Subscript.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSubscript($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['subscript' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->subscript = $pValue;
- $this->superscript = !$pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Underline.
- *
- * @return string
- */
- public function getUnderline()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getUnderline();
- }
-
- return $this->underline;
- }
-
- /**
- * Set Underline.
- *
- * @param bool|string $pValue \PhpOffice\PhpSpreadsheet\Style\Font underline type
- * If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE,
- * false equates to UNDERLINE_NONE
- *
- * @return $this
- */
- public function setUnderline($pValue)
- {
- if (is_bool($pValue)) {
- $pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE;
- } elseif ($pValue == '') {
- $pValue = self::UNDERLINE_NONE;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['underline' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->underline = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Strikethrough.
- *
- * @return bool
- */
- public function getStrikethrough()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getStrikethrough();
- }
-
- return $this->strikethrough;
- }
-
- /**
- * Set Strikethrough.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setStrikethrough($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
-
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['strikethrough' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->strikethrough = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get Color.
- *
- * @return Color
- */
- public function getColor()
- {
- return $this->color;
- }
-
- /**
- * Set Color.
- *
- * @return $this
- */
- public function setColor(Color $pValue)
- {
- // make sure parameter is a real color and not a supervisor
- $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;
-
- if ($this->isSupervisor) {
- $styleArray = $this->getColor()->getStyleArray(['argb' => $color->getARGB()]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->color = $color;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->name .
- $this->size .
- ($this->bold ? 't' : 'f') .
- ($this->italic ? 't' : 'f') .
- ($this->superscript ? 't' : 'f') .
- ($this->subscript ? 't' : 'f') .
- $this->underline .
- ($this->strikethrough ? 't' : 'f') .
- $this->color->getHashCode() .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/NumberFormat.php b/vendor/PhpSpreadsheet/Style/NumberFormat.php
deleted file mode 100644
index 259acab..0000000
--- a/vendor/PhpSpreadsheet/Style/NumberFormat.php
+++ /dev/null
@@ -1,873 +0,0 @@
-formatCode = null;
- $this->builtInFormatCode = false;
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return NumberFormat
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getNumberFormat();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['numberFormat' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(
- * [
- * 'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['formatCode'])) {
- $this->setFormatCode($pStyles['formatCode']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get Format Code.
- *
- * @return string
- */
- public function getFormatCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getFormatCode();
- }
- if ($this->builtInFormatCode !== false) {
- return self::builtInFormatCode($this->builtInFormatCode);
- }
-
- return $this->formatCode;
- }
-
- /**
- * Set Format Code.
- *
- * @param string $pValue see self::FORMAT_*
- *
- * @return $this
- */
- public function setFormatCode($pValue)
- {
- if ($pValue == '') {
- $pValue = self::FORMAT_GENERAL;
- }
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['formatCode' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->formatCode = $pValue;
- $this->builtInFormatCode = self::builtInFormatCodeIndex($pValue);
- }
-
- return $this;
- }
-
- /**
- * Get Built-In Format Code.
- *
- * @return int
- */
- public function getBuiltInFormatCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getBuiltInFormatCode();
- }
-
- return $this->builtInFormatCode;
- }
-
- /**
- * Set Built-In Format Code.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setBuiltInFormatCode($pValue)
- {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['formatCode' => self::builtInFormatCode($pValue)]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->builtInFormatCode = $pValue;
- $this->formatCode = self::builtInFormatCode($pValue);
- }
-
- return $this;
- }
-
- /**
- * Fill built-in format codes.
- */
- private static function fillBuiltInFormatCodes(): void
- {
- // [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance]
- // 18.8.30. numFmt (Number Format)
- //
- // The ECMA standard defines built-in format IDs
- // 14: "mm-dd-yy"
- // 22: "m/d/yy h:mm"
- // 37: "#,##0 ;(#,##0)"
- // 38: "#,##0 ;[Red](#,##0)"
- // 39: "#,##0.00;(#,##0.00)"
- // 40: "#,##0.00;[Red](#,##0.00)"
- // 47: "mmss.0"
- // KOR fmt 55: "yyyy-mm-dd"
- // Excel defines built-in format IDs
- // 14: "m/d/yyyy"
- // 22: "m/d/yyyy h:mm"
- // 37: "#,##0_);(#,##0)"
- // 38: "#,##0_);[Red](#,##0)"
- // 39: "#,##0.00_);(#,##0.00)"
- // 40: "#,##0.00_);[Red](#,##0.00)"
- // 47: "mm:ss.0"
- // KOR fmt 55: "yyyy/mm/dd"
-
- // Built-in format codes
- if (self::$builtInFormats === null) {
- self::$builtInFormats = [];
-
- // General
- self::$builtInFormats[0] = self::FORMAT_GENERAL;
- self::$builtInFormats[1] = '0';
- self::$builtInFormats[2] = '0.00';
- self::$builtInFormats[3] = '#,##0';
- self::$builtInFormats[4] = '#,##0.00';
-
- self::$builtInFormats[9] = '0%';
- self::$builtInFormats[10] = '0.00%';
- self::$builtInFormats[11] = '0.00E+00';
- self::$builtInFormats[12] = '# ?/?';
- self::$builtInFormats[13] = '# ??/??';
- self::$builtInFormats[14] = 'm/d/yyyy'; // Despite ECMA 'mm-dd-yy';
- self::$builtInFormats[15] = 'd-mmm-yy';
- self::$builtInFormats[16] = 'd-mmm';
- self::$builtInFormats[17] = 'mmm-yy';
- self::$builtInFormats[18] = 'h:mm AM/PM';
- self::$builtInFormats[19] = 'h:mm:ss AM/PM';
- self::$builtInFormats[20] = 'h:mm';
- self::$builtInFormats[21] = 'h:mm:ss';
- self::$builtInFormats[22] = 'm/d/yyyy h:mm'; // Despite ECMA 'm/d/yy h:mm';
-
- self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)';
- self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)';
- self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)';
- self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)';
-
- self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)';
- self::$builtInFormats[45] = 'mm:ss';
- self::$builtInFormats[46] = '[h]:mm:ss';
- self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0';
- self::$builtInFormats[48] = '##0.0E+0';
- self::$builtInFormats[49] = '@';
-
- // CHT
- self::$builtInFormats[27] = '[$-404]e/m/d';
- self::$builtInFormats[30] = 'm/d/yy';
- self::$builtInFormats[36] = '[$-404]e/m/d';
- self::$builtInFormats[50] = '[$-404]e/m/d';
- self::$builtInFormats[57] = '[$-404]e/m/d';
-
- // THA
- self::$builtInFormats[59] = 't0';
- self::$builtInFormats[60] = 't0.00';
- self::$builtInFormats[61] = 't#,##0';
- self::$builtInFormats[62] = 't#,##0.00';
- self::$builtInFormats[67] = 't0%';
- self::$builtInFormats[68] = 't0.00%';
- self::$builtInFormats[69] = 't# ?/?';
- self::$builtInFormats[70] = 't# ??/??';
-
- // JPN
- self::$builtInFormats[28] = '[$-411]ggge"年"m"月"d"日"';
- self::$builtInFormats[29] = '[$-411]ggge"年"m"月"d"日"';
- self::$builtInFormats[31] = 'yyyy"年"m"月"d"日"';
- self::$builtInFormats[32] = 'h"時"mm"分"';
- self::$builtInFormats[33] = 'h"時"mm"分"ss"秒"';
- self::$builtInFormats[34] = 'yyyy"年"m"月"';
- self::$builtInFormats[35] = 'm"月"d"日"';
- self::$builtInFormats[51] = '[$-411]ggge"年"m"月"d"日"';
- self::$builtInFormats[52] = 'yyyy"年"m"月"';
- self::$builtInFormats[53] = 'm"月"d"日"';
- self::$builtInFormats[54] = '[$-411]ggge"年"m"月"d"日"';
- self::$builtInFormats[55] = 'yyyy"年"m"月"';
- self::$builtInFormats[56] = 'm"月"d"日"';
- self::$builtInFormats[58] = '[$-411]ggge"年"m"月"d"日"';
-
- // Flip array (for faster lookups)
- self::$flippedBuiltInFormats = array_flip(self::$builtInFormats);
- }
- }
-
- /**
- * Get built-in format code.
- *
- * @param int $pIndex
- *
- * @return string
- */
- public static function builtInFormatCode($pIndex)
- {
- // Clean parameter
- $pIndex = (int) $pIndex;
-
- // Ensure built-in format codes are available
- self::fillBuiltInFormatCodes();
-
- // Lookup format code
- if (isset(self::$builtInFormats[$pIndex])) {
- return self::$builtInFormats[$pIndex];
- }
-
- return '';
- }
-
- /**
- * Get built-in format code index.
- *
- * @param string $formatCode
- *
- * @return bool|int
- */
- public static function builtInFormatCodeIndex($formatCode)
- {
- // Ensure built-in format codes are available
- self::fillBuiltInFormatCodes();
-
- // Lookup format code
- if (array_key_exists($formatCode, self::$flippedBuiltInFormats)) {
- return self::$flippedBuiltInFormats[$formatCode];
- }
-
- return false;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->formatCode .
- $this->builtInFormatCode .
- __CLASS__
- );
- }
-
- /**
- * Search/replace values to convert Excel date/time format masks to PHP format masks.
- *
- * @var array
- */
- private static $dateFormatReplacements = [
- // first remove escapes related to non-format characters
- '\\' => '',
- // 12-hour suffix
- 'am/pm' => 'A',
- // 4-digit year
- 'e' => 'Y',
- 'yyyy' => 'Y',
- // 2-digit year
- 'yy' => 'y',
- // first letter of month - no php equivalent
- 'mmmmm' => 'M',
- // full month name
- 'mmmm' => 'F',
- // short month name
- 'mmm' => 'M',
- // mm is minutes if time, but can also be month w/leading zero
- // so we try to identify times be the inclusion of a : separator in the mask
- // It isn't perfect, but the best way I know how
- ':mm' => ':i',
- 'mm:' => 'i:',
- // month leading zero
- 'mm' => 'm',
- // month no leading zero
- 'm' => 'n',
- // full day of week name
- 'dddd' => 'l',
- // short day of week name
- 'ddd' => 'D',
- // days leading zero
- 'dd' => 'd',
- // days no leading zero
- 'd' => 'j',
- // seconds
- 'ss' => 's',
- // fractional seconds - no php equivalent
- '.s' => '',
- ];
-
- /**
- * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock).
- *
- * @var array
- */
- private static $dateFormatReplacements24 = [
- 'hh' => 'H',
- 'h' => 'G',
- ];
-
- /**
- * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock).
- *
- * @var array
- */
- private static $dateFormatReplacements12 = [
- 'hh' => 'h',
- 'h' => 'g',
- ];
-
- private static function setLowercaseCallback($matches)
- {
- return mb_strtolower($matches[0]);
- }
-
- private static function escapeQuotesCallback($matches)
- {
- return '\\' . implode('\\', str_split($matches[1]));
- }
-
- private static function formatAsDate(&$value, &$format): void
- {
- // strip off first part containing e.g. [$-F800] or [$USD-409]
- // general syntax: [$-]
- // language info is in hexadecimal
- // strip off chinese part like [DBNum1][$-804]
- $format = preg_replace('/^(\[[0-9A-Za-z]*\])*(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format);
-
- // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case;
- // but we don't want to change any quoted strings
- $format = preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', ['self', 'setLowercaseCallback'], $format);
-
- // Only process the non-quoted blocks for date format characters
- $blocks = explode('"', $format);
- foreach ($blocks as $key => &$block) {
- if ($key % 2 == 0) {
- $block = strtr($block, self::$dateFormatReplacements);
- if (!strpos($block, 'A')) {
- // 24-hour time format
- // when [h]:mm format, the [h] should replace to the hours of the value * 24
- if (false !== strpos($block, '[h]')) {
- $hours = (int) ($value * 24);
- $block = str_replace('[h]', $hours, $block);
-
- continue;
- }
- $block = strtr($block, self::$dateFormatReplacements24);
- } else {
- // 12-hour time format
- $block = strtr($block, self::$dateFormatReplacements12);
- }
- }
- }
- $format = implode('"', $blocks);
-
- // escape any quoted characters so that DateTime format() will render them correctly
- $format = preg_replace_callback('/"(.*)"/U', ['self', 'escapeQuotesCallback'], $format);
-
- $dateObj = Date::excelToDateTimeObject($value);
- $value = $dateObj->format($format);
- }
-
- private static function formatAsPercentage(&$value, &$format): void
- {
- if ($format === self::FORMAT_PERCENTAGE) {
- $value = round((100 * $value), 0) . '%';
- } else {
- if (preg_match('/\.[#0]+/', $format, $m)) {
- $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1);
- $format = str_replace($m[0], $s, $format);
- }
- if (preg_match('/^[#0]+/', $format, $m)) {
- $format = str_replace($m[0], strlen($m[0]), $format);
- }
- $format = '%' . str_replace('%', 'f%%', $format);
-
- $value = sprintf($format, 100 * $value);
- }
- }
-
- private static function formatAsFraction(&$value, &$format): void
- {
- $sign = ($value < 0) ? '-' : '';
-
- $integerPart = floor(abs($value));
- $decimalPart = trim(fmod(abs($value), 1), '0.');
- $decimalLength = strlen($decimalPart);
- $decimalDivisor = 10 ** $decimalLength;
-
- $GCD = MathTrig::GCD($decimalPart, $decimalDivisor);
-
- $adjustedDecimalPart = $decimalPart / $GCD;
- $adjustedDecimalDivisor = $decimalDivisor / $GCD;
-
- if ((strpos($format, '0') !== false)) {
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- } elseif ((strpos($format, '#') !== false)) {
- if ($integerPart == 0) {
- $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
- } else {
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- }
- } elseif ((substr($format, 0, 3) == '? ?')) {
- if ($integerPart == 0) {
- $integerPart = '';
- }
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- } else {
- $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;
- $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
- }
- }
-
- private static function mergeComplexNumberFormatMasks($numbers, $masks)
- {
- $decimalCount = strlen($numbers[1]);
- $postDecimalMasks = [];
-
- do {
- $tempMask = array_pop($masks);
- $postDecimalMasks[] = $tempMask;
- $decimalCount -= strlen($tempMask);
- } while ($decimalCount > 0);
-
- return [
- implode('.', $masks),
- implode('.', array_reverse($postDecimalMasks)),
- ];
- }
-
- private static function processComplexNumberFormatMask($number, $mask)
- {
- $result = $number;
- $maskingBlockCount = preg_match_all('/0+/', $mask, $maskingBlocks, PREG_OFFSET_CAPTURE);
-
- if ($maskingBlockCount > 1) {
- $maskingBlocks = array_reverse($maskingBlocks[0]);
-
- foreach ($maskingBlocks as $block) {
- $divisor = 1 . $block[0];
- $size = strlen($block[0]);
- $offset = $block[1];
-
- $blockValue = sprintf(
- '%0' . $size . 'd',
- fmod($number, $divisor)
- );
- $number = floor($number / $divisor);
- $mask = substr_replace($mask, $blockValue, $offset, $size);
- }
- if ($number > 0) {
- $mask = substr_replace($mask, $number, $offset, 0);
- }
- $result = $mask;
- }
-
- return $result;
- }
-
- private static function complexNumberFormatMask($number, $mask, $splitOnPoint = true)
- {
- $sign = ($number < 0.0);
- $number = abs($number);
-
- if ($splitOnPoint && strpos($mask, '.') !== false && strpos($number, '.') !== false) {
- $numbers = explode('.', $number);
- $masks = explode('.', $mask);
- if (count($masks) > 2) {
- $masks = self::mergeComplexNumberFormatMasks($numbers, $masks);
- }
- $result1 = self::complexNumberFormatMask($numbers[0], $masks[0], false);
- $result2 = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), false));
-
- return (($sign) ? '-' : '') . $result1 . '.' . $result2;
- }
-
- $result = self::processComplexNumberFormatMask($number, $mask);
-
- return (($sign) ? '-' : '') . $result;
- }
-
- private static function formatStraightNumericValue($value, $format, array $matches, $useThousands, $number_regex)
- {
- $left = $matches[1];
- $dec = $matches[2];
- $right = $matches[3];
-
- // minimun width of formatted number (including dot)
- $minWidth = strlen($left) + strlen($dec) + strlen($right);
- if ($useThousands) {
- $value = number_format(
- $value,
- strlen($right),
- StringHelper::getDecimalSeparator(),
- StringHelper::getThousandsSeparator()
- );
- $value = preg_replace($number_regex, $value, $format);
- } else {
- if (preg_match('/[0#]E[+-]0/i', $format)) {
- // Scientific format
- $value = sprintf('%5.2E', $value);
- } elseif (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) {
- if ($value == (int) $value && substr_count($format, '.') === 1) {
- $value *= 10 ** strlen(explode('.', $format)[1]);
- }
- $value = self::complexNumberFormatMask($value, $format);
- } else {
- $sprintf_pattern = "%0$minWidth." . strlen($right) . 'f';
- $value = sprintf($sprintf_pattern, $value);
- $value = preg_replace($number_regex, $value, $format);
- }
- }
-
- return $value;
- }
-
- private static function formatAsNumber($value, $format)
- {
- // The "_" in this string has already been stripped out,
- // so this test is never true. Furthermore, testing
- // on Excel shows this format uses Euro symbol, not "EUR".
- //if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) {
- // return 'EUR ' . sprintf('%1.2f', $value);
- //}
-
- // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols
- $format = str_replace(['"', '*'], '', $format);
-
- // Find out if we need thousands separator
- // This is indicated by a comma enclosed by a digit placeholder:
- // #,# or 0,0
- $useThousands = preg_match('/(#,#|0,0)/', $format);
- if ($useThousands) {
- $format = preg_replace('/0,0/', '00', $format);
- $format = preg_replace('/#,#/', '##', $format);
- }
-
- // Scale thousands, millions,...
- // This is indicated by a number of commas after a digit placeholder:
- // #, or 0.0,,
- $scale = 1; // same as no scale
- $matches = [];
- if (preg_match('/(#|0)(,+)/', $format, $matches)) {
- $scale = 1000 ** strlen($matches[2]);
-
- // strip the commas
- $format = preg_replace('/0,+/', '0', $format);
- $format = preg_replace('/#,+/', '#', $format);
- }
-
- if (preg_match('/#?.*\?\/\?/', $format, $m)) {
- if ($value != (int) $value) {
- self::formatAsFraction($value, $format);
- }
- } else {
- // Handle the number itself
-
- // scale number
- $value = $value / $scale;
- // Strip #
- $format = preg_replace('/\\#/', '0', $format);
- // Remove locale code [$-###]
- $format = preg_replace('/\[\$\-.*\]/', '', $format);
-
- $n = '/\\[[^\\]]+\\]/';
- $m = preg_replace($n, '', $format);
- $number_regex = '/(0+)(\\.?)(0*)/';
- if (preg_match($number_regex, $m, $matches)) {
- $value = self::formatStraightNumericValue($value, $format, $matches, $useThousands, $number_regex);
- }
- }
-
- if (preg_match('/\[\$(.*)\]/u', $format, $m)) {
- // Currency or Accounting
- $currencyCode = $m[1];
- [$currencyCode] = explode('-', $currencyCode);
- if ($currencyCode == '') {
- $currencyCode = StringHelper::getCurrencyCode();
- }
- $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value);
- }
-
- return $value;
- }
-
- private static function splitFormatCompare($value, $cond, $val, $dfcond, $dfval)
- {
- if (!$cond) {
- $cond = $dfcond;
- $val = $dfval;
- }
- switch ($cond) {
- case '>':
- return $value > $val;
-
- case '<':
- return $value < $val;
-
- case '<=':
- return $value <= $val;
-
- case '<>':
- return $value != $val;
-
- case '=':
- return $value == $val;
- }
-
- return $value >= $val;
- }
-
- private static function splitFormat($sections, $value)
- {
- // Extract the relevant section depending on whether number is positive, negative, or zero?
- // Text not supported yet.
- // Here is how the sections apply to various values in Excel:
- // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT]
- // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE]
- // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO]
- // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
- $cnt = count($sections);
- $color_regex = '/\\[(' . implode('|', Color::NAMED_COLORS) . ')\\]/';
- $cond_regex = '/\\[(>|>=|<|<=|=|<>)([+-]?\\d+([.]\\d+)?)\\]/';
- $colors = ['', '', '', '', ''];
- $condops = ['', '', '', '', ''];
- $condvals = [0, 0, 0, 0, 0];
- for ($idx = 0; $idx < $cnt; ++$idx) {
- if (preg_match($color_regex, $sections[$idx], $matches)) {
- $colors[$idx] = $matches[0];
- $sections[$idx] = preg_replace($color_regex, '', $sections[$idx]);
- }
- if (preg_match($cond_regex, $sections[$idx], $matches)) {
- $condops[$idx] = $matches[1];
- $condvals[$idx] = $matches[2];
- $sections[$idx] = preg_replace($cond_regex, '', $sections[$idx]);
- }
- }
- $color = $colors[0];
- $format = $sections[0];
- $absval = $value;
- switch ($cnt) {
- case 2:
- $absval = abs($value);
- if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>=', 0)) {
- $color = $colors[1];
- $format = $sections[1];
- }
-
- break;
- case 3:
- case 4:
- $absval = abs($value);
- if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>', 0)) {
- if (self::splitFormatCompare($value, $condops[1], $condvals[1], '<', 0)) {
- $color = $colors[1];
- $format = $sections[1];
- } else {
- $color = $colors[2];
- $format = $sections[2];
- }
- }
-
- break;
- }
-
- return [$color, $format, $absval];
- }
-
- /**
- * Convert a value in a pre-defined format to a PHP string.
- *
- * @param mixed $value Value to format
- * @param string $format Format code, see = self::FORMAT_*
- * @param array $callBack Callback function for additional formatting of string
- *
- * @return string Formatted string
- */
- public static function toFormattedString($value, $format, $callBack = null)
- {
- // For now we do not treat strings although section 4 of a format code affects strings
- if (!is_numeric($value)) {
- return $value;
- }
-
- // For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
- // it seems to round numbers to a total of 10 digits.
- if (($format === self::FORMAT_GENERAL) || ($format === self::FORMAT_TEXT)) {
- return $value;
- }
-
- // Convert any other escaped characters to quoted strings, e.g. (\T to "T")
- $format = preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format);
-
- // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
- $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format);
-
- [$colors, $format, $value] = self::splitFormat($sections, $value);
-
- // In Excel formats, "_" is used to add spacing,
- // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
- $format = preg_replace('/_./', ' ', $format);
-
- // Let's begin inspecting the format and converting the value to a formatted string
-
- // Check for date/time characters (not inside quotes)
- if (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format, $matches)) {
- // datetime format
- self::formatAsDate($value, $format);
- } else {
- if (substr($format, 0, 1) === '"' && substr($format, -1, 1) === '"') {
- $value = substr($format, 1, -1);
- } elseif (preg_match('/%$/', $format)) {
- // % number format
- self::formatAsPercentage($value, $format);
- } else {
- $value = self::formatAsNumber($value, $format);
- }
- }
-
- // Additional formatting provided by callback function
- if ($callBack !== null) {
- [$writerInstance, $function] = $callBack;
- $value = $writerInstance->$function($value, $colors);
- }
-
- return $value;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Protection.php b/vendor/PhpSpreadsheet/Style/Protection.php
deleted file mode 100644
index f695837..0000000
--- a/vendor/PhpSpreadsheet/Style/Protection.php
+++ /dev/null
@@ -1,186 +0,0 @@
-locked = self::PROTECTION_INHERIT;
- $this->hidden = self::PROTECTION_INHERIT;
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Protection
- */
- public function getSharedComponent()
- {
- return $this->parent->getSharedComponent()->getProtection();
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['protection' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray(
- * [
- * 'locked' => TRUE,
- * 'hidden' => FALSE
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles)
- {
- if ($this->isSupervisor) {
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
- } else {
- if (isset($pStyles['locked'])) {
- $this->setLocked($pStyles['locked']);
- }
- if (isset($pStyles['hidden'])) {
- $this->setHidden($pStyles['hidden']);
- }
- }
-
- return $this;
- }
-
- /**
- * Get locked.
- *
- * @return string
- */
- public function getLocked()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getLocked();
- }
-
- return $this->locked;
- }
-
- /**
- * Set locked.
- *
- * @param string $pValue see self::PROTECTION_*
- *
- * @return $this
- */
- public function setLocked($pValue)
- {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['locked' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->locked = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hidden.
- *
- * @return string
- */
- public function getHidden()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHidden();
- }
-
- return $this->hidden;
- }
-
- /**
- * Set hidden.
- *
- * @param string $pValue see self::PROTECTION_*
- *
- * @return $this
- */
- public function setHidden($pValue)
- {
- if ($this->isSupervisor) {
- $styleArray = $this->getStyleArray(['hidden' => $pValue]);
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->hidden = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getHashCode();
- }
-
- return md5(
- $this->locked .
- $this->hidden .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Style.php b/vendor/PhpSpreadsheet/Style/Style.php
deleted file mode 100644
index 533a7c3..0000000
--- a/vendor/PhpSpreadsheet/Style/Style.php
+++ /dev/null
@@ -1,639 +0,0 @@
-conditionalStyles = [];
- $this->font = new Font($isSupervisor, $isConditional);
- $this->fill = new Fill($isSupervisor, $isConditional);
- $this->borders = new Borders($isSupervisor, $isConditional);
- $this->alignment = new Alignment($isSupervisor, $isConditional);
- $this->numberFormat = new NumberFormat($isSupervisor, $isConditional);
- $this->protection = new Protection($isSupervisor, $isConditional);
-
- // bind parent if we are a supervisor
- if ($isSupervisor) {
- $this->font->bindParent($this);
- $this->fill->bindParent($this);
- $this->borders->bindParent($this);
- $this->alignment->bindParent($this);
- $this->numberFormat->bindParent($this);
- $this->protection->bindParent($this);
- }
- }
-
- /**
- * Get the shared style component for the currently active cell in currently active sheet.
- * Only used for style supervisor.
- *
- * @return Style
- */
- public function getSharedComponent()
- {
- $activeSheet = $this->getActiveSheet();
- $selectedCell = $this->getActiveCell(); // e.g. 'A1'
-
- if ($activeSheet->cellExists($selectedCell)) {
- $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
- } else {
- $xfIndex = 0;
- }
-
- return $this->parent->getCellXfByIndex($xfIndex);
- }
-
- /**
- * Get parent. Only used for style supervisor.
- *
- * @return Spreadsheet
- */
- public function getParent()
- {
- return $this->parent;
- }
-
- /**
- * Build style array from subcomponents.
- *
- * @param array $array
- *
- * @return array
- */
- public function getStyleArray($array)
- {
- return ['quotePrefix' => $array];
- }
-
- /**
- * Apply styles from array.
- *
- *
- * $spreadsheet->getActiveSheet()->getStyle('B2')->applyFromArray(
- * [
- * 'font' => [
- * 'name' => 'Arial',
- * 'bold' => true,
- * 'italic' => false,
- * 'underline' => Font::UNDERLINE_DOUBLE,
- * 'strikethrough' => false,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ],
- * 'borders' => [
- * 'bottom' => [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ],
- * 'top' => [
- * 'borderStyle' => Border::BORDER_DASHDOT,
- * 'color' => [
- * 'rgb' => '808080'
- * ]
- * ]
- * ],
- * 'alignment' => [
- * 'horizontal' => Alignment::HORIZONTAL_CENTER,
- * 'vertical' => Alignment::VERTICAL_CENTER,
- * 'wrapText' => true,
- * ],
- * 'quotePrefix' => true
- * ]
- * );
- *
- *
- * @param array $pStyles Array containing style information
- * @param bool $pAdvanced advanced mode for setting borders
- *
- * @return $this
- */
- public function applyFromArray(array $pStyles, $pAdvanced = true)
- {
- if ($this->isSupervisor) {
- $pRange = $this->getSelectedCells();
-
- // Uppercase coordinate
- $pRange = strtoupper($pRange);
-
- // Is it a cell range or a single cell?
- if (strpos($pRange, ':') === false) {
- $rangeA = $pRange;
- $rangeB = $pRange;
- } else {
- [$rangeA, $rangeB] = explode(':', $pRange);
- }
-
- // Calculate range outer borders
- $rangeStart = Coordinate::coordinateFromString($rangeA);
- $rangeEnd = Coordinate::coordinateFromString($rangeB);
-
- // Translate column into index
- $rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]);
- $rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]);
-
- // Make sure we can loop upwards on rows and columns
- if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
- $tmp = $rangeStart;
- $rangeStart = $rangeEnd;
- $rangeEnd = $tmp;
- }
-
- // ADVANCED MODE:
- if ($pAdvanced && isset($pStyles['borders'])) {
- // 'allBorders' is a shorthand property for 'outline' and 'inside' and
- // it applies to components that have not been set explicitly
- if (isset($pStyles['borders']['allBorders'])) {
- foreach (['outline', 'inside'] as $component) {
- if (!isset($pStyles['borders'][$component])) {
- $pStyles['borders'][$component] = $pStyles['borders']['allBorders'];
- }
- }
- unset($pStyles['borders']['allBorders']); // not needed any more
- }
- // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
- // it applies to components that have not been set explicitly
- if (isset($pStyles['borders']['outline'])) {
- foreach (['top', 'right', 'bottom', 'left'] as $component) {
- if (!isset($pStyles['borders'][$component])) {
- $pStyles['borders'][$component] = $pStyles['borders']['outline'];
- }
- }
- unset($pStyles['borders']['outline']); // not needed any more
- }
- // 'inside' is a shorthand property for 'vertical' and 'horizontal'
- // it applies to components that have not been set explicitly
- if (isset($pStyles['borders']['inside'])) {
- foreach (['vertical', 'horizontal'] as $component) {
- if (!isset($pStyles['borders'][$component])) {
- $pStyles['borders'][$component] = $pStyles['borders']['inside'];
- }
- }
- unset($pStyles['borders']['inside']); // not needed any more
- }
- // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
- $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
- $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
-
- // loop through up to 3 x 3 = 9 regions
- for ($x = 1; $x <= $xMax; ++$x) {
- // start column index for region
- $colStart = ($x == 3) ?
- Coordinate::stringFromColumnIndex($rangeEnd[0])
- : Coordinate::stringFromColumnIndex($rangeStart[0] + $x - 1);
- // end column index for region
- $colEnd = ($x == 1) ?
- Coordinate::stringFromColumnIndex($rangeStart[0])
- : Coordinate::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
-
- for ($y = 1; $y <= $yMax; ++$y) {
- // which edges are touching the region
- $edges = [];
- if ($x == 1) {
- // are we at left edge
- $edges[] = 'left';
- }
- if ($x == $xMax) {
- // are we at right edge
- $edges[] = 'right';
- }
- if ($y == 1) {
- // are we at top edge?
- $edges[] = 'top';
- }
- if ($y == $yMax) {
- // are we at bottom edge?
- $edges[] = 'bottom';
- }
-
- // start row index for region
- $rowStart = ($y == 3) ?
- $rangeEnd[1] : $rangeStart[1] + $y - 1;
-
- // end row index for region
- $rowEnd = ($y == 1) ?
- $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
-
- // build range for region
- $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
-
- // retrieve relevant style array for region
- $regionStyles = $pStyles;
- unset($regionStyles['borders']['inside']);
-
- // what are the inner edges of the region when looking at the selection
- $innerEdges = array_diff(['top', 'right', 'bottom', 'left'], $edges);
-
- // inner edges that are not touching the region should take the 'inside' border properties if they have been set
- foreach ($innerEdges as $innerEdge) {
- switch ($innerEdge) {
- case 'top':
- case 'bottom':
- // should pick up 'horizontal' border property if set
- if (isset($pStyles['borders']['horizontal'])) {
- $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
- } else {
- unset($regionStyles['borders'][$innerEdge]);
- }
-
- break;
- case 'left':
- case 'right':
- // should pick up 'vertical' border property if set
- if (isset($pStyles['borders']['vertical'])) {
- $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
- } else {
- unset($regionStyles['borders'][$innerEdge]);
- }
-
- break;
- }
- }
-
- // apply region style to region by calling applyFromArray() in simple mode
- $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
- }
- }
-
- // restore initial cell selection range
- $this->getActiveSheet()->getStyle($pRange);
-
- return $this;
- }
-
- // SIMPLE MODE:
- // Selection type, inspect
- if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
- $selectionType = 'COLUMN';
- } elseif (preg_match('/^A\d+:XFD\d+$/', $pRange)) {
- $selectionType = 'ROW';
- } else {
- $selectionType = 'CELL';
- }
-
- // First loop through columns, rows, or cells to find out which styles are affected by this operation
- switch ($selectionType) {
- case 'COLUMN':
- $oldXfIndexes = [];
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
- }
-
- break;
- case 'ROW':
- $oldXfIndexes = [];
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
- $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
- } else {
- $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
- }
- }
-
- break;
- case 'CELL':
- $oldXfIndexes = [];
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
- }
- }
-
- break;
- }
-
- // clone each of the affected styles, apply the style array, and add the new styles to the workbook
- $workbook = $this->getActiveSheet()->getParent();
- foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
- $style = $workbook->getCellXfByIndex($oldXfIndex);
- $newStyle = clone $style;
- $newStyle->applyFromArray($pStyles);
-
- if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
- // there is already such cell Xf in our collection
- $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
- } else {
- // we don't have such a cell Xf, need to add
- $workbook->addCellXf($newStyle);
- $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
- }
- }
-
- // Loop through columns, rows, or cells again and update the XF index
- switch ($selectionType) {
- case 'COLUMN':
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
- $oldXfIndex = $columnDimension->getXfIndex();
- $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
- }
-
- break;
- case 'ROW':
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $rowDimension = $this->getActiveSheet()->getRowDimension($row);
- $oldXfIndex = $rowDimension->getXfIndex() === null ?
- 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
- $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
- }
-
- break;
- case 'CELL':
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
- $oldXfIndex = $cell->getXfIndex();
- $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
- }
- }
-
- break;
- }
- } else {
- // not a supervisor, just apply the style array directly on style object
- if (isset($pStyles['fill'])) {
- $this->getFill()->applyFromArray($pStyles['fill']);
- }
- if (isset($pStyles['font'])) {
- $this->getFont()->applyFromArray($pStyles['font']);
- }
- if (isset($pStyles['borders'])) {
- $this->getBorders()->applyFromArray($pStyles['borders']);
- }
- if (isset($pStyles['alignment'])) {
- $this->getAlignment()->applyFromArray($pStyles['alignment']);
- }
- if (isset($pStyles['numberFormat'])) {
- $this->getNumberFormat()->applyFromArray($pStyles['numberFormat']);
- }
- if (isset($pStyles['protection'])) {
- $this->getProtection()->applyFromArray($pStyles['protection']);
- }
- if (isset($pStyles['quotePrefix'])) {
- $this->quotePrefix = $pStyles['quotePrefix'];
- }
- }
-
- return $this;
- }
-
- /**
- * Get Fill.
- *
- * @return Fill
- */
- public function getFill()
- {
- return $this->fill;
- }
-
- /**
- * Get Font.
- *
- * @return Font
- */
- public function getFont()
- {
- return $this->font;
- }
-
- /**
- * Set font.
- *
- * @return $this
- */
- public function setFont(Font $font)
- {
- $this->font = $font;
-
- return $this;
- }
-
- /**
- * Get Borders.
- *
- * @return Borders
- */
- public function getBorders()
- {
- return $this->borders;
- }
-
- /**
- * Get Alignment.
- *
- * @return Alignment
- */
- public function getAlignment()
- {
- return $this->alignment;
- }
-
- /**
- * Get Number Format.
- *
- * @return NumberFormat
- */
- public function getNumberFormat()
- {
- return $this->numberFormat;
- }
-
- /**
- * Get Conditional Styles. Only used on supervisor.
- *
- * @return Conditional[]
- */
- public function getConditionalStyles()
- {
- return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
- }
-
- /**
- * Set Conditional Styles. Only used on supervisor.
- *
- * @param Conditional[] $pValue Array of conditional styles
- *
- * @return $this
- */
- public function setConditionalStyles(array $pValue)
- {
- $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
-
- return $this;
- }
-
- /**
- * Get Protection.
- *
- * @return Protection
- */
- public function getProtection()
- {
- return $this->protection;
- }
-
- /**
- * Get quote prefix.
- *
- * @return bool
- */
- public function getQuotePrefix()
- {
- if ($this->isSupervisor) {
- return $this->getSharedComponent()->getQuotePrefix();
- }
-
- return $this->quotePrefix;
- }
-
- /**
- * Set quote prefix.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setQuotePrefix($pValue)
- {
- if ($pValue == '') {
- $pValue = false;
- }
- if ($this->isSupervisor) {
- $styleArray = ['quotePrefix' => $pValue];
- $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
- } else {
- $this->quotePrefix = (bool) $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- $hashConditionals = '';
- foreach ($this->conditionalStyles as $conditional) {
- $hashConditionals .= $conditional->getHashCode();
- }
-
- return md5(
- $this->fill->getHashCode() .
- $this->font->getHashCode() .
- $this->borders->getHashCode() .
- $this->alignment->getHashCode() .
- $this->numberFormat->getHashCode() .
- $hashConditionals .
- $this->protection->getHashCode() .
- ($this->quotePrefix ? 't' : 'f') .
- __CLASS__
- );
- }
-
- /**
- * Get own index in style collection.
- *
- * @return int
- */
- public function getIndex()
- {
- return $this->index;
- }
-
- /**
- * Set own index in style collection.
- *
- * @param int $pValue
- */
- public function setIndex($pValue): void
- {
- $this->index = $pValue;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Style/Supervisor.php b/vendor/PhpSpreadsheet/Style/Supervisor.php
deleted file mode 100644
index 1a70097..0000000
--- a/vendor/PhpSpreadsheet/Style/Supervisor.php
+++ /dev/null
@@ -1,117 +0,0 @@
-isSupervisor = $isSupervisor;
- }
-
- /**
- * Bind parent. Only used for supervisor.
- *
- * @param Spreadsheet|Style $parent
- * @param null|string $parentPropertyName
- *
- * @return $this
- */
- public function bindParent($parent, $parentPropertyName = null)
- {
- $this->parent = $parent;
- $this->parentPropertyName = $parentPropertyName;
-
- return $this;
- }
-
- /**
- * Is this a supervisor or a cell style component?
- *
- * @return bool
- */
- public function getIsSupervisor()
- {
- return $this->isSupervisor;
- }
-
- /**
- * Get the currently active sheet. Only used for supervisor.
- *
- * @return Worksheet
- */
- public function getActiveSheet()
- {
- return $this->parent->getActiveSheet();
- }
-
- /**
- * Get the currently active cell coordinate in currently active sheet.
- * Only used for supervisor.
- *
- * @return string E.g. 'A1'
- */
- public function getSelectedCells()
- {
- return $this->getActiveSheet()->getSelectedCells();
- }
-
- /**
- * Get the currently active cell coordinate in currently active sheet.
- * Only used for supervisor.
- *
- * @return string E.g. 'A1'
- */
- public function getActiveCell()
- {
- return $this->getActiveSheet()->getActiveCell();
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if ((is_object($value)) && ($key != 'parent')) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/AutoFilter.php b/vendor/PhpSpreadsheet/Worksheet/AutoFilter.php
deleted file mode 100644
index c2ded19..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/AutoFilter.php
+++ /dev/null
@@ -1,871 +0,0 @@
-range = $pRange;
- $this->workSheet = $pSheet;
- }
-
- /**
- * Get AutoFilter Parent Worksheet.
- *
- * @return Worksheet
- */
- public function getParent()
- {
- return $this->workSheet;
- }
-
- /**
- * Set AutoFilter Parent Worksheet.
- *
- * @param Worksheet $pSheet
- *
- * @return $this
- */
- public function setParent(?Worksheet $pSheet = null)
- {
- $this->workSheet = $pSheet;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Range.
- *
- * @return string
- */
- public function getRange()
- {
- return $this->range;
- }
-
- /**
- * Set AutoFilter Range.
- *
- * @param string $pRange Cell range (i.e. A1:E10)
- *
- * @return $this
- */
- public function setRange($pRange)
- {
- // extract coordinate
- [$worksheet, $pRange] = Worksheet::extractSheetTitle($pRange, true);
-
- if (strpos($pRange, ':') !== false) {
- $this->range = $pRange;
- } elseif (empty($pRange)) {
- $this->range = '';
- } else {
- throw new PhpSpreadsheetException('Autofilter must be set on a range of cells.');
- }
-
- if (empty($pRange)) {
- // Discard all column rules
- $this->columns = [];
- } else {
- // Discard any column rules that are no longer valid within this range
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
- foreach ($this->columns as $key => $value) {
- $colIndex = Coordinate::columnIndexFromString($key);
- if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) {
- unset($this->columns[$key]);
- }
- }
- }
-
- return $this;
- }
-
- /**
- * Get all AutoFilter Columns.
- *
- * @return AutoFilter\Column[]
- */
- public function getColumns()
- {
- return $this->columns;
- }
-
- /**
- * Validate that the specified column is in the AutoFilter range.
- *
- * @param string $column Column name (e.g. A)
- *
- * @return int The column offset within the autofilter range
- */
- public function testColumnInRange($column)
- {
- if (empty($this->range)) {
- throw new PhpSpreadsheetException('No autofilter range is defined.');
- }
-
- $columnIndex = Coordinate::columnIndexFromString($column);
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
- if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) {
- throw new PhpSpreadsheetException('Column is outside of current autofilter range.');
- }
-
- return $columnIndex - $rangeStart[0];
- }
-
- /**
- * Get a specified AutoFilter Column Offset within the defined AutoFilter range.
- *
- * @param string $pColumn Column name (e.g. A)
- *
- * @return int The offset of the specified column within the autofilter range
- */
- public function getColumnOffset($pColumn)
- {
- return $this->testColumnInRange($pColumn);
- }
-
- /**
- * Get a specified AutoFilter Column.
- *
- * @param string $pColumn Column name (e.g. A)
- *
- * @return AutoFilter\Column
- */
- public function getColumn($pColumn)
- {
- $this->testColumnInRange($pColumn);
-
- if (!isset($this->columns[$pColumn])) {
- $this->columns[$pColumn] = new AutoFilter\Column($pColumn, $this);
- }
-
- return $this->columns[$pColumn];
- }
-
- /**
- * Get a specified AutoFilter Column by it's offset.
- *
- * @param int $pColumnOffset Column offset within range (starting from 0)
- *
- * @return AutoFilter\Column
- */
- public function getColumnByOffset($pColumnOffset)
- {
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
- $pColumn = Coordinate::stringFromColumnIndex($rangeStart[0] + $pColumnOffset);
-
- return $this->getColumn($pColumn);
- }
-
- /**
- * Set AutoFilter.
- *
- * @param AutoFilter\Column|string $pColumn
- * A simple string containing a Column ID like 'A' is permitted
- *
- * @return $this
- */
- public function setColumn($pColumn)
- {
- if ((is_string($pColumn)) && (!empty($pColumn))) {
- $column = $pColumn;
- } elseif (is_object($pColumn) && ($pColumn instanceof AutoFilter\Column)) {
- $column = $pColumn->getColumnIndex();
- } else {
- throw new PhpSpreadsheetException('Column is not within the autofilter range.');
- }
- $this->testColumnInRange($column);
-
- if (is_string($pColumn)) {
- $this->columns[$pColumn] = new AutoFilter\Column($pColumn, $this);
- } elseif (is_object($pColumn) && ($pColumn instanceof AutoFilter\Column)) {
- $pColumn->setParent($this);
- $this->columns[$column] = $pColumn;
- }
- ksort($this->columns);
-
- return $this;
- }
-
- /**
- * Clear a specified AutoFilter Column.
- *
- * @param string $pColumn Column name (e.g. A)
- *
- * @return $this
- */
- public function clearColumn($pColumn)
- {
- $this->testColumnInRange($pColumn);
-
- if (isset($this->columns[$pColumn])) {
- unset($this->columns[$pColumn]);
- }
-
- return $this;
- }
-
- /**
- * Shift an AutoFilter Column Rule to a different column.
- *
- * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range.
- * Nor does it verify whether any column rule already exists at $toColumn, but will simply override any existing value.
- * Use with caution.
- *
- * @param string $fromColumn Column name (e.g. A)
- * @param string $toColumn Column name (e.g. B)
- *
- * @return $this
- */
- public function shiftColumn($fromColumn, $toColumn)
- {
- $fromColumn = strtoupper($fromColumn);
- $toColumn = strtoupper($toColumn);
-
- if (($fromColumn !== null) && (isset($this->columns[$fromColumn])) && ($toColumn !== null)) {
- $this->columns[$fromColumn]->setParent();
- $this->columns[$fromColumn]->setColumnIndex($toColumn);
- $this->columns[$toColumn] = $this->columns[$fromColumn];
- $this->columns[$toColumn]->setParent($this);
- unset($this->columns[$fromColumn]);
-
- ksort($this->columns);
- }
-
- return $this;
- }
-
- /**
- * Test if cell value is in the defined set of values.
- *
- * @param mixed $cellValue
- * @param mixed[] $dataSet
- *
- * @return bool
- */
- private static function filterTestInSimpleDataSet($cellValue, $dataSet)
- {
- $dataSetValues = $dataSet['filterValues'];
- $blanks = $dataSet['blanks'];
- if (($cellValue == '') || ($cellValue === null)) {
- return $blanks;
- }
-
- return in_array($cellValue, $dataSetValues);
- }
-
- /**
- * Test if cell value is in the defined set of Excel date values.
- *
- * @param mixed $cellValue
- * @param mixed[] $dataSet
- *
- * @return bool
- */
- private static function filterTestInDateGroupSet($cellValue, $dataSet)
- {
- $dateSet = $dataSet['filterValues'];
- $blanks = $dataSet['blanks'];
- if (($cellValue == '') || ($cellValue === null)) {
- return $blanks;
- }
-
- if (is_numeric($cellValue)) {
- $dateValue = Date::excelToTimestamp($cellValue);
- if ($cellValue < 1) {
- // Just the time part
- $dtVal = date('His', $dateValue);
- $dateSet = $dateSet['time'];
- } elseif ($cellValue == floor($cellValue)) {
- // Just the date part
- $dtVal = date('Ymd', $dateValue);
- $dateSet = $dateSet['date'];
- } else {
- // date and time parts
- $dtVal = date('YmdHis', $dateValue);
- $dateSet = $dateSet['dateTime'];
- }
- foreach ($dateSet as $dateValue) {
- // Use of substr to extract value at the appropriate group level
- if (substr($dtVal, 0, strlen($dateValue)) == $dateValue) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Test if cell value is within a set of values defined by a ruleset.
- *
- * @param mixed $cellValue
- * @param mixed[] $ruleSet
- *
- * @return bool
- */
- private static function filterTestInCustomDataSet($cellValue, $ruleSet)
- {
- $dataSet = $ruleSet['filterRules'];
- $join = $ruleSet['join'];
- $customRuleForBlanks = $ruleSet['customRuleForBlanks'] ?? false;
-
- if (!$customRuleForBlanks) {
- // Blank cells are always ignored, so return a FALSE
- if (($cellValue == '') || ($cellValue === null)) {
- return false;
- }
- }
- $returnVal = ($join == AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND);
- foreach ($dataSet as $rule) {
- $retVal = false;
-
- if (is_numeric($rule['value'])) {
- // Numeric values are tested using the appropriate operator
- switch ($rule['operator']) {
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
- $retVal = ($cellValue == $rule['value']);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
- $retVal = ($cellValue != $rule['value']);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN:
- $retVal = ($cellValue > $rule['value']);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL:
- $retVal = ($cellValue >= $rule['value']);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN:
- $retVal = ($cellValue < $rule['value']);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL:
- $retVal = ($cellValue <= $rule['value']);
-
- break;
- }
- } elseif ($rule['value'] == '') {
- switch ($rule['operator']) {
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL:
- $retVal = (($cellValue == '') || ($cellValue === null));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL:
- $retVal = (($cellValue != '') && ($cellValue !== null));
-
- break;
- default:
- $retVal = true;
-
- break;
- }
- } else {
- // String values are always tested for equality, factoring in for wildcards (hence a regexp test)
- $retVal = preg_match('/^' . $rule['value'] . '$/i', $cellValue);
- }
- // If there are multiple conditions, then we need to test both using the appropriate join operator
- switch ($join) {
- case AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR:
- $returnVal = $returnVal || $retVal;
- // Break as soon as we have a TRUE match for OR joins,
- // to avoid unnecessary additional code execution
- if ($returnVal) {
- return $returnVal;
- }
-
- break;
- case AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND:
- $returnVal = $returnVal && $retVal;
-
- break;
- }
- }
-
- return $returnVal;
- }
-
- /**
- * Test if cell date value is matches a set of values defined by a set of months.
- *
- * @param mixed $cellValue
- * @param mixed[] $monthSet
- *
- * @return bool
- */
- private static function filterTestInPeriodDateSet($cellValue, $monthSet)
- {
- // Blank cells are always ignored, so return a FALSE
- if (($cellValue == '') || ($cellValue === null)) {
- return false;
- }
-
- if (is_numeric($cellValue)) {
- $dateValue = date('m', Date::excelToTimestamp($cellValue));
- if (in_array($dateValue, $monthSet)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching.
- *
- * @var array
- */
- private static $fromReplace = ['\*', '\?', '~~', '~.*', '~.?'];
-
- private static $toReplace = ['.*', '.', '~', '\*', '\?'];
-
- /**
- * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation.
- *
- * @param string $dynamicRuleType
- * @param AutoFilter\Column $filterColumn
- *
- * @return mixed[]
- */
- private function dynamicFilterDateRange($dynamicRuleType, &$filterColumn)
- {
- $rDateType = Functions::getReturnDateType();
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
- $val = $maxVal = null;
-
- $ruleValues = [];
- $baseDate = DateTime::DATENOW();
- // Calculate start/end dates for the required date range based on current date
- switch ($dynamicRuleType) {
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
- $baseDate = strtotime('-7 days', $baseDate);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
- $baseDate = strtotime('-7 days', $baseDate);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
- $baseDate = strtotime('-1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
- $baseDate = strtotime('+1 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
- $baseDate = strtotime('-3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
- $baseDate = strtotime('+3 month', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
- $baseDate = strtotime('-1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
- $baseDate = strtotime('+1 year', gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- }
-
- switch ($dynamicRuleType) {
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
- $maxVal = (int) Date::PHPtoExcel(strtotime('+1 day', $baseDate));
- $val = (int) Date::PHPToExcel($baseDate);
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE:
- $maxVal = (int) Date::PHPtoExcel(strtotime('+1 day', $baseDate));
- $val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR:
- $maxVal = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 31, 12, date('Y', $baseDate)));
- ++$maxVal;
- $val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1, date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER:
- $thisMonth = date('m', $baseDate);
- $thisQuarter = floor(--$thisMonth / 3);
- $maxVal = (int) Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), (1 + $thisQuarter) * 3, date('Y', $baseDate)));
- ++$maxVal;
- $val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, 1 + $thisQuarter * 3, date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH:
- $maxVal = (int) Date::PHPtoExcel(gmmktime(0, 0, 0, date('t', $baseDate), date('m', $baseDate), date('Y', $baseDate)));
- ++$maxVal;
- $val = (int) Date::PHPToExcel(gmmktime(0, 0, 0, 1, date('m', $baseDate), date('Y', $baseDate)));
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK:
- $dayOfWeek = date('w', $baseDate);
- $val = (int) Date::PHPToExcel($baseDate) - $dayOfWeek;
- $maxVal = $val + 7;
-
- break;
- }
-
- switch ($dynamicRuleType) {
- // Adjust Today dates for Yesterday and Tomorrow
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY:
- --$maxVal;
- --$val;
-
- break;
- case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW:
- ++$maxVal;
- ++$val;
-
- break;
- }
-
- // Set the filter column rule attributes ready for writing
- $filterColumn->setAttributes(['val' => $val, 'maxVal' => $maxVal]);
-
- // Set the rules for identifying rows for hide/show
- $ruleValues[] = ['operator' => AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, 'value' => $val];
- $ruleValues[] = ['operator' => AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, 'value' => $maxVal];
- Functions::setReturnDateType($rDateType);
-
- return ['method' => 'filterTestInCustomDataSet', 'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND]];
- }
-
- private function calculateTopTenValue($columnID, $startRow, $endRow, $ruleType, $ruleValue)
- {
- $range = $columnID . $startRow . ':' . $columnID . $endRow;
- $dataValues = Functions::flattenArray($this->workSheet->rangeToArray($range, null, true, false));
-
- $dataValues = array_filter($dataValues);
- if ($ruleType == AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) {
- rsort($dataValues);
- } else {
- sort($dataValues);
- }
-
- return array_pop(array_slice($dataValues, 0, $ruleValue));
- }
-
- /**
- * Apply the AutoFilter rules to the AutoFilter Range.
- *
- * @return $this
- */
- public function showHideRows()
- {
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($this->range);
-
- // The heading row should always be visible
- $this->workSheet->getRowDimension($rangeStart[1])->setVisible(true);
-
- $columnFilterTests = [];
- foreach ($this->columns as $columnID => $filterColumn) {
- $rules = $filterColumn->getRules();
- switch ($filterColumn->getFilterType()) {
- case AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER:
- $ruleType = null;
- $ruleValues = [];
- // Build a list of the filter value selections
- foreach ($rules as $rule) {
- $ruleType = $rule->getRuleType();
- $ruleValues[] = $rule->getValue();
- }
- // Test if we want to include blanks in our filter criteria
- $blanks = false;
- $ruleDataSet = array_filter($ruleValues);
- if (count($ruleValues) != count($ruleDataSet)) {
- $blanks = true;
- }
- if ($ruleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_FILTER) {
- // Filter on absolute values
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInSimpleDataSet',
- 'arguments' => ['filterValues' => $ruleDataSet, 'blanks' => $blanks],
- ];
- } else {
- // Filter on date group values
- $arguments = [
- 'date' => [],
- 'time' => [],
- 'dateTime' => [],
- ];
- foreach ($ruleDataSet as $ruleValue) {
- $date = $time = '';
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')
- ) {
- $date .= sprintf('%04d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]);
- }
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')
- ) {
- $date .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]);
- }
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')
- ) {
- $date .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]);
- }
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')
- ) {
- $time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]);
- }
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')
- ) {
- $time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]);
- }
- if (
- (isset($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) &&
- ($ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')
- ) {
- $time .= sprintf('%02d', $ruleValue[AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]);
- }
- $dateTime = $date . $time;
- $arguments['date'][] = $date;
- $arguments['time'][] = $time;
- $arguments['dateTime'][] = $dateTime;
- }
- // Remove empty elements
- $arguments['date'] = array_filter($arguments['date']);
- $arguments['time'] = array_filter($arguments['time']);
- $arguments['dateTime'] = array_filter($arguments['dateTime']);
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInDateGroupSet',
- 'arguments' => ['filterValues' => $arguments, 'blanks' => $blanks],
- ];
- }
-
- break;
- case AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER:
- $customRuleForBlanks = false;
- $ruleValues = [];
- // Build a list of the filter value selections
- foreach ($rules as $rule) {
- $ruleValue = $rule->getValue();
- if (!is_numeric($ruleValue)) {
- // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
- $ruleValue = preg_quote($ruleValue);
- $ruleValue = str_replace(self::$fromReplace, self::$toReplace, $ruleValue);
- if (trim($ruleValue) == '') {
- $customRuleForBlanks = true;
- $ruleValue = trim($ruleValue);
- }
- }
- $ruleValues[] = ['operator' => $rule->getOperator(), 'value' => $ruleValue];
- }
- $join = $filterColumn->getJoin();
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInCustomDataSet',
- 'arguments' => ['filterRules' => $ruleValues, 'join' => $join, 'customRuleForBlanks' => $customRuleForBlanks],
- ];
-
- break;
- case AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER:
- $ruleValues = [];
- foreach ($rules as $rule) {
- // We should only ever have one Dynamic Filter Rule anyway
- $dynamicRuleType = $rule->getGrouping();
- if (
- ($dynamicRuleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ||
- ($dynamicRuleType == AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)
- ) {
- // Number (Average) based
- // Calculate the average
- $averageFormula = '=AVERAGE(' . $columnID . ($rangeStart[1] + 1) . ':' . $columnID . $rangeEnd[1] . ')';
- $average = Calculation::getInstance()->calculateFormula($averageFormula, null, $this->workSheet->getCell('A1'));
- // Set above/below rule based on greaterThan or LessTan
- $operator = ($dynamicRuleType === AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)
- ? AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN
- : AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;
- $ruleValues[] = [
- 'operator' => $operator,
- 'value' => $average,
- ];
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInCustomDataSet',
- 'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR],
- ];
- } else {
- // Date based
- if ($dynamicRuleType[0] == 'M' || $dynamicRuleType[0] == 'Q') {
- $periodType = '';
- $period = 0;
- // Month or Quarter
- sscanf($dynamicRuleType, '%[A-Z]%d', $periodType, $period);
- if ($periodType == 'M') {
- $ruleValues = [$period];
- } else {
- --$period;
- $periodEnd = (1 + $period) * 3;
- $periodStart = 1 + $period * 3;
- $ruleValues = range($periodStart, $periodEnd);
- }
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInPeriodDateSet',
- 'arguments' => $ruleValues,
- ];
- $filterColumn->setAttributes([]);
- } else {
- // Date Range
- $columnFilterTests[$columnID] = $this->dynamicFilterDateRange($dynamicRuleType, $filterColumn);
-
- break;
- }
- }
- }
-
- break;
- case AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER:
- $ruleValues = [];
- $dataRowCount = $rangeEnd[1] - $rangeStart[1];
- foreach ($rules as $rule) {
- // We should only ever have one Dynamic Filter Rule anyway
- $toptenRuleType = $rule->getGrouping();
- $ruleValue = $rule->getValue();
- $ruleOperator = $rule->getOperator();
- }
- if ($ruleOperator === AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
- $ruleValue = floor($ruleValue * ($dataRowCount / 100));
- }
- if ($ruleValue < 1) {
- $ruleValue = 1;
- }
- if ($ruleValue > 500) {
- $ruleValue = 500;
- }
-
- $maxVal = $this->calculateTopTenValue($columnID, $rangeStart[1] + 1, $rangeEnd[1], $toptenRuleType, $ruleValue);
-
- $operator = ($toptenRuleType == AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP)
- ? AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL
- : AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL;
- $ruleValues[] = ['operator' => $operator, 'value' => $maxVal];
- $columnFilterTests[$columnID] = [
- 'method' => 'filterTestInCustomDataSet',
- 'arguments' => ['filterRules' => $ruleValues, 'join' => AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR],
- ];
- $filterColumn->setAttributes(['maxVal' => $maxVal]);
-
- break;
- }
- }
-
- // Execute the column tests for each row in the autoFilter range to determine show/hide,
- for ($row = $rangeStart[1] + 1; $row <= $rangeEnd[1]; ++$row) {
- $result = true;
- foreach ($columnFilterTests as $columnID => $columnFilterTest) {
- $cellValue = $this->workSheet->getCell($columnID . $row)->getCalculatedValue();
- // Execute the filter test
- $result = $result &&
- call_user_func_array(
- [self::class, $columnFilterTest['method']],
- [$cellValue, $columnFilterTest['arguments']]
- );
- // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests
- if (!$result) {
- break;
- }
- }
- // Set show/hide for the row based on the result of the autoFilter result
- $this->workSheet->getRowDimension($row)->setVisible($result);
- }
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- if ($key === 'workSheet') {
- // Detach from worksheet
- $this->{$key} = null;
- } else {
- $this->{$key} = clone $value;
- }
- } elseif ((is_array($value)) && ($key == 'columns')) {
- // The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects
- $this->{$key} = [];
- foreach ($value as $k => $v) {
- $this->{$key}[$k] = clone $v;
- // attach the new cloned Column to this new cloned Autofilter object
- $this->{$key}[$k]->setParent($this);
- }
- } else {
- $this->{$key} = $value;
- }
- }
- }
-
- /**
- * toString method replicates previous behavior by returning the range if object is
- * referenced as a property of its parent.
- */
- public function __toString()
- {
- return (string) $this->range;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column.php b/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
deleted file mode 100644
index 09584a7..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
+++ /dev/null
@@ -1,380 +0,0 @@
-columnIndex = $pColumn;
- $this->parent = $pParent;
- }
-
- /**
- * Get AutoFilter column index as string eg: 'A'.
- *
- * @return string
- */
- public function getColumnIndex()
- {
- return $this->columnIndex;
- }
-
- /**
- * Set AutoFilter column index as string eg: 'A'.
- *
- * @param string $pColumn Column (e.g. A)
- *
- * @return $this
- */
- public function setColumnIndex($pColumn)
- {
- // Uppercase coordinate
- $pColumn = strtoupper($pColumn);
- if ($this->parent !== null) {
- $this->parent->testColumnInRange($pColumn);
- }
-
- $this->columnIndex = $pColumn;
-
- return $this;
- }
-
- /**
- * Get this Column's AutoFilter Parent.
- *
- * @return AutoFilter
- */
- public function getParent()
- {
- return $this->parent;
- }
-
- /**
- * Set this Column's AutoFilter Parent.
- *
- * @param AutoFilter $pParent
- *
- * @return $this
- */
- public function setParent(?AutoFilter $pParent = null)
- {
- $this->parent = $pParent;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Type.
- *
- * @return string
- */
- public function getFilterType()
- {
- return $this->filterType;
- }
-
- /**
- * Set AutoFilter Type.
- *
- * @param string $pFilterType
- *
- * @return $this
- */
- public function setFilterType($pFilterType)
- {
- if (!in_array($pFilterType, self::$filterTypes)) {
- throw new PhpSpreadsheetException('Invalid filter type for column AutoFilter.');
- }
-
- $this->filterType = $pFilterType;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Multiple Rules And/Or Join.
- *
- * @return string
- */
- public function getJoin()
- {
- return $this->join;
- }
-
- /**
- * Set AutoFilter Multiple Rules And/Or.
- *
- * @param string $pJoin And/Or
- *
- * @return $this
- */
- public function setJoin($pJoin)
- {
- // Lowercase And/Or
- $pJoin = strtolower($pJoin);
- if (!in_array($pJoin, self::$ruleJoins)) {
- throw new PhpSpreadsheetException('Invalid rule connection for column AutoFilter.');
- }
-
- $this->join = $pJoin;
-
- return $this;
- }
-
- /**
- * Set AutoFilter Attributes.
- *
- * @param string[] $attributes
- *
- * @return $this
- */
- public function setAttributes(array $attributes)
- {
- $this->attributes = $attributes;
-
- return $this;
- }
-
- /**
- * Set An AutoFilter Attribute.
- *
- * @param string $pName Attribute Name
- * @param string $pValue Attribute Value
- *
- * @return $this
- */
- public function setAttribute($pName, $pValue)
- {
- $this->attributes[$pName] = $pValue;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Column Attributes.
- *
- * @return string[]
- */
- public function getAttributes()
- {
- return $this->attributes;
- }
-
- /**
- * Get specific AutoFilter Column Attribute.
- *
- * @param string $pName Attribute Name
- *
- * @return string
- */
- public function getAttribute($pName)
- {
- if (isset($this->attributes[$pName])) {
- return $this->attributes[$pName];
- }
-
- return null;
- }
-
- /**
- * Get all AutoFilter Column Rules.
- *
- * @return Column\Rule[]
- */
- public function getRules()
- {
- return $this->ruleset;
- }
-
- /**
- * Get a specified AutoFilter Column Rule.
- *
- * @param int $pIndex Rule index in the ruleset array
- *
- * @return Column\Rule
- */
- public function getRule($pIndex)
- {
- if (!isset($this->ruleset[$pIndex])) {
- $this->ruleset[$pIndex] = new Column\Rule($this);
- }
-
- return $this->ruleset[$pIndex];
- }
-
- /**
- * Create a new AutoFilter Column Rule in the ruleset.
- *
- * @return Column\Rule
- */
- public function createRule()
- {
- $this->ruleset[] = new Column\Rule($this);
-
- return end($this->ruleset);
- }
-
- /**
- * Add a new AutoFilter Column Rule to the ruleset.
- *
- * @return $this
- */
- public function addRule(Column\Rule $pRule)
- {
- $pRule->setParent($this);
- $this->ruleset[] = $pRule;
-
- return $this;
- }
-
- /**
- * Delete a specified AutoFilter Column Rule
- * If the number of rules is reduced to 1, then we reset And/Or logic to Or.
- *
- * @param int $pIndex Rule index in the ruleset array
- *
- * @return $this
- */
- public function deleteRule($pIndex)
- {
- if (isset($this->ruleset[$pIndex])) {
- unset($this->ruleset[$pIndex]);
- // If we've just deleted down to a single rule, then reset And/Or joining to Or
- if (count($this->ruleset) <= 1) {
- $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
- }
- }
-
- return $this;
- }
-
- /**
- * Delete all AutoFilter Column Rules.
- *
- * @return $this
- */
- public function clearRules()
- {
- $this->ruleset = [];
- $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if ($key === 'parent') {
- // Detach from autofilter parent
- $this->parent = null;
- } elseif ($key === 'ruleset') {
- // The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects
- $this->ruleset = [];
- foreach ($value as $k => $v) {
- $cloned = clone $v;
- $cloned->setParent($this); // attach the new cloned Rule to this new cloned Autofilter Cloned object
- $this->ruleset[$k] = $cloned;
- }
- } elseif (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php b/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
deleted file mode 100644
index 1aacb0c..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+++ /dev/null
@@ -1,449 +0,0 @@
-
- *
- *
- *
- *
- *
- */
- const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal';
- const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual';
- const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan';
- const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual';
- const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan';
- const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual';
-
- private static $operators = [
- self::AUTOFILTER_COLUMN_RULE_EQUAL,
- self::AUTOFILTER_COLUMN_RULE_NOTEQUAL,
- self::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
- self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,
- self::AUTOFILTER_COLUMN_RULE_LESSTHAN,
- self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,
- ];
-
- const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue';
- const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent';
-
- private static $topTenValue = [
- self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
- self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,
- ];
-
- const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top';
- const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom';
-
- private static $topTenType = [
- self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,
- self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,
- ];
-
- // Rule Operators (Numeric, Boolean etc)
-// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2
- // Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values
-// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value
-// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value
-// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average
-// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average
- // Rule Operators (String) which are set as wild-carded values
-// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A*
-// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z
-// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B*
-// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B*
- // Rule Operators (Date Special) which are translated to standard numeric operators with calculated values
-// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan';
-// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan';
-// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday';
-// const AUTOFILTER_COLUMN_RULE_TODAY = 'today';
-// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow';
-// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek';
-// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek';
-// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek';
-// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth';
-// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth';
-// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth';
-// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter';
-// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter';
-// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter';
-// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear';
-// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear';
-// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear';
-// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; //
-// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // for Month/February
-// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // for Quarter 2
-
- /**
- * Autofilter Column.
- *
- * @var Column
- */
- private $parent;
-
- /**
- * Autofilter Rule Type.
- *
- * @var string
- */
- private $ruleType = self::AUTOFILTER_RULETYPE_FILTER;
-
- /**
- * Autofilter Rule Value.
- *
- * @var string
- */
- private $value = '';
-
- /**
- * Autofilter Rule Operator.
- *
- * @var string
- */
- private $operator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
-
- /**
- * DateTimeGrouping Group Value.
- *
- * @var string
- */
- private $grouping = '';
-
- /**
- * Create a new Rule.
- *
- * @param Column $pParent
- */
- public function __construct(?Column $pParent = null)
- {
- $this->parent = $pParent;
- }
-
- /**
- * Get AutoFilter Rule Type.
- *
- * @return string
- */
- public function getRuleType()
- {
- return $this->ruleType;
- }
-
- /**
- * Set AutoFilter Rule Type.
- *
- * @param string $pRuleType see self::AUTOFILTER_RULETYPE_*
- *
- * @return $this
- */
- public function setRuleType($pRuleType)
- {
- if (!in_array($pRuleType, self::$ruleTypes)) {
- throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
- }
-
- $this->ruleType = $pRuleType;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Rule Value.
- *
- * @return string
- */
- public function getValue()
- {
- return $this->value;
- }
-
- /**
- * Set AutoFilter Rule Value.
- *
- * @param string|string[] $pValue
- *
- * @return $this
- */
- public function setValue($pValue)
- {
- if (is_array($pValue)) {
- $grouping = -1;
- foreach ($pValue as $key => $value) {
- // Validate array entries
- if (!in_array($key, self::$dateTimeGroups)) {
- // Remove any invalid entries from the value array
- unset($pValue[$key]);
- } else {
- // Work out what the dateTime grouping will be
- $grouping = max($grouping, array_search($key, self::$dateTimeGroups));
- }
- }
- if (count($pValue) == 0) {
- throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.');
- }
- // Set the dateTime grouping that we've anticipated
- $this->setGrouping(self::$dateTimeGroups[$grouping]);
- }
- $this->value = $pValue;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Rule Operator.
- *
- * @return string
- */
- public function getOperator()
- {
- return $this->operator;
- }
-
- /**
- * Set AutoFilter Rule Operator.
- *
- * @param string $pOperator see self::AUTOFILTER_COLUMN_RULE_*
- *
- * @return $this
- */
- public function setOperator($pOperator)
- {
- if (empty($pOperator)) {
- $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
- }
- if (
- (!in_array($pOperator, self::$operators)) &&
- (!in_array($pOperator, self::$topTenValue))
- ) {
- throw new PhpSpreadsheetException('Invalid operator for column AutoFilter Rule.');
- }
- $this->operator = $pOperator;
-
- return $this;
- }
-
- /**
- * Get AutoFilter Rule Grouping.
- *
- * @return string
- */
- public function getGrouping()
- {
- return $this->grouping;
- }
-
- /**
- * Set AutoFilter Rule Grouping.
- *
- * @param string $pGrouping
- *
- * @return $this
- */
- public function setGrouping($pGrouping)
- {
- if (
- ($pGrouping !== null) &&
- (!in_array($pGrouping, self::$dateTimeGroups)) &&
- (!in_array($pGrouping, self::$dynamicTypes)) &&
- (!in_array($pGrouping, self::$topTenType))
- ) {
- throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
- }
- $this->grouping = $pGrouping;
-
- return $this;
- }
-
- /**
- * Set AutoFilter Rule.
- *
- * @param string $pOperator see self::AUTOFILTER_COLUMN_RULE_*
- * @param string|string[] $pValue
- * @param string $pGrouping
- *
- * @return $this
- */
- public function setRule($pOperator, $pValue, $pGrouping = null)
- {
- $this->setOperator($pOperator);
- $this->setValue($pValue);
- // Only set grouping if it's been passed in as a user-supplied argument,
- // otherwise we're calculating it when we setValue() and don't want to overwrite that
- // If the user supplies an argumnet for grouping, then on their own head be it
- if ($pGrouping !== null) {
- $this->setGrouping($pGrouping);
- }
-
- return $this;
- }
-
- /**
- * Get this Rule's AutoFilter Column Parent.
- *
- * @return Column
- */
- public function getParent()
- {
- return $this->parent;
- }
-
- /**
- * Set this Rule's AutoFilter Column Parent.
- *
- * @param Column $pParent
- *
- * @return $this
- */
- public function setParent(?Column $pParent = null)
- {
- $this->parent = $pParent;
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- if ($key == 'parent') {
- // Detach from autofilter column parent
- $this->$key = null;
- } else {
- $this->$key = clone $value;
- }
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/BaseDrawing.php b/vendor/PhpSpreadsheet/Worksheet/BaseDrawing.php
deleted file mode 100644
index be2f23d..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/BaseDrawing.php
+++ /dev/null
@@ -1,532 +0,0 @@
-name = '';
- $this->description = '';
- $this->worksheet = null;
- $this->coordinates = 'A1';
- $this->offsetX = 0;
- $this->offsetY = 0;
- $this->width = 0;
- $this->height = 0;
- $this->resizeProportional = true;
- $this->rotation = 0;
- $this->shadow = new Drawing\Shadow();
-
- // Set image index
- ++self::$imageCounter;
- $this->imageIndex = self::$imageCounter;
- }
-
- /**
- * Get image index.
- *
- * @return int
- */
- public function getImageIndex()
- {
- return $this->imageIndex;
- }
-
- /**
- * Get Name.
- *
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * Set Name.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setName($pValue)
- {
- $this->name = $pValue;
-
- return $this;
- }
-
- /**
- * Get Description.
- *
- * @return string
- */
- public function getDescription()
- {
- return $this->description;
- }
-
- /**
- * Set Description.
- *
- * @param string $description
- *
- * @return $this
- */
- public function setDescription($description)
- {
- $this->description = $description;
-
- return $this;
- }
-
- /**
- * Get Worksheet.
- *
- * @return Worksheet
- */
- public function getWorksheet()
- {
- return $this->worksheet;
- }
-
- /**
- * Set Worksheet.
- *
- * @param Worksheet $pValue
- * @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet?
- *
- * @return $this
- */
- public function setWorksheet(?Worksheet $pValue = null, $pOverrideOld = false)
- {
- if ($this->worksheet === null) {
- // Add drawing to \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- $this->worksheet = $pValue;
- $this->worksheet->getCell($this->coordinates);
- $this->worksheet->getDrawingCollection()->append($this);
- } else {
- if ($pOverrideOld) {
- // Remove drawing from old \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- $iterator = $this->worksheet->getDrawingCollection()->getIterator();
-
- while ($iterator->valid()) {
- if ($iterator->current()->getHashCode() === $this->getHashCode()) {
- $this->worksheet->getDrawingCollection()->offsetUnset($iterator->key());
- $this->worksheet = null;
-
- break;
- }
- }
-
- // Set new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- $this->setWorksheet($pValue);
- } else {
- throw new PhpSpreadsheetException('A Worksheet has already been assigned. Drawings can only exist on one \\PhpOffice\\PhpSpreadsheet\\Worksheet.');
- }
- }
-
- return $this;
- }
-
- /**
- * Get Coordinates.
- *
- * @return string
- */
- public function getCoordinates()
- {
- return $this->coordinates;
- }
-
- /**
- * Set Coordinates.
- *
- * @param string $pValue eg: 'A1'
- *
- * @return $this
- */
- public function setCoordinates($pValue)
- {
- $this->coordinates = $pValue;
-
- return $this;
- }
-
- /**
- * Get OffsetX.
- *
- * @return int
- */
- public function getOffsetX()
- {
- return $this->offsetX;
- }
-
- /**
- * Set OffsetX.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setOffsetX($pValue)
- {
- $this->offsetX = $pValue;
-
- return $this;
- }
-
- /**
- * Get OffsetY.
- *
- * @return int
- */
- public function getOffsetY()
- {
- return $this->offsetY;
- }
-
- /**
- * Set OffsetY.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setOffsetY($pValue)
- {
- $this->offsetY = $pValue;
-
- return $this;
- }
-
- /**
- * Get Width.
- *
- * @return int
- */
- public function getWidth()
- {
- return $this->width;
- }
-
- /**
- * Set Width.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setWidth($pValue)
- {
- // Resize proportional?
- if ($this->resizeProportional && $pValue != 0) {
- $ratio = $this->height / ($this->width != 0 ? $this->width : 1);
- $this->height = round($ratio * $pValue);
- }
-
- // Set width
- $this->width = $pValue;
-
- return $this;
- }
-
- /**
- * Get Height.
- *
- * @return int
- */
- public function getHeight()
- {
- return $this->height;
- }
-
- /**
- * Set Height.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setHeight($pValue)
- {
- // Resize proportional?
- if ($this->resizeProportional && $pValue != 0) {
- $ratio = $this->width / ($this->height != 0 ? $this->height : 1);
- $this->width = round($ratio * $pValue);
- }
-
- // Set height
- $this->height = $pValue;
-
- return $this;
- }
-
- /**
- * Set width and height with proportional resize.
- *
- * Example:
- *
- * $objDrawing->setResizeProportional(true);
- * $objDrawing->setWidthAndHeight(160,120);
- *
- *
- * @author Vincent@luo MSN:kele_100@hotmail.com
- *
- * @param int $width
- * @param int $height
- *
- * @return $this
- */
- public function setWidthAndHeight($width, $height)
- {
- $xratio = $width / ($this->width != 0 ? $this->width : 1);
- $yratio = $height / ($this->height != 0 ? $this->height : 1);
- if ($this->resizeProportional && !($width == 0 || $height == 0)) {
- if (($xratio * $this->height) < $height) {
- $this->height = ceil($xratio * $this->height);
- $this->width = $width;
- } else {
- $this->width = ceil($yratio * $this->width);
- $this->height = $height;
- }
- } else {
- $this->width = $width;
- $this->height = $height;
- }
-
- return $this;
- }
-
- /**
- * Get ResizeProportional.
- *
- * @return bool
- */
- public function getResizeProportional()
- {
- return $this->resizeProportional;
- }
-
- /**
- * Set ResizeProportional.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setResizeProportional($pValue)
- {
- $this->resizeProportional = $pValue;
-
- return $this;
- }
-
- /**
- * Get Rotation.
- *
- * @return int
- */
- public function getRotation()
- {
- return $this->rotation;
- }
-
- /**
- * Set Rotation.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setRotation($pValue)
- {
- $this->rotation = $pValue;
-
- return $this;
- }
-
- /**
- * Get Shadow.
- *
- * @return Drawing\Shadow
- */
- public function getShadow()
- {
- return $this->shadow;
- }
-
- /**
- * Set Shadow.
- *
- * @param Drawing\Shadow $pValue
- *
- * @return $this
- */
- public function setShadow(?Drawing\Shadow $pValue = null)
- {
- $this->shadow = $pValue;
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- return md5(
- $this->name .
- $this->description .
- $this->worksheet->getHashCode() .
- $this->coordinates .
- $this->offsetX .
- $this->offsetY .
- $this->width .
- $this->height .
- $this->rotation .
- $this->shadow->getHashCode() .
- __CLASS__
- );
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if ($key == 'worksheet') {
- $this->worksheet = null;
- } elseif (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-
- public function setHyperlink(?Hyperlink $pHyperlink = null): void
- {
- $this->hyperlink = $pHyperlink;
- }
-
- /**
- * @return null|Hyperlink
- */
- public function getHyperlink()
- {
- return $this->hyperlink;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/CellIterator.php b/vendor/PhpSpreadsheet/Worksheet/CellIterator.php
deleted file mode 100644
index 45f76ca..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/CellIterator.php
+++ /dev/null
@@ -1,57 +0,0 @@
-worksheet = null;
- }
-
- /**
- * Get loop only existing cells.
- *
- * @return bool
- */
- public function getIterateOnlyExistingCells()
- {
- return $this->onlyExistingCells;
- }
-
- /**
- * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
- */
- abstract protected function adjustForExistingOnlyRange();
-
- /**
- * Set the iterator to loop only existing cells.
- *
- * @param bool $value
- */
- public function setIterateOnlyExistingCells($value): void
- {
- $this->onlyExistingCells = (bool) $value;
-
- $this->adjustForExistingOnlyRange();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Column.php b/vendor/PhpSpreadsheet/Worksheet/Column.php
deleted file mode 100644
index 410e807..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Column.php
+++ /dev/null
@@ -1,64 +0,0 @@
-parent = $parent;
- $this->columnIndex = $columnIndex;
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->parent = null;
- }
-
- /**
- * Get column index as string eg: 'A'.
- *
- * @return string
- */
- public function getColumnIndex()
- {
- return $this->columnIndex;
- }
-
- /**
- * Get cell iterator.
- *
- * @param int $startRow The row number at which to start iterating
- * @param int $endRow Optionally, the row number at which to stop iterating
- *
- * @return ColumnCellIterator
- */
- public function getCellIterator($startRow = 1, $endRow = null)
- {
- return new ColumnCellIterator($this->parent, $this->columnIndex, $startRow, $endRow);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/ColumnCellIterator.php b/vendor/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
deleted file mode 100644
index 12420d7..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
+++ /dev/null
@@ -1,197 +0,0 @@
-worksheet = $subject;
- $this->columnIndex = Coordinate::columnIndexFromString($columnIndex);
- $this->resetEnd($endRow);
- $this->resetStart($startRow);
- }
-
- /**
- * (Re)Set the start row and the current row pointer.
- *
- * @param int $startRow The row number at which to start iterating
- *
- * @return $this
- */
- public function resetStart($startRow = 1)
- {
- $this->startRow = $startRow;
- $this->adjustForExistingOnlyRange();
- $this->seek($startRow);
-
- return $this;
- }
-
- /**
- * (Re)Set the end row.
- *
- * @param int $endRow The row number at which to stop iterating
- *
- * @return $this
- */
- public function resetEnd($endRow = null)
- {
- $this->endRow = ($endRow) ? $endRow : $this->worksheet->getHighestRow();
- $this->adjustForExistingOnlyRange();
-
- return $this;
- }
-
- /**
- * Set the row pointer to the selected row.
- *
- * @param int $row The row number to set the current pointer at
- *
- * @return $this
- */
- public function seek($row = 1)
- {
- if (($row < $this->startRow) || ($row > $this->endRow)) {
- throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
- } elseif ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $row))) {
- throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
- }
- $this->currentRow = $row;
-
- return $this;
- }
-
- /**
- * Rewind the iterator to the starting row.
- */
- public function rewind(): void
- {
- $this->currentRow = $this->startRow;
- }
-
- /**
- * Return the current cell in this worksheet column.
- *
- * @return null|\PhpOffice\PhpSpreadsheet\Cell\Cell
- */
- public function current()
- {
- return $this->worksheet->getCellByColumnAndRow($this->columnIndex, $this->currentRow);
- }
-
- /**
- * Return the current iterator key.
- *
- * @return int
- */
- public function key()
- {
- return $this->currentRow;
- }
-
- /**
- * Set the iterator to its next value.
- */
- public function next(): void
- {
- do {
- ++$this->currentRow;
- } while (
- ($this->onlyExistingCells) &&
- (!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
- ($this->currentRow <= $this->endRow)
- );
- }
-
- /**
- * Set the iterator to its previous value.
- */
- public function prev(): void
- {
- do {
- --$this->currentRow;
- } while (
- ($this->onlyExistingCells) &&
- (!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->currentRow)) &&
- ($this->currentRow >= $this->startRow)
- );
- }
-
- /**
- * Indicate if more rows exist in the worksheet range of rows that we're iterating.
- *
- * @return bool
- */
- public function valid()
- {
- return $this->currentRow <= $this->endRow && $this->currentRow >= $this->startRow;
- }
-
- /**
- * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
- */
- protected function adjustForExistingOnlyRange(): void
- {
- if ($this->onlyExistingCells) {
- while (
- (!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->startRow)) &&
- ($this->startRow <= $this->endRow)
- ) {
- ++$this->startRow;
- }
- if ($this->startRow > $this->endRow) {
- throw new PhpSpreadsheetException('No cells exist within the specified range');
- }
- while (
- (!$this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $this->endRow)) &&
- ($this->endRow >= $this->startRow)
- ) {
- --$this->endRow;
- }
- if ($this->endRow < $this->startRow) {
- throw new PhpSpreadsheetException('No cells exist within the specified range');
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/ColumnDimension.php b/vendor/PhpSpreadsheet/Worksheet/ColumnDimension.php
deleted file mode 100644
index 4e87a34..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/ColumnDimension.php
+++ /dev/null
@@ -1,115 +0,0 @@
-columnIndex = $pIndex;
-
- // set dimension as unformatted by default
- parent::__construct(0);
- }
-
- /**
- * Get column index as string eg: 'A'.
- *
- * @return string
- */
- public function getColumnIndex()
- {
- return $this->columnIndex;
- }
-
- /**
- * Set column index as string eg: 'A'.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setColumnIndex($pValue)
- {
- $this->columnIndex = $pValue;
-
- return $this;
- }
-
- /**
- * Get Width.
- *
- * @return float
- */
- public function getWidth()
- {
- return $this->width;
- }
-
- /**
- * Set Width.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setWidth($pValue)
- {
- $this->width = $pValue;
-
- return $this;
- }
-
- /**
- * Get Auto Size.
- *
- * @return bool
- */
- public function getAutoSize()
- {
- return $this->autoSize;
- }
-
- /**
- * Set Auto Size.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setAutoSize($pValue)
- {
- $this->autoSize = $pValue;
-
- return $this;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/ColumnIterator.php b/vendor/PhpSpreadsheet/Worksheet/ColumnIterator.php
deleted file mode 100644
index d0bb20c..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/ColumnIterator.php
+++ /dev/null
@@ -1,172 +0,0 @@
-worksheet = $worksheet;
- $this->resetEnd($endColumn);
- $this->resetStart($startColumn);
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->worksheet = null;
- }
-
- /**
- * (Re)Set the start column and the current column pointer.
- *
- * @param string $startColumn The column address at which to start iterating
- *
- * @return $this
- */
- public function resetStart($startColumn = 'A')
- {
- $startColumnIndex = Coordinate::columnIndexFromString($startColumn);
- if ($startColumnIndex > Coordinate::columnIndexFromString($this->worksheet->getHighestColumn())) {
- throw new Exception("Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})");
- }
-
- $this->startColumnIndex = $startColumnIndex;
- if ($this->endColumnIndex < $this->startColumnIndex) {
- $this->endColumnIndex = $this->startColumnIndex;
- }
- $this->seek($startColumn);
-
- return $this;
- }
-
- /**
- * (Re)Set the end column.
- *
- * @param string $endColumn The column address at which to stop iterating
- *
- * @return $this
- */
- public function resetEnd($endColumn = null)
- {
- $endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
- $this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
-
- return $this;
- }
-
- /**
- * Set the column pointer to the selected column.
- *
- * @param string $column The column address to set the current pointer at
- *
- * @return $this
- */
- public function seek($column = 'A')
- {
- $column = Coordinate::columnIndexFromString($column);
- if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
- throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
- }
- $this->currentColumnIndex = $column;
-
- return $this;
- }
-
- /**
- * Rewind the iterator to the starting column.
- */
- public function rewind(): void
- {
- $this->currentColumnIndex = $this->startColumnIndex;
- }
-
- /**
- * Return the current column in this worksheet.
- *
- * @return Column
- */
- public function current()
- {
- return new Column($this->worksheet, Coordinate::stringFromColumnIndex($this->currentColumnIndex));
- }
-
- /**
- * Return the current iterator key.
- *
- * @return string
- */
- public function key()
- {
- return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
- }
-
- /**
- * Set the iterator to its next value.
- */
- public function next(): void
- {
- ++$this->currentColumnIndex;
- }
-
- /**
- * Set the iterator to its previous value.
- */
- public function prev(): void
- {
- --$this->currentColumnIndex;
- }
-
- /**
- * Indicate if more columns exist in the worksheet range of columns that we're iterating.
- *
- * @return bool
- */
- public function valid()
- {
- return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Dimension.php b/vendor/PhpSpreadsheet/Worksheet/Dimension.php
deleted file mode 100644
index a27daf0..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Dimension.php
+++ /dev/null
@@ -1,163 +0,0 @@
-xfIndex = $initialValue;
- }
-
- /**
- * Get Visible.
- *
- * @return bool
- */
- public function getVisible()
- {
- return $this->visible;
- }
-
- /**
- * Set Visible.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setVisible($pValue)
- {
- $this->visible = (bool) $pValue;
-
- return $this;
- }
-
- /**
- * Get Outline Level.
- *
- * @return int
- */
- public function getOutlineLevel()
- {
- return $this->outlineLevel;
- }
-
- /**
- * Set Outline Level.
- * Value must be between 0 and 7.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setOutlineLevel($pValue)
- {
- if ($pValue < 0 || $pValue > 7) {
- throw new PhpSpreadsheetException('Outline level must range between 0 and 7.');
- }
-
- $this->outlineLevel = $pValue;
-
- return $this;
- }
-
- /**
- * Get Collapsed.
- *
- * @return bool
- */
- public function getCollapsed()
- {
- return $this->collapsed;
- }
-
- /**
- * Set Collapsed.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setCollapsed($pValue)
- {
- $this->collapsed = (bool) $pValue;
-
- return $this;
- }
-
- /**
- * Get index to cellXf.
- *
- * @return int
- */
- public function getXfIndex()
- {
- return $this->xfIndex;
- }
-
- /**
- * Set index to cellXf.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setXfIndex($pValue)
- {
- $this->xfIndex = $pValue;
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Drawing.php b/vendor/PhpSpreadsheet/Worksheet/Drawing.php
deleted file mode 100644
index 1f1dae9..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Drawing.php
+++ /dev/null
@@ -1,114 +0,0 @@
-path = '';
-
- // Initialize parent
- parent::__construct();
- }
-
- /**
- * Get Filename.
- *
- * @return string
- */
- public function getFilename()
- {
- return basename($this->path);
- }
-
- /**
- * Get indexed filename (using image index).
- *
- * @return string
- */
- public function getIndexedFilename()
- {
- $fileName = $this->getFilename();
- $fileName = str_replace(' ', '_', $fileName);
-
- return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension();
- }
-
- /**
- * Get Extension.
- *
- * @return string
- */
- public function getExtension()
- {
- $exploded = explode('.', basename($this->path));
-
- return $exploded[count($exploded) - 1];
- }
-
- /**
- * Get Path.
- *
- * @return string
- */
- public function getPath()
- {
- return $this->path;
- }
-
- /**
- * Set Path.
- *
- * @param string $pValue File path
- * @param bool $pVerifyFile Verify file
- *
- * @return $this
- */
- public function setPath($pValue, $pVerifyFile = true)
- {
- if ($pVerifyFile) {
- if (file_exists($pValue)) {
- $this->path = $pValue;
-
- if ($this->width == 0 && $this->height == 0) {
- // Get width/height
- [$this->width, $this->height] = getimagesize($pValue);
- }
- } else {
- throw new PhpSpreadsheetException("File $pValue not found!");
- }
- } else {
- $this->path = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- return md5(
- $this->path .
- parent::getHashCode() .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Drawing/Shadow.php b/vendor/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
deleted file mode 100644
index 01ffed9..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
+++ /dev/null
@@ -1,289 +0,0 @@
-visible = false;
- $this->blurRadius = 6;
- $this->distance = 2;
- $this->direction = 0;
- $this->alignment = self::SHADOW_BOTTOM_RIGHT;
- $this->color = new Color(Color::COLOR_BLACK);
- $this->alpha = 50;
- }
-
- /**
- * Get Visible.
- *
- * @return bool
- */
- public function getVisible()
- {
- return $this->visible;
- }
-
- /**
- * Set Visible.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setVisible($pValue)
- {
- $this->visible = $pValue;
-
- return $this;
- }
-
- /**
- * Get Blur radius.
- *
- * @return int
- */
- public function getBlurRadius()
- {
- return $this->blurRadius;
- }
-
- /**
- * Set Blur radius.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setBlurRadius($pValue)
- {
- $this->blurRadius = $pValue;
-
- return $this;
- }
-
- /**
- * Get Shadow distance.
- *
- * @return int
- */
- public function getDistance()
- {
- return $this->distance;
- }
-
- /**
- * Set Shadow distance.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setDistance($pValue)
- {
- $this->distance = $pValue;
-
- return $this;
- }
-
- /**
- * Get Shadow direction (in degrees).
- *
- * @return int
- */
- public function getDirection()
- {
- return $this->direction;
- }
-
- /**
- * Set Shadow direction (in degrees).
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setDirection($pValue)
- {
- $this->direction = $pValue;
-
- return $this;
- }
-
- /**
- * Get Shadow alignment.
- *
- * @return int
- */
- public function getAlignment()
- {
- return $this->alignment;
- }
-
- /**
- * Set Shadow alignment.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setAlignment($pValue)
- {
- $this->alignment = $pValue;
-
- return $this;
- }
-
- /**
- * Get Color.
- *
- * @return Color
- */
- public function getColor()
- {
- return $this->color;
- }
-
- /**
- * Set Color.
- *
- * @param Color $pValue
- *
- * @return $this
- */
- public function setColor(?Color $pValue = null)
- {
- $this->color = $pValue;
-
- return $this;
- }
-
- /**
- * Get Alpha.
- *
- * @return int
- */
- public function getAlpha()
- {
- return $this->alpha;
- }
-
- /**
- * Set Alpha.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setAlpha($pValue)
- {
- $this->alpha = $pValue;
-
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- return md5(
- ($this->visible ? 't' : 'f') .
- $this->blurRadius .
- $this->distance .
- $this->direction .
- $this->alignment .
- $this->color->getHashCode() .
- $this->alpha .
- __CLASS__
- );
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/HeaderFooter.php b/vendor/PhpSpreadsheet/Worksheet/HeaderFooter.php
deleted file mode 100644
index cc37e7f..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/HeaderFooter.php
+++ /dev/null
@@ -1,490 +0,0 @@
-
- * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970:.
- *
- * There are a number of formatting codes that can be written inline with the actual header / footer text, which
- * affect the formatting in the header or footer.
- *
- * Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on
- * the second line (center section).
- * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D
- *
- * General Rules:
- * There is no required order in which these codes must appear.
- *
- * The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again:
- * - strikethrough
- * - superscript
- * - subscript
- * Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored,
- * while the first is ON.
- * &L - code for "left section" (there are three header / footer locations, "left", "center", and "right"). When
- * two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the
- * order of appearance, and placed into the left section.
- * &P - code for "current page #"
- * &N - code for "total pages"
- * &font size - code for "text font size", where font size is a font size in points.
- * &K - code for "text font color"
- * RGB Color is specified as RRGGBB
- * Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade
- * value, NN is the tint/shade value.
- * &S - code for "text strikethrough" on / off
- * &X - code for "text super script" on / off
- * &Y - code for "text subscript" on / off
- * &C - code for "center section". When two or more occurrences of this section marker exist, the contents
- * from all markers are concatenated, in the order of appearance, and placed into the center section.
- *
- * &D - code for "date"
- * &T - code for "time"
- * &G - code for "picture as background"
- * &U - code for "text single underline"
- * &E - code for "double underline"
- * &R - code for "right section". When two or more occurrences of this section marker exist, the contents
- * from all markers are concatenated, in the order of appearance, and placed into the right section.
- * &Z - code for "this workbook's file path"
- * &F - code for "this workbook's file name"
- * &A - code for "sheet tab name"
- * &+ - code for add to page #.
- * &- - code for subtract from page #.
- * &"font name,font type" - code for "text font name" and "text font type", where font name and font type
- * are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font
- * name, it means "none specified". Both of font name and font type can be localized values.
- * &"-,Bold" - code for "bold font style"
- * &B - also means "bold font style".
- * &"-,Regular" - code for "regular font style"
- * &"-,Italic" - code for "italic font style"
- * &I - also means "italic font style"
- * &"-,Bold Italic" code for "bold italic font style"
- * &O - code for "outline style"
- * &H - code for "shadow style"
- *
- */
-class HeaderFooter
-{
- // Header/footer image location
- const IMAGE_HEADER_LEFT = 'LH';
- const IMAGE_HEADER_CENTER = 'CH';
- const IMAGE_HEADER_RIGHT = 'RH';
- const IMAGE_FOOTER_LEFT = 'LF';
- const IMAGE_FOOTER_CENTER = 'CF';
- const IMAGE_FOOTER_RIGHT = 'RF';
-
- /**
- * OddHeader.
- *
- * @var string
- */
- private $oddHeader = '';
-
- /**
- * OddFooter.
- *
- * @var string
- */
- private $oddFooter = '';
-
- /**
- * EvenHeader.
- *
- * @var string
- */
- private $evenHeader = '';
-
- /**
- * EvenFooter.
- *
- * @var string
- */
- private $evenFooter = '';
-
- /**
- * FirstHeader.
- *
- * @var string
- */
- private $firstHeader = '';
-
- /**
- * FirstFooter.
- *
- * @var string
- */
- private $firstFooter = '';
-
- /**
- * Different header for Odd/Even, defaults to false.
- *
- * @var bool
- */
- private $differentOddEven = false;
-
- /**
- * Different header for first page, defaults to false.
- *
- * @var bool
- */
- private $differentFirst = false;
-
- /**
- * Scale with document, defaults to true.
- *
- * @var bool
- */
- private $scaleWithDocument = true;
-
- /**
- * Align with margins, defaults to true.
- *
- * @var bool
- */
- private $alignWithMargins = true;
-
- /**
- * Header/footer images.
- *
- * @var HeaderFooterDrawing[]
- */
- private $headerFooterImages = [];
-
- /**
- * Create a new HeaderFooter.
- */
- public function __construct()
- {
- }
-
- /**
- * Get OddHeader.
- *
- * @return string
- */
- public function getOddHeader()
- {
- return $this->oddHeader;
- }
-
- /**
- * Set OddHeader.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setOddHeader($pValue)
- {
- $this->oddHeader = $pValue;
-
- return $this;
- }
-
- /**
- * Get OddFooter.
- *
- * @return string
- */
- public function getOddFooter()
- {
- return $this->oddFooter;
- }
-
- /**
- * Set OddFooter.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setOddFooter($pValue)
- {
- $this->oddFooter = $pValue;
-
- return $this;
- }
-
- /**
- * Get EvenHeader.
- *
- * @return string
- */
- public function getEvenHeader()
- {
- return $this->evenHeader;
- }
-
- /**
- * Set EvenHeader.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setEvenHeader($pValue)
- {
- $this->evenHeader = $pValue;
-
- return $this;
- }
-
- /**
- * Get EvenFooter.
- *
- * @return string
- */
- public function getEvenFooter()
- {
- return $this->evenFooter;
- }
-
- /**
- * Set EvenFooter.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setEvenFooter($pValue)
- {
- $this->evenFooter = $pValue;
-
- return $this;
- }
-
- /**
- * Get FirstHeader.
- *
- * @return string
- */
- public function getFirstHeader()
- {
- return $this->firstHeader;
- }
-
- /**
- * Set FirstHeader.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setFirstHeader($pValue)
- {
- $this->firstHeader = $pValue;
-
- return $this;
- }
-
- /**
- * Get FirstFooter.
- *
- * @return string
- */
- public function getFirstFooter()
- {
- return $this->firstFooter;
- }
-
- /**
- * Set FirstFooter.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setFirstFooter($pValue)
- {
- $this->firstFooter = $pValue;
-
- return $this;
- }
-
- /**
- * Get DifferentOddEven.
- *
- * @return bool
- */
- public function getDifferentOddEven()
- {
- return $this->differentOddEven;
- }
-
- /**
- * Set DifferentOddEven.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setDifferentOddEven($pValue)
- {
- $this->differentOddEven = $pValue;
-
- return $this;
- }
-
- /**
- * Get DifferentFirst.
- *
- * @return bool
- */
- public function getDifferentFirst()
- {
- return $this->differentFirst;
- }
-
- /**
- * Set DifferentFirst.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setDifferentFirst($pValue)
- {
- $this->differentFirst = $pValue;
-
- return $this;
- }
-
- /**
- * Get ScaleWithDocument.
- *
- * @return bool
- */
- public function getScaleWithDocument()
- {
- return $this->scaleWithDocument;
- }
-
- /**
- * Set ScaleWithDocument.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setScaleWithDocument($pValue)
- {
- $this->scaleWithDocument = $pValue;
-
- return $this;
- }
-
- /**
- * Get AlignWithMargins.
- *
- * @return bool
- */
- public function getAlignWithMargins()
- {
- return $this->alignWithMargins;
- }
-
- /**
- * Set AlignWithMargins.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setAlignWithMargins($pValue)
- {
- $this->alignWithMargins = $pValue;
-
- return $this;
- }
-
- /**
- * Add header/footer image.
- *
- * @param string $location
- *
- * @return $this
- */
- public function addImage(HeaderFooterDrawing $image, $location = self::IMAGE_HEADER_LEFT)
- {
- $this->headerFooterImages[$location] = $image;
-
- return $this;
- }
-
- /**
- * Remove header/footer image.
- *
- * @param string $location
- *
- * @return $this
- */
- public function removeImage($location = self::IMAGE_HEADER_LEFT)
- {
- if (isset($this->headerFooterImages[$location])) {
- unset($this->headerFooterImages[$location]);
- }
-
- return $this;
- }
-
- /**
- * Set header/footer images.
- *
- * @param HeaderFooterDrawing[] $images
- *
- * @return $this
- */
- public function setImages(array $images)
- {
- $this->headerFooterImages = $images;
-
- return $this;
- }
-
- /**
- * Get header/footer images.
- *
- * @return HeaderFooterDrawing[]
- */
- public function getImages()
- {
- // Sort array
- $images = [];
- if (isset($this->headerFooterImages[self::IMAGE_HEADER_LEFT])) {
- $images[self::IMAGE_HEADER_LEFT] = $this->headerFooterImages[self::IMAGE_HEADER_LEFT];
- }
- if (isset($this->headerFooterImages[self::IMAGE_HEADER_CENTER])) {
- $images[self::IMAGE_HEADER_CENTER] = $this->headerFooterImages[self::IMAGE_HEADER_CENTER];
- }
- if (isset($this->headerFooterImages[self::IMAGE_HEADER_RIGHT])) {
- $images[self::IMAGE_HEADER_RIGHT] = $this->headerFooterImages[self::IMAGE_HEADER_RIGHT];
- }
- if (isset($this->headerFooterImages[self::IMAGE_FOOTER_LEFT])) {
- $images[self::IMAGE_FOOTER_LEFT] = $this->headerFooterImages[self::IMAGE_FOOTER_LEFT];
- }
- if (isset($this->headerFooterImages[self::IMAGE_FOOTER_CENTER])) {
- $images[self::IMAGE_FOOTER_CENTER] = $this->headerFooterImages[self::IMAGE_FOOTER_CENTER];
- }
- if (isset($this->headerFooterImages[self::IMAGE_FOOTER_RIGHT])) {
- $images[self::IMAGE_FOOTER_RIGHT] = $this->headerFooterImages[self::IMAGE_FOOTER_RIGHT];
- }
- $this->headerFooterImages = $images;
-
- return $this->headerFooterImages;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/HeaderFooterDrawing.php b/vendor/PhpSpreadsheet/Worksheet/HeaderFooterDrawing.php
deleted file mode 100644
index b42c732..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/HeaderFooterDrawing.php
+++ /dev/null
@@ -1,24 +0,0 @@
-getPath() .
- $this->name .
- $this->offsetX .
- $this->offsetY .
- $this->width .
- $this->height .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Iterator.php b/vendor/PhpSpreadsheet/Worksheet/Iterator.php
deleted file mode 100644
index 6cfed37..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Iterator.php
+++ /dev/null
@@ -1,85 +0,0 @@
-subject = $subject;
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->subject = null;
- }
-
- /**
- * Rewind iterator.
- */
- public function rewind(): void
- {
- $this->position = 0;
- }
-
- /**
- * Current Worksheet.
- *
- * @return Worksheet
- */
- public function current()
- {
- return $this->subject->getSheet($this->position);
- }
-
- /**
- * Current key.
- *
- * @return int
- */
- public function key()
- {
- return $this->position;
- }
-
- /**
- * Next value.
- */
- public function next(): void
- {
- ++$this->position;
- }
-
- /**
- * Are there more Worksheet instances available?
- *
- * @return bool
- */
- public function valid()
- {
- return $this->position < $this->subject->getSheetCount() && $this->position >= 0;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/MemoryDrawing.php b/vendor/PhpSpreadsheet/Worksheet/MemoryDrawing.php
deleted file mode 100644
index 22e0909..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/MemoryDrawing.php
+++ /dev/null
@@ -1,169 +0,0 @@
-imageResource = null;
- $this->renderingFunction = self::RENDERING_DEFAULT;
- $this->mimeType = self::MIMETYPE_DEFAULT;
- $this->uniqueName = md5(mt_rand(0, 9999) . time() . mt_rand(0, 9999));
-
- // Initialize parent
- parent::__construct();
- }
-
- /**
- * Get image resource.
- *
- * @return resource
- */
- public function getImageResource()
- {
- return $this->imageResource;
- }
-
- /**
- * Set image resource.
- *
- * @param resource $value
- *
- * @return $this
- */
- public function setImageResource($value)
- {
- $this->imageResource = $value;
-
- if ($this->imageResource !== null) {
- // Get width/height
- $this->width = imagesx($this->imageResource);
- $this->height = imagesy($this->imageResource);
- }
-
- return $this;
- }
-
- /**
- * Get rendering function.
- *
- * @return string
- */
- public function getRenderingFunction()
- {
- return $this->renderingFunction;
- }
-
- /**
- * Set rendering function.
- *
- * @param string $value see self::RENDERING_*
- *
- * @return $this
- */
- public function setRenderingFunction($value)
- {
- $this->renderingFunction = $value;
-
- return $this;
- }
-
- /**
- * Get mime type.
- *
- * @return string
- */
- public function getMimeType()
- {
- return $this->mimeType;
- }
-
- /**
- * Set mime type.
- *
- * @param string $value see self::MIMETYPE_*
- *
- * @return $this
- */
- public function setMimeType($value)
- {
- $this->mimeType = $value;
-
- return $this;
- }
-
- /**
- * Get indexed filename (using image index).
- *
- * @return string
- */
- public function getIndexedFilename()
- {
- $extension = strtolower($this->getMimeType());
- $extension = explode('/', $extension);
- $extension = $extension[1];
-
- return $this->uniqueName . $this->getImageIndex() . '.' . $extension;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- return md5(
- $this->renderingFunction .
- $this->mimeType .
- $this->uniqueName .
- parent::getHashCode() .
- __CLASS__
- );
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/PageMargins.php b/vendor/PhpSpreadsheet/Worksheet/PageMargins.php
deleted file mode 100644
index a829793..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/PageMargins.php
+++ /dev/null
@@ -1,244 +0,0 @@
-left;
- }
-
- /**
- * Set Left.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setLeft($pValue)
- {
- $this->left = $pValue;
-
- return $this;
- }
-
- /**
- * Get Right.
- *
- * @return float
- */
- public function getRight()
- {
- return $this->right;
- }
-
- /**
- * Set Right.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setRight($pValue)
- {
- $this->right = $pValue;
-
- return $this;
- }
-
- /**
- * Get Top.
- *
- * @return float
- */
- public function getTop()
- {
- return $this->top;
- }
-
- /**
- * Set Top.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setTop($pValue)
- {
- $this->top = $pValue;
-
- return $this;
- }
-
- /**
- * Get Bottom.
- *
- * @return float
- */
- public function getBottom()
- {
- return $this->bottom;
- }
-
- /**
- * Set Bottom.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setBottom($pValue)
- {
- $this->bottom = $pValue;
-
- return $this;
- }
-
- /**
- * Get Header.
- *
- * @return float
- */
- public function getHeader()
- {
- return $this->header;
- }
-
- /**
- * Set Header.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setHeader($pValue)
- {
- $this->header = $pValue;
-
- return $this;
- }
-
- /**
- * Get Footer.
- *
- * @return float
- */
- public function getFooter()
- {
- return $this->footer;
- }
-
- /**
- * Set Footer.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setFooter($pValue)
- {
- $this->footer = $pValue;
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-
- public static function fromCentimeters(float $value): float
- {
- return $value / 2.54;
- }
-
- public static function toCentimeters(float $value): float
- {
- return $value * 2.54;
- }
-
- public static function fromMillimeters(float $value): float
- {
- return $value / 25.4;
- }
-
- public static function toMillimeters(float $value): float
- {
- return $value * 25.4;
- }
-
- public static function fromPoints(float $value): float
- {
- return $value / 72;
- }
-
- public static function toPoints(float $value): float
- {
- return $value * 72;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/PageSetup.php b/vendor/PhpSpreadsheet/Worksheet/PageSetup.php
deleted file mode 100644
index d1a22a7..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/PageSetup.php
+++ /dev/null
@@ -1,857 +0,0 @@
-
- * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988:.
- *
- * 1 = Letter paper (8.5 in. by 11 in.)
- * 2 = Letter small paper (8.5 in. by 11 in.)
- * 3 = Tabloid paper (11 in. by 17 in.)
- * 4 = Ledger paper (17 in. by 11 in.)
- * 5 = Legal paper (8.5 in. by 14 in.)
- * 6 = Statement paper (5.5 in. by 8.5 in.)
- * 7 = Executive paper (7.25 in. by 10.5 in.)
- * 8 = A3 paper (297 mm by 420 mm)
- * 9 = A4 paper (210 mm by 297 mm)
- * 10 = A4 small paper (210 mm by 297 mm)
- * 11 = A5 paper (148 mm by 210 mm)
- * 12 = B4 paper (250 mm by 353 mm)
- * 13 = B5 paper (176 mm by 250 mm)
- * 14 = Folio paper (8.5 in. by 13 in.)
- * 15 = Quarto paper (215 mm by 275 mm)
- * 16 = Standard paper (10 in. by 14 in.)
- * 17 = Standard paper (11 in. by 17 in.)
- * 18 = Note paper (8.5 in. by 11 in.)
- * 19 = #9 envelope (3.875 in. by 8.875 in.)
- * 20 = #10 envelope (4.125 in. by 9.5 in.)
- * 21 = #11 envelope (4.5 in. by 10.375 in.)
- * 22 = #12 envelope (4.75 in. by 11 in.)
- * 23 = #14 envelope (5 in. by 11.5 in.)
- * 24 = C paper (17 in. by 22 in.)
- * 25 = D paper (22 in. by 34 in.)
- * 26 = E paper (34 in. by 44 in.)
- * 27 = DL envelope (110 mm by 220 mm)
- * 28 = C5 envelope (162 mm by 229 mm)
- * 29 = C3 envelope (324 mm by 458 mm)
- * 30 = C4 envelope (229 mm by 324 mm)
- * 31 = C6 envelope (114 mm by 162 mm)
- * 32 = C65 envelope (114 mm by 229 mm)
- * 33 = B4 envelope (250 mm by 353 mm)
- * 34 = B5 envelope (176 mm by 250 mm)
- * 35 = B6 envelope (176 mm by 125 mm)
- * 36 = Italy envelope (110 mm by 230 mm)
- * 37 = Monarch envelope (3.875 in. by 7.5 in.).
- * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.)
- * 39 = US standard fanfold (14.875 in. by 11 in.)
- * 40 = German standard fanfold (8.5 in. by 12 in.)
- * 41 = German legal fanfold (8.5 in. by 13 in.)
- * 42 = ISO B4 (250 mm by 353 mm)
- * 43 = Japanese double postcard (200 mm by 148 mm)
- * 44 = Standard paper (9 in. by 11 in.)
- * 45 = Standard paper (10 in. by 11 in.)
- * 46 = Standard paper (15 in. by 11 in.)
- * 47 = Invite envelope (220 mm by 220 mm)
- * 50 = Letter extra paper (9.275 in. by 12 in.)
- * 51 = Legal extra paper (9.275 in. by 15 in.)
- * 52 = Tabloid extra paper (11.69 in. by 18 in.)
- * 53 = A4 extra paper (236 mm by 322 mm)
- * 54 = Letter transverse paper (8.275 in. by 11 in.)
- * 55 = A4 transverse paper (210 mm by 297 mm)
- * 56 = Letter extra transverse paper (9.275 in. by 12 in.)
- * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)
- * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)
- * 59 = Letter plus paper (8.5 in. by 12.69 in.)
- * 60 = A4 plus paper (210 mm by 330 mm)
- * 61 = A5 transverse paper (148 mm by 210 mm)
- * 62 = JIS B5 transverse paper (182 mm by 257 mm)
- * 63 = A3 extra paper (322 mm by 445 mm)
- * 64 = A5 extra paper (174 mm by 235 mm)
- * 65 = ISO B5 extra paper (201 mm by 276 mm)
- * 66 = A2 paper (420 mm by 594 mm)
- * 67 = A3 transverse paper (297 mm by 420 mm)
- * 68 = A3 extra transverse paper (322 mm by 445 mm)
- *
- */
-class PageSetup
-{
- // Paper size
- const PAPERSIZE_LETTER = 1;
- const PAPERSIZE_LETTER_SMALL = 2;
- const PAPERSIZE_TABLOID = 3;
- const PAPERSIZE_LEDGER = 4;
- const PAPERSIZE_LEGAL = 5;
- const PAPERSIZE_STATEMENT = 6;
- const PAPERSIZE_EXECUTIVE = 7;
- const PAPERSIZE_A3 = 8;
- const PAPERSIZE_A4 = 9;
- const PAPERSIZE_A4_SMALL = 10;
- const PAPERSIZE_A5 = 11;
- const PAPERSIZE_B4 = 12;
- const PAPERSIZE_B5 = 13;
- const PAPERSIZE_FOLIO = 14;
- const PAPERSIZE_QUARTO = 15;
- const PAPERSIZE_STANDARD_1 = 16;
- const PAPERSIZE_STANDARD_2 = 17;
- const PAPERSIZE_NOTE = 18;
- const PAPERSIZE_NO9_ENVELOPE = 19;
- const PAPERSIZE_NO10_ENVELOPE = 20;
- const PAPERSIZE_NO11_ENVELOPE = 21;
- const PAPERSIZE_NO12_ENVELOPE = 22;
- const PAPERSIZE_NO14_ENVELOPE = 23;
- const PAPERSIZE_C = 24;
- const PAPERSIZE_D = 25;
- const PAPERSIZE_E = 26;
- const PAPERSIZE_DL_ENVELOPE = 27;
- const PAPERSIZE_C5_ENVELOPE = 28;
- const PAPERSIZE_C3_ENVELOPE = 29;
- const PAPERSIZE_C4_ENVELOPE = 30;
- const PAPERSIZE_C6_ENVELOPE = 31;
- const PAPERSIZE_C65_ENVELOPE = 32;
- const PAPERSIZE_B4_ENVELOPE = 33;
- const PAPERSIZE_B5_ENVELOPE = 34;
- const PAPERSIZE_B6_ENVELOPE = 35;
- const PAPERSIZE_ITALY_ENVELOPE = 36;
- const PAPERSIZE_MONARCH_ENVELOPE = 37;
- const PAPERSIZE_6_3_4_ENVELOPE = 38;
- const PAPERSIZE_US_STANDARD_FANFOLD = 39;
- const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40;
- const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41;
- const PAPERSIZE_ISO_B4 = 42;
- const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43;
- const PAPERSIZE_STANDARD_PAPER_1 = 44;
- const PAPERSIZE_STANDARD_PAPER_2 = 45;
- const PAPERSIZE_STANDARD_PAPER_3 = 46;
- const PAPERSIZE_INVITE_ENVELOPE = 47;
- const PAPERSIZE_LETTER_EXTRA_PAPER = 48;
- const PAPERSIZE_LEGAL_EXTRA_PAPER = 49;
- const PAPERSIZE_TABLOID_EXTRA_PAPER = 50;
- const PAPERSIZE_A4_EXTRA_PAPER = 51;
- const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52;
- const PAPERSIZE_A4_TRANSVERSE_PAPER = 53;
- const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54;
- const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55;
- const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56;
- const PAPERSIZE_LETTER_PLUS_PAPER = 57;
- const PAPERSIZE_A4_PLUS_PAPER = 58;
- const PAPERSIZE_A5_TRANSVERSE_PAPER = 59;
- const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60;
- const PAPERSIZE_A3_EXTRA_PAPER = 61;
- const PAPERSIZE_A5_EXTRA_PAPER = 62;
- const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63;
- const PAPERSIZE_A2_PAPER = 64;
- const PAPERSIZE_A3_TRANSVERSE_PAPER = 65;
- const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66;
-
- // Page orientation
- const ORIENTATION_DEFAULT = 'default';
- const ORIENTATION_LANDSCAPE = 'landscape';
- const ORIENTATION_PORTRAIT = 'portrait';
-
- // Print Range Set Method
- const SETPRINTRANGE_OVERWRITE = 'O';
- const SETPRINTRANGE_INSERT = 'I';
-
- const PAGEORDER_OVER_THEN_DOWN = 'overThenDown';
- const PAGEORDER_DOWN_THEN_OVER = 'downThenOver';
-
- /**
- * Paper size.
- *
- * @var int
- */
- private $paperSize = self::PAPERSIZE_LETTER;
-
- /**
- * Orientation.
- *
- * @var string
- */
- private $orientation = self::ORIENTATION_DEFAULT;
-
- /**
- * Scale (Print Scale).
- *
- * Print scaling. Valid values range from 10 to 400
- * This setting is overridden when fitToWidth and/or fitToHeight are in use
- *
- * @var null|int
- */
- private $scale = 100;
-
- /**
- * Fit To Page
- * Whether scale or fitToWith / fitToHeight applies.
- *
- * @var bool
- */
- private $fitToPage = false;
-
- /**
- * Fit To Height
- * Number of vertical pages to fit on.
- *
- * @var null|int
- */
- private $fitToHeight = 1;
-
- /**
- * Fit To Width
- * Number of horizontal pages to fit on.
- *
- * @var null|int
- */
- private $fitToWidth = 1;
-
- /**
- * Columns to repeat at left.
- *
- * @var array Containing start column and end column, empty array if option unset
- */
- private $columnsToRepeatAtLeft = ['', ''];
-
- /**
- * Rows to repeat at top.
- *
- * @var array Containing start row number and end row number, empty array if option unset
- */
- private $rowsToRepeatAtTop = [0, 0];
-
- /**
- * Center page horizontally.
- *
- * @var bool
- */
- private $horizontalCentered = false;
-
- /**
- * Center page vertically.
- *
- * @var bool
- */
- private $verticalCentered = false;
-
- /**
- * Print area.
- *
- * @var string
- */
- private $printArea;
-
- /**
- * First page number.
- *
- * @var int
- */
- private $firstPageNumber;
-
- private $pageOrder = self::PAGEORDER_DOWN_THEN_OVER;
-
- /**
- * Create a new PageSetup.
- */
- public function __construct()
- {
- }
-
- /**
- * Get Paper Size.
- *
- * @return int
- */
- public function getPaperSize()
- {
- return $this->paperSize;
- }
-
- /**
- * Set Paper Size.
- *
- * @param int $pValue see self::PAPERSIZE_*
- *
- * @return $this
- */
- public function setPaperSize($pValue)
- {
- $this->paperSize = $pValue;
-
- return $this;
- }
-
- /**
- * Get Orientation.
- *
- * @return string
- */
- public function getOrientation()
- {
- return $this->orientation;
- }
-
- /**
- * Set Orientation.
- *
- * @param string $pValue see self::ORIENTATION_*
- *
- * @return $this
- */
- public function setOrientation($pValue)
- {
- $this->orientation = $pValue;
-
- return $this;
- }
-
- /**
- * Get Scale.
- *
- * @return null|int
- */
- public function getScale()
- {
- return $this->scale;
- }
-
- /**
- * Set Scale.
- * Print scaling. Valid values range from 10 to 400
- * This setting is overridden when fitToWidth and/or fitToHeight are in use.
- *
- * @param null|int $pValue
- * @param bool $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth
- *
- * @return $this
- */
- public function setScale($pValue, $pUpdate = true)
- {
- // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
- // but it is apparently still able to handle any scale >= 0, where 0 results in 100
- if (($pValue >= 0) || $pValue === null) {
- $this->scale = $pValue;
- if ($pUpdate) {
- $this->fitToPage = false;
- }
- } else {
- throw new PhpSpreadsheetException('Scale must not be negative');
- }
-
- return $this;
- }
-
- /**
- * Get Fit To Page.
- *
- * @return bool
- */
- public function getFitToPage()
- {
- return $this->fitToPage;
- }
-
- /**
- * Set Fit To Page.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setFitToPage($pValue)
- {
- $this->fitToPage = $pValue;
-
- return $this;
- }
-
- /**
- * Get Fit To Height.
- *
- * @return null|int
- */
- public function getFitToHeight()
- {
- return $this->fitToHeight;
- }
-
- /**
- * Set Fit To Height.
- *
- * @param null|int $pValue
- * @param bool $pUpdate Update fitToPage so it applies rather than scaling
- *
- * @return $this
- */
- public function setFitToHeight($pValue, $pUpdate = true)
- {
- $this->fitToHeight = $pValue;
- if ($pUpdate) {
- $this->fitToPage = true;
- }
-
- return $this;
- }
-
- /**
- * Get Fit To Width.
- *
- * @return null|int
- */
- public function getFitToWidth()
- {
- return $this->fitToWidth;
- }
-
- /**
- * Set Fit To Width.
- *
- * @param null|int $pValue
- * @param bool $pUpdate Update fitToPage so it applies rather than scaling
- *
- * @return $this
- */
- public function setFitToWidth($pValue, $pUpdate = true)
- {
- $this->fitToWidth = $pValue;
- if ($pUpdate) {
- $this->fitToPage = true;
- }
-
- return $this;
- }
-
- /**
- * Is Columns to repeat at left set?
- *
- * @return bool
- */
- public function isColumnsToRepeatAtLeftSet()
- {
- if (is_array($this->columnsToRepeatAtLeft)) {
- if ($this->columnsToRepeatAtLeft[0] != '' && $this->columnsToRepeatAtLeft[1] != '') {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Get Columns to repeat at left.
- *
- * @return array Containing start column and end column, empty array if option unset
- */
- public function getColumnsToRepeatAtLeft()
- {
- return $this->columnsToRepeatAtLeft;
- }
-
- /**
- * Set Columns to repeat at left.
- *
- * @param array $pValue Containing start column and end column, empty array if option unset
- *
- * @return $this
- */
- public function setColumnsToRepeatAtLeft(array $pValue)
- {
- $this->columnsToRepeatAtLeft = $pValue;
-
- return $this;
- }
-
- /**
- * Set Columns to repeat at left by start and end.
- *
- * @param string $pStart eg: 'A'
- * @param string $pEnd eg: 'B'
- *
- * @return $this
- */
- public function setColumnsToRepeatAtLeftByStartAndEnd($pStart, $pEnd)
- {
- $this->columnsToRepeatAtLeft = [$pStart, $pEnd];
-
- return $this;
- }
-
- /**
- * Is Rows to repeat at top set?
- *
- * @return bool
- */
- public function isRowsToRepeatAtTopSet()
- {
- if (is_array($this->rowsToRepeatAtTop)) {
- if ($this->rowsToRepeatAtTop[0] != 0 && $this->rowsToRepeatAtTop[1] != 0) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Get Rows to repeat at top.
- *
- * @return array Containing start column and end column, empty array if option unset
- */
- public function getRowsToRepeatAtTop()
- {
- return $this->rowsToRepeatAtTop;
- }
-
- /**
- * Set Rows to repeat at top.
- *
- * @param array $pValue Containing start column and end column, empty array if option unset
- *
- * @return $this
- */
- public function setRowsToRepeatAtTop(array $pValue)
- {
- $this->rowsToRepeatAtTop = $pValue;
-
- return $this;
- }
-
- /**
- * Set Rows to repeat at top by start and end.
- *
- * @param int $pStart eg: 1
- * @param int $pEnd eg: 1
- *
- * @return $this
- */
- public function setRowsToRepeatAtTopByStartAndEnd($pStart, $pEnd)
- {
- $this->rowsToRepeatAtTop = [$pStart, $pEnd];
-
- return $this;
- }
-
- /**
- * Get center page horizontally.
- *
- * @return bool
- */
- public function getHorizontalCentered()
- {
- return $this->horizontalCentered;
- }
-
- /**
- * Set center page horizontally.
- *
- * @param bool $value
- *
- * @return $this
- */
- public function setHorizontalCentered($value)
- {
- $this->horizontalCentered = $value;
-
- return $this;
- }
-
- /**
- * Get center page vertically.
- *
- * @return bool
- */
- public function getVerticalCentered()
- {
- return $this->verticalCentered;
- }
-
- /**
- * Set center page vertically.
- *
- * @param bool $value
- *
- * @return $this
- */
- public function setVerticalCentered($value)
- {
- $this->verticalCentered = $value;
-
- return $this;
- }
-
- /**
- * Get print area.
- *
- * @param int $index Identifier for a specific print area range if several ranges have been set
- * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string
- * Otherwise, the specific range identified by the value of $index will be returned
- * Print areas are numbered from 1
- *
- * @return string
- */
- public function getPrintArea($index = 0)
- {
- if ($index == 0) {
- return $this->printArea;
- }
- $printAreas = explode(',', $this->printArea);
- if (isset($printAreas[$index - 1])) {
- return $printAreas[$index - 1];
- }
-
- throw new PhpSpreadsheetException('Requested Print Area does not exist');
- }
-
- /**
- * Is print area set?
- *
- * @param int $index Identifier for a specific print area range if several ranges have been set
- * Default behaviour, or an index value of 0, will identify whether any print range is set
- * Otherwise, existence of the range identified by the value of $index will be returned
- * Print areas are numbered from 1
- *
- * @return bool
- */
- public function isPrintAreaSet($index = 0)
- {
- if ($index == 0) {
- return $this->printArea !== null;
- }
- $printAreas = explode(',', $this->printArea);
-
- return isset($printAreas[$index - 1]);
- }
-
- /**
- * Clear a print area.
- *
- * @param int $index Identifier for a specific print area range if several ranges have been set
- * Default behaviour, or an index value of 0, will clear all print ranges that are set
- * Otherwise, the range identified by the value of $index will be removed from the series
- * Print areas are numbered from 1
- *
- * @return $this
- */
- public function clearPrintArea($index = 0)
- {
- if ($index == 0) {
- $this->printArea = null;
- } else {
- $printAreas = explode(',', $this->printArea);
- if (isset($printAreas[$index - 1])) {
- unset($printAreas[$index - 1]);
- $this->printArea = implode(',', $printAreas);
- }
- }
-
- return $this;
- }
-
- /**
- * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20'.
- *
- * @param string $value
- * @param int $index Identifier for a specific print area range allowing several ranges to be set
- * When the method is "O"verwrite, then a positive integer index will overwrite that indexed
- * entry in the print areas list; a negative index value will identify which entry to
- * overwrite working bacward through the print area to the list, with the last entry as -1.
- * Specifying an index value of 0, will overwrite all existing print ranges.
- * When the method is "I"nsert, then a positive index will insert after that indexed entry in
- * the print areas list, while a negative index will insert before the indexed entry.
- * Specifying an index value of 0, will always append the new print range at the end of the
- * list.
- * Print areas are numbered from 1
- * @param string $method Determines the method used when setting multiple print areas
- * Default behaviour, or the "O" method, overwrites existing print area
- * The "I" method, inserts the new print area before any specified index, or at the end of the list
- *
- * @return $this
- */
- public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
- {
- if (strpos($value, '!') !== false) {
- throw new PhpSpreadsheetException('Cell coordinate must not specify a worksheet.');
- } elseif (strpos($value, ':') === false) {
- throw new PhpSpreadsheetException('Cell coordinate must be a range of cells.');
- } elseif (strpos($value, '$') !== false) {
- throw new PhpSpreadsheetException('Cell coordinate must not be absolute.');
- }
- $value = strtoupper($value);
- if (!$this->printArea) {
- $index = 0;
- }
-
- if ($method == self::SETPRINTRANGE_OVERWRITE) {
- if ($index == 0) {
- $this->printArea = $value;
- } else {
- $printAreas = explode(',', $this->printArea);
- if ($index < 0) {
- $index = count($printAreas) - abs($index) + 1;
- }
- if (($index <= 0) || ($index > count($printAreas))) {
- throw new PhpSpreadsheetException('Invalid index for setting print range.');
- }
- $printAreas[$index - 1] = $value;
- $this->printArea = implode(',', $printAreas);
- }
- } elseif ($method == self::SETPRINTRANGE_INSERT) {
- if ($index == 0) {
- $this->printArea = $this->printArea ? ($this->printArea . ',' . $value) : $value;
- } else {
- $printAreas = explode(',', $this->printArea);
- if ($index < 0) {
- $index = abs($index) - 1;
- }
- if ($index > count($printAreas)) {
- throw new PhpSpreadsheetException('Invalid index for setting print range.');
- }
- $printAreas = array_merge(array_slice($printAreas, 0, $index), [$value], array_slice($printAreas, $index));
- $this->printArea = implode(',', $printAreas);
- }
- } else {
- throw new PhpSpreadsheetException('Invalid method for setting print range.');
- }
-
- return $this;
- }
-
- /**
- * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas.
- *
- * @param string $value
- * @param int $index Identifier for a specific print area range allowing several ranges to be set
- * A positive index will insert after that indexed entry in the print areas list, while a
- * negative index will insert before the indexed entry.
- * Specifying an index value of 0, will always append the new print range at the end of the
- * list.
- * Print areas are numbered from 1
- *
- * @return $this
- */
- public function addPrintArea($value, $index = -1)
- {
- return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT);
- }
-
- /**
- * Set print area.
- *
- * @param int $column1 Column 1
- * @param int $row1 Row 1
- * @param int $column2 Column 2
- * @param int $row2 Row 2
- * @param int $index Identifier for a specific print area range allowing several ranges to be set
- * When the method is "O"verwrite, then a positive integer index will overwrite that indexed
- * entry in the print areas list; a negative index value will identify which entry to
- * overwrite working backward through the print area to the list, with the last entry as -1.
- * Specifying an index value of 0, will overwrite all existing print ranges.
- * When the method is "I"nsert, then a positive index will insert after that indexed entry in
- * the print areas list, while a negative index will insert before the indexed entry.
- * Specifying an index value of 0, will always append the new print range at the end of the
- * list.
- * Print areas are numbered from 1
- * @param string $method Determines the method used when setting multiple print areas
- * Default behaviour, or the "O" method, overwrites existing print area
- * The "I" method, inserts the new print area before any specified index, or at the end of the list
- *
- * @return $this
- */
- public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)
- {
- return $this->setPrintArea(
- Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
- $index,
- $method
- );
- }
-
- /**
- * Add a new print area to the list of print areas.
- *
- * @param int $column1 Start Column for the print area
- * @param int $row1 Start Row for the print area
- * @param int $column2 End Column for the print area
- * @param int $row2 End Row for the print area
- * @param int $index Identifier for a specific print area range allowing several ranges to be set
- * A positive index will insert after that indexed entry in the print areas list, while a
- * negative index will insert before the indexed entry.
- * Specifying an index value of 0, will always append the new print range at the end of the
- * list.
- * Print areas are numbered from 1
- *
- * @return $this
- */
- public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1)
- {
- return $this->setPrintArea(
- Coordinate::stringFromColumnIndex($column1) . $row1 . ':' . Coordinate::stringFromColumnIndex($column2) . $row2,
- $index,
- self::SETPRINTRANGE_INSERT
- );
- }
-
- /**
- * Get first page number.
- *
- * @return int
- */
- public function getFirstPageNumber()
- {
- return $this->firstPageNumber;
- }
-
- /**
- * Set first page number.
- *
- * @param int $value
- *
- * @return $this
- */
- public function setFirstPageNumber($value)
- {
- $this->firstPageNumber = $value;
-
- return $this;
- }
-
- /**
- * Reset first page number.
- *
- * @return $this
- */
- public function resetFirstPageNumber()
- {
- return $this->setFirstPageNumber(null);
- }
-
- public function getPageOrder(): string
- {
- return $this->pageOrder;
- }
-
- public function setPageOrder(?string $pageOrder): self
- {
- if ($pageOrder === null || $pageOrder === self::PAGEORDER_DOWN_THEN_OVER || $pageOrder === self::PAGEORDER_OVER_THEN_DOWN) {
- $this->pageOrder = $pageOrder ?? self::PAGEORDER_DOWN_THEN_OVER;
- }
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Protection.php b/vendor/PhpSpreadsheet/Worksheet/Protection.php
deleted file mode 100644
index ba3af0a..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Protection.php
+++ /dev/null
@@ -1,691 +0,0 @@
-sheet ||
- $this->objects ||
- $this->scenarios ||
- $this->formatCells ||
- $this->formatColumns ||
- $this->formatRows ||
- $this->insertColumns ||
- $this->insertRows ||
- $this->insertHyperlinks ||
- $this->deleteColumns ||
- $this->deleteRows ||
- $this->selectLockedCells ||
- $this->sort ||
- $this->autoFilter ||
- $this->pivotTables ||
- $this->selectUnlockedCells;
- }
-
- /**
- * Get Sheet.
- *
- * @return bool
- */
- public function getSheet()
- {
- return $this->sheet;
- }
-
- /**
- * Set Sheet.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSheet($pValue)
- {
- $this->sheet = $pValue;
-
- return $this;
- }
-
- /**
- * Get Objects.
- *
- * @return bool
- */
- public function getObjects()
- {
- return $this->objects;
- }
-
- /**
- * Set Objects.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setObjects($pValue)
- {
- $this->objects = $pValue;
-
- return $this;
- }
-
- /**
- * Get Scenarios.
- *
- * @return bool
- */
- public function getScenarios()
- {
- return $this->scenarios;
- }
-
- /**
- * Set Scenarios.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setScenarios($pValue)
- {
- $this->scenarios = $pValue;
-
- return $this;
- }
-
- /**
- * Get FormatCells.
- *
- * @return bool
- */
- public function getFormatCells()
- {
- return $this->formatCells;
- }
-
- /**
- * Set FormatCells.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setFormatCells($pValue)
- {
- $this->formatCells = $pValue;
-
- return $this;
- }
-
- /**
- * Get FormatColumns.
- *
- * @return bool
- */
- public function getFormatColumns()
- {
- return $this->formatColumns;
- }
-
- /**
- * Set FormatColumns.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setFormatColumns($pValue)
- {
- $this->formatColumns = $pValue;
-
- return $this;
- }
-
- /**
- * Get FormatRows.
- *
- * @return bool
- */
- public function getFormatRows()
- {
- return $this->formatRows;
- }
-
- /**
- * Set FormatRows.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setFormatRows($pValue)
- {
- $this->formatRows = $pValue;
-
- return $this;
- }
-
- /**
- * Get InsertColumns.
- *
- * @return bool
- */
- public function getInsertColumns()
- {
- return $this->insertColumns;
- }
-
- /**
- * Set InsertColumns.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setInsertColumns($pValue)
- {
- $this->insertColumns = $pValue;
-
- return $this;
- }
-
- /**
- * Get InsertRows.
- *
- * @return bool
- */
- public function getInsertRows()
- {
- return $this->insertRows;
- }
-
- /**
- * Set InsertRows.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setInsertRows($pValue)
- {
- $this->insertRows = $pValue;
-
- return $this;
- }
-
- /**
- * Get InsertHyperlinks.
- *
- * @return bool
- */
- public function getInsertHyperlinks()
- {
- return $this->insertHyperlinks;
- }
-
- /**
- * Set InsertHyperlinks.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setInsertHyperlinks($pValue)
- {
- $this->insertHyperlinks = $pValue;
-
- return $this;
- }
-
- /**
- * Get DeleteColumns.
- *
- * @return bool
- */
- public function getDeleteColumns()
- {
- return $this->deleteColumns;
- }
-
- /**
- * Set DeleteColumns.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setDeleteColumns($pValue)
- {
- $this->deleteColumns = $pValue;
-
- return $this;
- }
-
- /**
- * Get DeleteRows.
- *
- * @return bool
- */
- public function getDeleteRows()
- {
- return $this->deleteRows;
- }
-
- /**
- * Set DeleteRows.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setDeleteRows($pValue)
- {
- $this->deleteRows = $pValue;
-
- return $this;
- }
-
- /**
- * Get SelectLockedCells.
- *
- * @return bool
- */
- public function getSelectLockedCells()
- {
- return $this->selectLockedCells;
- }
-
- /**
- * Set SelectLockedCells.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSelectLockedCells($pValue)
- {
- $this->selectLockedCells = $pValue;
-
- return $this;
- }
-
- /**
- * Get Sort.
- *
- * @return bool
- */
- public function getSort()
- {
- return $this->sort;
- }
-
- /**
- * Set Sort.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSort($pValue)
- {
- $this->sort = $pValue;
-
- return $this;
- }
-
- /**
- * Get AutoFilter.
- *
- * @return bool
- */
- public function getAutoFilter()
- {
- return $this->autoFilter;
- }
-
- /**
- * Set AutoFilter.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setAutoFilter($pValue)
- {
- $this->autoFilter = $pValue;
-
- return $this;
- }
-
- /**
- * Get PivotTables.
- *
- * @return bool
- */
- public function getPivotTables()
- {
- return $this->pivotTables;
- }
-
- /**
- * Set PivotTables.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setPivotTables($pValue)
- {
- $this->pivotTables = $pValue;
-
- return $this;
- }
-
- /**
- * Get SelectUnlockedCells.
- *
- * @return bool
- */
- public function getSelectUnlockedCells()
- {
- return $this->selectUnlockedCells;
- }
-
- /**
- * Set SelectUnlockedCells.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setSelectUnlockedCells($pValue)
- {
- $this->selectUnlockedCells = $pValue;
-
- return $this;
- }
-
- /**
- * Get hashed password.
- *
- * @return string
- */
- public function getPassword()
- {
- return $this->password;
- }
-
- /**
- * Set Password.
- *
- * @param string $pValue
- * @param bool $pAlreadyHashed If the password has already been hashed, set this to true
- *
- * @return $this
- */
- public function setPassword($pValue, $pAlreadyHashed = false)
- {
- if (!$pAlreadyHashed) {
- $salt = $this->generateSalt();
- $this->setSalt($salt);
- $pValue = PasswordHasher::hashPassword($pValue, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
- }
-
- $this->password = $pValue;
-
- return $this;
- }
-
- /**
- * Create a pseudorandom string.
- */
- private function generateSalt(): string
- {
- return base64_encode(random_bytes(16));
- }
-
- /**
- * Get algorithm name.
- */
- public function getAlgorithm(): string
- {
- return $this->algorithm;
- }
-
- /**
- * Set algorithm name.
- */
- public function setAlgorithm(string $algorithm): void
- {
- $this->algorithm = $algorithm;
- }
-
- /**
- * Get salt value.
- */
- public function getSalt(): string
- {
- return $this->salt;
- }
-
- /**
- * Set salt value.
- */
- public function setSalt(string $salt): void
- {
- $this->salt = $salt;
- }
-
- /**
- * Get spin count.
- */
- public function getSpinCount(): int
- {
- return $this->spinCount;
- }
-
- /**
- * Set spin count.
- */
- public function setSpinCount(int $spinCount): void
- {
- $this->spinCount = $spinCount;
- }
-
- /**
- * Verify that the given non-hashed password can "unlock" the protection.
- */
- public function verify(string $password): bool
- {
- if (!$this->isProtectionEnabled()) {
- return true;
- }
-
- $hash = PasswordHasher::hashPassword($password, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
-
- return $this->getPassword() === $hash;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Row.php b/vendor/PhpSpreadsheet/Worksheet/Row.php
deleted file mode 100644
index 4f48a34..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Row.php
+++ /dev/null
@@ -1,74 +0,0 @@
-worksheet = $worksheet;
- $this->rowIndex = $rowIndex;
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->worksheet = null;
- }
-
- /**
- * Get row index.
- *
- * @return int
- */
- public function getRowIndex()
- {
- return $this->rowIndex;
- }
-
- /**
- * Get cell iterator.
- *
- * @param string $startColumn The column address at which to start iterating
- * @param string $endColumn Optionally, the column address at which to stop iterating
- *
- * @return RowCellIterator
- */
- public function getCellIterator($startColumn = 'A', $endColumn = null)
- {
- return new RowCellIterator($this->worksheet, $this->rowIndex, $startColumn, $endColumn);
- }
-
- /**
- * Returns bound worksheet.
- *
- * @return Worksheet
- */
- public function getWorksheet()
- {
- return $this->worksheet;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/RowCellIterator.php b/vendor/PhpSpreadsheet/Worksheet/RowCellIterator.php
deleted file mode 100644
index f5576dc..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/RowCellIterator.php
+++ /dev/null
@@ -1,195 +0,0 @@
-worksheet = $worksheet;
- $this->rowIndex = $rowIndex;
- $this->resetEnd($endColumn);
- $this->resetStart($startColumn);
- }
-
- /**
- * (Re)Set the start column and the current column pointer.
- *
- * @param string $startColumn The column address at which to start iterating
- *
- * @return $this
- */
- public function resetStart($startColumn = 'A')
- {
- $this->startColumnIndex = Coordinate::columnIndexFromString($startColumn);
- $this->adjustForExistingOnlyRange();
- $this->seek(Coordinate::stringFromColumnIndex($this->startColumnIndex));
-
- return $this;
- }
-
- /**
- * (Re)Set the end column.
- *
- * @param string $endColumn The column address at which to stop iterating
- *
- * @return $this
- */
- public function resetEnd($endColumn = null)
- {
- $endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
- $this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
- $this->adjustForExistingOnlyRange();
-
- return $this;
- }
-
- /**
- * Set the column pointer to the selected column.
- *
- * @param string $column The column address to set the current pointer at
- *
- * @return $this
- */
- public function seek($column = 'A')
- {
- $column = Coordinate::columnIndexFromString($column);
- if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
- throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
- } elseif ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($column, $this->rowIndex))) {
- throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
- }
- $this->currentColumnIndex = $column;
-
- return $this;
- }
-
- /**
- * Rewind the iterator to the starting column.
- */
- public function rewind(): void
- {
- $this->currentColumnIndex = $this->startColumnIndex;
- }
-
- /**
- * Return the current cell in this worksheet row.
- *
- * @return \PhpOffice\PhpSpreadsheet\Cell\Cell
- */
- public function current()
- {
- return $this->worksheet->getCellByColumnAndRow($this->currentColumnIndex, $this->rowIndex);
- }
-
- /**
- * Return the current iterator key.
- *
- * @return string
- */
- public function key()
- {
- return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
- }
-
- /**
- * Set the iterator to its next value.
- */
- public function next(): void
- {
- do {
- ++$this->currentColumnIndex;
- } while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex <= $this->endColumnIndex));
- }
-
- /**
- * Set the iterator to its previous value.
- */
- public function prev(): void
- {
- do {
- --$this->currentColumnIndex;
- } while (($this->onlyExistingCells) && (!$this->worksheet->cellExistsByColumnAndRow($this->currentColumnIndex, $this->rowIndex)) && ($this->currentColumnIndex >= $this->startColumnIndex));
- }
-
- /**
- * Indicate if more columns exist in the worksheet range of columns that we're iterating.
- *
- * @return bool
- */
- public function valid()
- {
- return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
- }
-
- /**
- * Return the current iterator position.
- *
- * @return int
- */
- public function getCurrentColumnIndex()
- {
- return $this->currentColumnIndex;
- }
-
- /**
- * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
- */
- protected function adjustForExistingOnlyRange(): void
- {
- if ($this->onlyExistingCells) {
- while ((!$this->worksheet->cellExistsByColumnAndRow($this->startColumnIndex, $this->rowIndex)) && ($this->startColumnIndex <= $this->endColumnIndex)) {
- ++$this->startColumnIndex;
- }
- if ($this->startColumnIndex > $this->endColumnIndex) {
- throw new PhpSpreadsheetException('No cells exist within the specified range');
- }
- while ((!$this->worksheet->cellExistsByColumnAndRow($this->endColumnIndex, $this->rowIndex)) && ($this->endColumnIndex >= $this->startColumnIndex)) {
- --$this->endColumnIndex;
- }
- if ($this->endColumnIndex < $this->startColumnIndex) {
- throw new PhpSpreadsheetException('No cells exist within the specified range');
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/RowDimension.php b/vendor/PhpSpreadsheet/Worksheet/RowDimension.php
deleted file mode 100644
index c4a87bd..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/RowDimension.php
+++ /dev/null
@@ -1,115 +0,0 @@
-rowIndex = $pIndex;
-
- // set dimension as unformatted by default
- parent::__construct(null);
- }
-
- /**
- * Get Row Index.
- *
- * @return int
- */
- public function getRowIndex()
- {
- return $this->rowIndex;
- }
-
- /**
- * Set Row Index.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setRowIndex($pValue)
- {
- $this->rowIndex = $pValue;
-
- return $this;
- }
-
- /**
- * Get Row Height.
- *
- * @return float
- */
- public function getRowHeight()
- {
- return $this->height;
- }
-
- /**
- * Set Row Height.
- *
- * @param float $pValue
- *
- * @return $this
- */
- public function setRowHeight($pValue)
- {
- $this->height = $pValue;
-
- return $this;
- }
-
- /**
- * Get ZeroHeight.
- *
- * @return bool
- */
- public function getZeroHeight()
- {
- return $this->zeroHeight;
- }
-
- /**
- * Set ZeroHeight.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setZeroHeight($pValue)
- {
- $this->zeroHeight = $pValue;
-
- return $this;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/RowIterator.php b/vendor/PhpSpreadsheet/Worksheet/RowIterator.php
deleted file mode 100644
index 4254253..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/RowIterator.php
+++ /dev/null
@@ -1,167 +0,0 @@
-subject = $subject;
- $this->resetEnd($endRow);
- $this->resetStart($startRow);
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->subject = null;
- }
-
- /**
- * (Re)Set the start row and the current row pointer.
- *
- * @param int $startRow The row number at which to start iterating
- *
- * @return $this
- */
- public function resetStart($startRow = 1)
- {
- if ($startRow > $this->subject->getHighestRow()) {
- throw new PhpSpreadsheetException("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
- }
-
- $this->startRow = $startRow;
- if ($this->endRow < $this->startRow) {
- $this->endRow = $this->startRow;
- }
- $this->seek($startRow);
-
- return $this;
- }
-
- /**
- * (Re)Set the end row.
- *
- * @param int $endRow The row number at which to stop iterating
- *
- * @return $this
- */
- public function resetEnd($endRow = null)
- {
- $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
-
- return $this;
- }
-
- /**
- * Set the row pointer to the selected row.
- *
- * @param int $row The row number to set the current pointer at
- *
- * @return $this
- */
- public function seek($row = 1)
- {
- if (($row < $this->startRow) || ($row > $this->endRow)) {
- throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
- }
- $this->position = $row;
-
- return $this;
- }
-
- /**
- * Rewind the iterator to the starting row.
- */
- public function rewind(): void
- {
- $this->position = $this->startRow;
- }
-
- /**
- * Return the current row in this worksheet.
- *
- * @return Row
- */
- public function current()
- {
- return new Row($this->subject, $this->position);
- }
-
- /**
- * Return the current iterator key.
- *
- * @return int
- */
- public function key()
- {
- return $this->position;
- }
-
- /**
- * Set the iterator to its next value.
- */
- public function next(): void
- {
- ++$this->position;
- }
-
- /**
- * Set the iterator to its previous value.
- */
- public function prev(): void
- {
- --$this->position;
- }
-
- /**
- * Indicate if more rows exist in the worksheet range of rows that we're iterating.
- *
- * @return bool
- */
- public function valid()
- {
- return $this->position <= $this->endRow && $this->position >= $this->startRow;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/SheetView.php b/vendor/PhpSpreadsheet/Worksheet/SheetView.php
deleted file mode 100644
index 2f7d381..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/SheetView.php
+++ /dev/null
@@ -1,193 +0,0 @@
-zoomScale;
- }
-
- /**
- * Set ZoomScale.
- * Valid values range from 10 to 400.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setZoomScale($pValue)
- {
- // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
- // but it is apparently still able to handle any scale >= 1
- if (($pValue >= 1) || $pValue === null) {
- $this->zoomScale = $pValue;
- } else {
- throw new PhpSpreadsheetException('Scale must be greater than or equal to 1.');
- }
-
- return $this;
- }
-
- /**
- * Get ZoomScaleNormal.
- *
- * @return int
- */
- public function getZoomScaleNormal()
- {
- return $this->zoomScaleNormal;
- }
-
- /**
- * Set ZoomScale.
- * Valid values range from 10 to 400.
- *
- * @param int $pValue
- *
- * @return $this
- */
- public function setZoomScaleNormal($pValue)
- {
- if (($pValue >= 1) || $pValue === null) {
- $this->zoomScaleNormal = $pValue;
- } else {
- throw new PhpSpreadsheetException('Scale must be greater than or equal to 1.');
- }
-
- return $this;
- }
-
- /**
- * Set ShowZeroes setting.
- *
- * @param bool $pValue
- */
- public function setShowZeros($pValue): void
- {
- $this->showZeros = $pValue;
- }
-
- /**
- * @return bool
- */
- public function getShowZeros()
- {
- return $this->showZeros;
- }
-
- /**
- * Get View.
- *
- * @return string
- */
- public function getView()
- {
- return $this->sheetviewType;
- }
-
- /**
- * Set View.
- *
- * Valid values are
- * 'normal' self::SHEETVIEW_NORMAL
- * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT
- * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setView($pValue)
- {
- // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' via the user interface
- if ($pValue === null) {
- $pValue = self::SHEETVIEW_NORMAL;
- }
- if (in_array($pValue, self::$sheetViewTypes)) {
- $this->sheetviewType = $pValue;
- } else {
- throw new PhpSpreadsheetException('Invalid sheetview layout type.');
- }
-
- return $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- $vars = get_object_vars($this);
- foreach ($vars as $key => $value) {
- if (is_object($value)) {
- $this->$key = clone $value;
- } else {
- $this->$key = $value;
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Worksheet/Worksheet.php b/vendor/PhpSpreadsheet/Worksheet/Worksheet.php
deleted file mode 100644
index 19833b7..0000000
--- a/vendor/PhpSpreadsheet/Worksheet/Worksheet.php
+++ /dev/null
@@ -1,3019 +0,0 @@
-parent = $parent;
- $this->setTitle($pTitle, false);
- // setTitle can change $pTitle
- $this->setCodeName($this->getTitle());
- $this->setSheetState(self::SHEETSTATE_VISIBLE);
-
- $this->cellCollection = CellsFactory::getInstance($this);
- // Set page setup
- $this->pageSetup = new PageSetup();
- // Set page margins
- $this->pageMargins = new PageMargins();
- // Set page header/footer
- $this->headerFooter = new HeaderFooter();
- // Set sheet view
- $this->sheetView = new SheetView();
- // Drawing collection
- $this->drawingCollection = new ArrayObject();
- // Chart collection
- $this->chartCollection = new ArrayObject();
- // Protection
- $this->protection = new Protection();
- // Default row dimension
- $this->defaultRowDimension = new RowDimension(null);
- // Default column dimension
- $this->defaultColumnDimension = new ColumnDimension(null);
- $this->autoFilter = new AutoFilter(null, $this);
- }
-
- /**
- * Disconnect all cells from this Worksheet object,
- * typically so that the worksheet object can be unset.
- */
- public function disconnectCells(): void
- {
- if ($this->cellCollection !== null) {
- $this->cellCollection->unsetWorksheetCells();
- $this->cellCollection = null;
- }
- // detach ourself from the workbook, so that it can then delete this worksheet successfully
- $this->parent = null;
- }
-
- /**
- * Code to execute when this worksheet is unset().
- */
- public function __destruct()
- {
- Calculation::getInstance($this->parent)->clearCalculationCacheForWorksheet($this->title);
-
- $this->disconnectCells();
- }
-
- /**
- * Return the cell collection.
- *
- * @return Cells
- */
- public function getCellCollection()
- {
- return $this->cellCollection;
- }
-
- /**
- * Get array of invalid characters for sheet title.
- *
- * @return array
- */
- public static function getInvalidCharacters()
- {
- return self::$invalidCharacters;
- }
-
- /**
- * Check sheet code name for valid Excel syntax.
- *
- * @param string $pValue The string to check
- *
- * @return string The valid string
- */
- private static function checkSheetCodeName($pValue)
- {
- $CharCount = Shared\StringHelper::countCharacters($pValue);
- if ($CharCount == 0) {
- throw new Exception('Sheet code name cannot be empty.');
- }
- // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'"
- if (
- (str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) ||
- (Shared\StringHelper::substring($pValue, -1, 1) == '\'') ||
- (Shared\StringHelper::substring($pValue, 0, 1) == '\'')
- ) {
- throw new Exception('Invalid character found in sheet code name');
- }
-
- // Enforce maximum characters allowed for sheet title
- if ($CharCount > self::SHEET_TITLE_MAXIMUM_LENGTH) {
- throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet code name.');
- }
-
- return $pValue;
- }
-
- /**
- * Check sheet title for valid Excel syntax.
- *
- * @param string $pValue The string to check
- *
- * @return string The valid string
- */
- private static function checkSheetTitle($pValue)
- {
- // Some of the printable ASCII characters are invalid: * : / \ ? [ ]
- if (str_replace(self::$invalidCharacters, '', $pValue) !== $pValue) {
- throw new Exception('Invalid character found in sheet title');
- }
-
- // Enforce maximum characters allowed for sheet title
- if (Shared\StringHelper::countCharacters($pValue) > self::SHEET_TITLE_MAXIMUM_LENGTH) {
- throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.');
- }
-
- return $pValue;
- }
-
- /**
- * Get a sorted list of all cell coordinates currently held in the collection by row and column.
- *
- * @param bool $sorted Also sort the cell collection?
- *
- * @return string[]
- */
- public function getCoordinates($sorted = true)
- {
- if ($this->cellCollection == null) {
- return [];
- }
-
- if ($sorted) {
- return $this->cellCollection->getSortedCoordinates();
- }
-
- return $this->cellCollection->getCoordinates();
- }
-
- /**
- * Get collection of row dimensions.
- *
- * @return RowDimension[]
- */
- public function getRowDimensions()
- {
- return $this->rowDimensions;
- }
-
- /**
- * Get default row dimension.
- *
- * @return RowDimension
- */
- public function getDefaultRowDimension()
- {
- return $this->defaultRowDimension;
- }
-
- /**
- * Get collection of column dimensions.
- *
- * @return ColumnDimension[]
- */
- public function getColumnDimensions()
- {
- return $this->columnDimensions;
- }
-
- /**
- * Get default column dimension.
- *
- * @return ColumnDimension
- */
- public function getDefaultColumnDimension()
- {
- return $this->defaultColumnDimension;
- }
-
- /**
- * Get collection of drawings.
- *
- * @return BaseDrawing[]
- */
- public function getDrawingCollection()
- {
- return $this->drawingCollection;
- }
-
- /**
- * Get collection of charts.
- *
- * @return Chart[]
- */
- public function getChartCollection()
- {
- return $this->chartCollection;
- }
-
- /**
- * Add chart.
- *
- * @param null|int $iChartIndex Index where chart should go (0,1,..., or null for last)
- *
- * @return Chart
- */
- public function addChart(Chart $pChart, $iChartIndex = null)
- {
- $pChart->setWorksheet($this);
- if ($iChartIndex === null) {
- $this->chartCollection[] = $pChart;
- } else {
- // Insert the chart at the requested index
- array_splice($this->chartCollection, $iChartIndex, 0, [$pChart]);
- }
-
- return $pChart;
- }
-
- /**
- * Return the count of charts on this worksheet.
- *
- * @return int The number of charts
- */
- public function getChartCount()
- {
- return count($this->chartCollection);
- }
-
- /**
- * Get a chart by its index position.
- *
- * @param string $index Chart index position
- *
- * @return Chart|false
- */
- public function getChartByIndex($index)
- {
- $chartCount = count($this->chartCollection);
- if ($chartCount == 0) {
- return false;
- }
- if ($index === null) {
- $index = --$chartCount;
- }
- if (!isset($this->chartCollection[$index])) {
- return false;
- }
-
- return $this->chartCollection[$index];
- }
-
- /**
- * Return an array of the names of charts on this worksheet.
- *
- * @return string[] The names of charts
- */
- public function getChartNames()
- {
- $chartNames = [];
- foreach ($this->chartCollection as $chart) {
- $chartNames[] = $chart->getName();
- }
-
- return $chartNames;
- }
-
- /**
- * Get a chart by name.
- *
- * @param string $chartName Chart name
- *
- * @return Chart|false
- */
- public function getChartByName($chartName)
- {
- $chartCount = count($this->chartCollection);
- if ($chartCount == 0) {
- return false;
- }
- foreach ($this->chartCollection as $index => $chart) {
- if ($chart->getName() == $chartName) {
- return $this->chartCollection[$index];
- }
- }
-
- return false;
- }
-
- /**
- * Refresh column dimensions.
- *
- * @return $this
- */
- public function refreshColumnDimensions()
- {
- $currentColumnDimensions = $this->getColumnDimensions();
- $newColumnDimensions = [];
-
- foreach ($currentColumnDimensions as $objColumnDimension) {
- $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension;
- }
-
- $this->columnDimensions = $newColumnDimensions;
-
- return $this;
- }
-
- /**
- * Refresh row dimensions.
- *
- * @return $this
- */
- public function refreshRowDimensions()
- {
- $currentRowDimensions = $this->getRowDimensions();
- $newRowDimensions = [];
-
- foreach ($currentRowDimensions as $objRowDimension) {
- $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension;
- }
-
- $this->rowDimensions = $newRowDimensions;
-
- return $this;
- }
-
- /**
- * Calculate worksheet dimension.
- *
- * @return string String containing the dimension of this worksheet
- */
- public function calculateWorksheetDimension()
- {
- // Return
- return 'A1:' . $this->getHighestColumn() . $this->getHighestRow();
- }
-
- /**
- * Calculate worksheet data dimension.
- *
- * @return string String containing the dimension of this worksheet that actually contain data
- */
- public function calculateWorksheetDataDimension()
- {
- // Return
- return 'A1:' . $this->getHighestDataColumn() . $this->getHighestDataRow();
- }
-
- /**
- * Calculate widths for auto-size columns.
- *
- * @return $this
- */
- public function calculateColumnWidths()
- {
- // initialize $autoSizes array
- $autoSizes = [];
- foreach ($this->getColumnDimensions() as $colDimension) {
- if ($colDimension->getAutoSize()) {
- $autoSizes[$colDimension->getColumnIndex()] = -1;
- }
- }
-
- // There is only something to do if there are some auto-size columns
- if (!empty($autoSizes)) {
- // build list of cells references that participate in a merge
- $isMergeCell = [];
- foreach ($this->getMergeCells() as $cells) {
- foreach (Coordinate::extractAllCellReferencesInRange($cells) as $cellReference) {
- $isMergeCell[$cellReference] = true;
- }
- }
-
- // loop through all cells in the worksheet
- foreach ($this->getCoordinates(false) as $coordinate) {
- $cell = $this->getCell($coordinate, false);
- if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) {
- //Determine if cell is in merge range
- $isMerged = isset($isMergeCell[$this->cellCollection->getCurrentCoordinate()]);
-
- //By default merged cells should be ignored
- $isMergedButProceed = false;
-
- //The only exception is if it's a merge range value cell of a 'vertical' randge (1 column wide)
- if ($isMerged && $cell->isMergeRangeValueCell()) {
- $range = $cell->getMergeRange();
- $rangeBoundaries = Coordinate::rangeDimension($range);
- if ($rangeBoundaries[0] == 1) {
- $isMergedButProceed = true;
- }
- }
-
- // Determine width if cell does not participate in a merge or does and is a value cell of 1-column wide range
- if (!$isMerged || $isMergedButProceed) {
- // Calculated value
- // To formatted string
- $cellValue = NumberFormat::toFormattedString(
- $cell->getCalculatedValue(),
- $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()
- );
-
- $autoSizes[$this->cellCollection->getCurrentColumn()] = max(
- (float) $autoSizes[$this->cellCollection->getCurrentColumn()],
- (float) Shared\Font::calculateColumnWidth(
- $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),
- $cellValue,
- $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),
- $this->getParent()->getDefaultStyle()->getFont()
- )
- );
- }
- }
- }
-
- // adjust column widths
- foreach ($autoSizes as $columnIndex => $width) {
- if ($width == -1) {
- $width = $this->getDefaultColumnDimension()->getWidth();
- }
- $this->getColumnDimension($columnIndex)->setWidth($width);
- }
- }
-
- return $this;
- }
-
- /**
- * Get parent.
- *
- * @return Spreadsheet
- */
- public function getParent()
- {
- return $this->parent;
- }
-
- /**
- * Re-bind parent.
- *
- * @return $this
- */
- public function rebindParent(Spreadsheet $parent)
- {
- if ($this->parent !== null) {
- $definedNames = $this->parent->getDefinedNames();
- foreach ($definedNames as $definedName) {
- $parent->addDefinedName($definedName);
- }
-
- $this->parent->removeSheetByIndex(
- $this->parent->getIndex($this)
- );
- }
- $this->parent = $parent;
-
- return $this;
- }
-
- /**
- * Get title.
- *
- * @return string
- */
- public function getTitle()
- {
- return $this->title;
- }
-
- /**
- * Set title.
- *
- * @param string $pValue String containing the dimension of this worksheet
- * @param bool $updateFormulaCellReferences Flag indicating whether cell references in formulae should
- * be updated to reflect the new sheet name.
- * This should be left as the default true, unless you are
- * certain that no formula cells on any worksheet contain
- * references to this worksheet
- * @param bool $validate False to skip validation of new title. WARNING: This should only be set
- * at parse time (by Readers), where titles can be assumed to be valid.
- *
- * @return $this
- */
- public function setTitle($pValue, $updateFormulaCellReferences = true, $validate = true)
- {
- // Is this a 'rename' or not?
- if ($this->getTitle() == $pValue) {
- return $this;
- }
-
- // Old title
- $oldTitle = $this->getTitle();
-
- if ($validate) {
- // Syntax check
- self::checkSheetTitle($pValue);
-
- if ($this->parent) {
- // Is there already such sheet name?
- if ($this->parent->sheetNameExists($pValue)) {
- // Use name, but append with lowest possible integer
-
- if (Shared\StringHelper::countCharacters($pValue) > 29) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 29);
- }
- $i = 1;
- while ($this->parent->sheetNameExists($pValue . ' ' . $i)) {
- ++$i;
- if ($i == 10) {
- if (Shared\StringHelper::countCharacters($pValue) > 28) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 28);
- }
- } elseif ($i == 100) {
- if (Shared\StringHelper::countCharacters($pValue) > 27) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 27);
- }
- }
- }
-
- $pValue .= " $i";
- }
- }
- }
-
- // Set title
- $this->title = $pValue;
- $this->dirty = true;
-
- if ($this->parent && $this->parent->getCalculationEngine()) {
- // New title
- $newTitle = $this->getTitle();
- $this->parent->getCalculationEngine()
- ->renameCalculationCacheForWorksheet($oldTitle, $newTitle);
- if ($updateFormulaCellReferences) {
- ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle);
- }
- }
-
- return $this;
- }
-
- /**
- * Get sheet state.
- *
- * @return string Sheet state (visible, hidden, veryHidden)
- */
- public function getSheetState()
- {
- return $this->sheetState;
- }
-
- /**
- * Set sheet state.
- *
- * @param string $value Sheet state (visible, hidden, veryHidden)
- *
- * @return $this
- */
- public function setSheetState($value)
- {
- $this->sheetState = $value;
-
- return $this;
- }
-
- /**
- * Get page setup.
- *
- * @return PageSetup
- */
- public function getPageSetup()
- {
- return $this->pageSetup;
- }
-
- /**
- * Set page setup.
- *
- * @return $this
- */
- public function setPageSetup(PageSetup $pValue)
- {
- $this->pageSetup = $pValue;
-
- return $this;
- }
-
- /**
- * Get page margins.
- *
- * @return PageMargins
- */
- public function getPageMargins()
- {
- return $this->pageMargins;
- }
-
- /**
- * Set page margins.
- *
- * @return $this
- */
- public function setPageMargins(PageMargins $pValue)
- {
- $this->pageMargins = $pValue;
-
- return $this;
- }
-
- /**
- * Get page header/footer.
- *
- * @return HeaderFooter
- */
- public function getHeaderFooter()
- {
- return $this->headerFooter;
- }
-
- /**
- * Set page header/footer.
- *
- * @return $this
- */
- public function setHeaderFooter(HeaderFooter $pValue)
- {
- $this->headerFooter = $pValue;
-
- return $this;
- }
-
- /**
- * Get sheet view.
- *
- * @return SheetView
- */
- public function getSheetView()
- {
- return $this->sheetView;
- }
-
- /**
- * Set sheet view.
- *
- * @return $this
- */
- public function setSheetView(SheetView $pValue)
- {
- $this->sheetView = $pValue;
-
- return $this;
- }
-
- /**
- * Get Protection.
- *
- * @return Protection
- */
- public function getProtection()
- {
- return $this->protection;
- }
-
- /**
- * Set Protection.
- *
- * @return $this
- */
- public function setProtection(Protection $pValue)
- {
- $this->protection = $pValue;
- $this->dirty = true;
-
- return $this;
- }
-
- /**
- * Get highest worksheet column.
- *
- * @param string $row Return the data highest column for the specified row,
- * or the highest column of any row if no row number is passed
- *
- * @return string Highest column name
- */
- public function getHighestColumn($row = null)
- {
- if ($row == null) {
- return $this->cachedHighestColumn;
- }
-
- return $this->getHighestDataColumn($row);
- }
-
- /**
- * Get highest worksheet column that contains data.
- *
- * @param string $row Return the highest data column for the specified row,
- * or the highest data column of any row if no row number is passed
- *
- * @return string Highest column name that contains data
- */
- public function getHighestDataColumn($row = null)
- {
- return $this->cellCollection->getHighestColumn($row);
- }
-
- /**
- * Get highest worksheet row.
- *
- * @param string $column Return the highest data row for the specified column,
- * or the highest row of any column if no column letter is passed
- *
- * @return int Highest row number
- */
- public function getHighestRow($column = null)
- {
- if ($column == null) {
- return $this->cachedHighestRow;
- }
-
- return $this->getHighestDataRow($column);
- }
-
- /**
- * Get highest worksheet row that contains data.
- *
- * @param string $column Return the highest data row for the specified column,
- * or the highest data row of any column if no column letter is passed
- *
- * @return int Highest row number that contains data
- */
- public function getHighestDataRow($column = null)
- {
- return $this->cellCollection->getHighestRow($column);
- }
-
- /**
- * Get highest worksheet column and highest row that have cell records.
- *
- * @return array Highest column name and highest row number
- */
- public function getHighestRowAndColumn()
- {
- return $this->cellCollection->getHighestRowAndColumn();
- }
-
- /**
- * Set a cell value.
- *
- * @param string $pCoordinate Coordinate of the cell, eg: 'A1'
- * @param mixed $pValue Value of the cell
- *
- * @return $this
- */
- public function setCellValue($pCoordinate, $pValue)
- {
- $this->getCell($pCoordinate)->setValue($pValue);
-
- return $this;
- }
-
- /**
- * Set a cell value by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- * @param mixed $value Value of the cell
- *
- * @return $this
- */
- public function setCellValueByColumnAndRow($columnIndex, $row, $value)
- {
- $this->getCellByColumnAndRow($columnIndex, $row)->setValue($value);
-
- return $this;
- }
-
- /**
- * Set a cell value.
- *
- * @param string $pCoordinate Coordinate of the cell, eg: 'A1'
- * @param mixed $pValue Value of the cell
- * @param string $pDataType Explicit data type, see DataType::TYPE_*
- *
- * @return $this
- */
- public function setCellValueExplicit($pCoordinate, $pValue, $pDataType)
- {
- // Set value
- $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType);
-
- return $this;
- }
-
- /**
- * Set a cell value by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- * @param mixed $value Value of the cell
- * @param string $dataType Explicit data type, see DataType::TYPE_*
- *
- * @return $this
- */
- public function setCellValueExplicitByColumnAndRow($columnIndex, $row, $value, $dataType)
- {
- $this->getCellByColumnAndRow($columnIndex, $row)->setValueExplicit($value, $dataType);
-
- return $this;
- }
-
- /**
- * Get cell at a specific coordinate.
- *
- * @param string $pCoordinate Coordinate of the cell, eg: 'A1'
- * @param bool $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
- * already exist, or a null should be returned instead
- *
- * @return null|Cell Cell that was found/created or null
- */
- public function getCell($pCoordinate, $createIfNotExists = true)
- {
- // Uppercase coordinate
- $pCoordinateUpper = strtoupper($pCoordinate);
-
- // Check cell collection
- if ($this->cellCollection->has($pCoordinateUpper)) {
- return $this->cellCollection->get($pCoordinateUpper);
- }
-
- // Worksheet reference?
- if (strpos($pCoordinate, '!') !== false) {
- $worksheetReference = self::extractSheetTitle($pCoordinate, true);
-
- return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1]), $createIfNotExists);
- }
-
- // Named range?
- if (
- (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $pCoordinate, $matches)) &&
- (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $pCoordinate, $matches))
- ) {
- $namedRange = DefinedName::resolveName($pCoordinate, $this);
- if ($namedRange !== null) {
- $pCoordinate = $namedRange->getValue();
-
- return $namedRange->getWorksheet()->getCell($pCoordinate, $createIfNotExists);
- }
- }
-
- if (Coordinate::coordinateIsRange($pCoordinate)) {
- throw new Exception('Cell coordinate can not be a range of cells.');
- } elseif (strpos($pCoordinate, '$') !== false) {
- throw new Exception('Cell coordinate must not be absolute.');
- }
-
- // Create new cell object, if required
- return $createIfNotExists ? $this->createNewCell($pCoordinateUpper) : null;
- }
-
- /**
- * Get cell at a specific coordinate by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- * @param bool $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
- * already exist, or a null should be returned instead
- *
- * @return null|Cell Cell that was found/created or null
- */
- public function getCellByColumnAndRow($columnIndex, $row, $createIfNotExists = true)
- {
- $columnLetter = Coordinate::stringFromColumnIndex($columnIndex);
- $coordinate = $columnLetter . $row;
-
- if ($this->cellCollection->has($coordinate)) {
- return $this->cellCollection->get($coordinate);
- }
-
- // Create new cell object, if required
- return $createIfNotExists ? $this->createNewCell($coordinate) : null;
- }
-
- /**
- * Create a new cell at the specified coordinate.
- *
- * @param string $pCoordinate Coordinate of the cell
- *
- * @return Cell Cell that was created
- */
- private function createNewCell($pCoordinate)
- {
- $cell = new Cell(null, DataType::TYPE_NULL, $this);
- $this->cellCollection->add($pCoordinate, $cell);
- $this->cellCollectionIsSorted = false;
-
- // Coordinates
- $aCoordinates = Coordinate::coordinateFromString($pCoordinate);
- if (Coordinate::columnIndexFromString($this->cachedHighestColumn) < Coordinate::columnIndexFromString($aCoordinates[0])) {
- $this->cachedHighestColumn = $aCoordinates[0];
- }
- if ($aCoordinates[1] > $this->cachedHighestRow) {
- $this->cachedHighestRow = $aCoordinates[1];
- }
-
- // Cell needs appropriate xfIndex from dimensions records
- // but don't create dimension records if they don't already exist
- $rowDimension = $this->getRowDimension($aCoordinates[1], false);
- $columnDimension = $this->getColumnDimension($aCoordinates[0], false);
-
- if ($rowDimension !== null && $rowDimension->getXfIndex() > 0) {
- // then there is a row dimension with explicit style, assign it to the cell
- $cell->setXfIndex($rowDimension->getXfIndex());
- } elseif ($columnDimension !== null && $columnDimension->getXfIndex() > 0) {
- // then there is a column dimension, assign it to the cell
- $cell->setXfIndex($columnDimension->getXfIndex());
- }
-
- return $cell;
- }
-
- /**
- * Does the cell at a specific coordinate exist?
- *
- * @param string $pCoordinate Coordinate of the cell eg: 'A1'
- *
- * @return bool
- */
- public function cellExists($pCoordinate)
- {
- // Worksheet reference?
- if (strpos($pCoordinate, '!') !== false) {
- $worksheetReference = self::extractSheetTitle($pCoordinate, true);
-
- return $this->parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1]));
- }
-
- // Named range?
- if (
- (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $pCoordinate, $matches)) &&
- (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $pCoordinate, $matches))
- ) {
- $namedRange = DefinedName::resolveName($pCoordinate, $this);
- if ($namedRange !== null) {
- $pCoordinate = $namedRange->getValue();
- if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {
- if (!$namedRange->getLocalOnly()) {
- return $namedRange->getWorksheet()->cellExists($pCoordinate);
- }
-
- throw new Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());
- }
- } else {
- return false;
- }
- }
-
- // Uppercase coordinate
- $pCoordinate = strtoupper($pCoordinate);
-
- if (Coordinate::coordinateIsRange($pCoordinate)) {
- throw new Exception('Cell coordinate can not be a range of cells.');
- } elseif (strpos($pCoordinate, '$') !== false) {
- throw new Exception('Cell coordinate must not be absolute.');
- }
-
- // Cell exists?
- return $this->cellCollection->has($pCoordinate);
- }
-
- /**
- * Cell at a specific coordinate by using numeric cell coordinates exists?
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- *
- * @return bool
- */
- public function cellExistsByColumnAndRow($columnIndex, $row)
- {
- return $this->cellExists(Coordinate::stringFromColumnIndex($columnIndex) . $row);
- }
-
- /**
- * Get row dimension at a specific row.
- *
- * @param int $pRow Numeric index of the row
- * @param bool $create
- *
- * @return RowDimension
- */
- public function getRowDimension($pRow, $create = true)
- {
- // Found
- $found = null;
-
- // Get row dimension
- if (!isset($this->rowDimensions[$pRow])) {
- if (!$create) {
- return null;
- }
- $this->rowDimensions[$pRow] = new RowDimension($pRow);
-
- $this->cachedHighestRow = max($this->cachedHighestRow, $pRow);
- }
-
- return $this->rowDimensions[$pRow];
- }
-
- /**
- * Get column dimension at a specific column.
- *
- * @param string $pColumn String index of the column eg: 'A'
- * @param bool $create
- *
- * @return ColumnDimension
- */
- public function getColumnDimension($pColumn, $create = true)
- {
- // Uppercase coordinate
- $pColumn = strtoupper($pColumn);
-
- // Fetch dimensions
- if (!isset($this->columnDimensions[$pColumn])) {
- if (!$create) {
- return null;
- }
- $this->columnDimensions[$pColumn] = new ColumnDimension($pColumn);
-
- if (Coordinate::columnIndexFromString($this->cachedHighestColumn) < Coordinate::columnIndexFromString($pColumn)) {
- $this->cachedHighestColumn = $pColumn;
- }
- }
-
- return $this->columnDimensions[$pColumn];
- }
-
- /**
- * Get column dimension at a specific column by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- *
- * @return ColumnDimension
- */
- public function getColumnDimensionByColumn($columnIndex)
- {
- return $this->getColumnDimension(Coordinate::stringFromColumnIndex($columnIndex));
- }
-
- /**
- * Get styles.
- *
- * @return Style[]
- */
- public function getStyles()
- {
- return $this->styles;
- }
-
- /**
- * Get style for cell.
- *
- * @param string $pCellCoordinate Cell coordinate (or range) to get style for, eg: 'A1'
- *
- * @return Style
- */
- public function getStyle($pCellCoordinate)
- {
- // set this sheet as active
- $this->parent->setActiveSheetIndex($this->parent->getIndex($this));
-
- // set cell coordinate as active
- $this->setSelectedCells($pCellCoordinate);
-
- return $this->parent->getCellXfSupervisor();
- }
-
- /**
- * Get conditional styles for a cell.
- *
- * @param string $pCoordinate eg: 'A1'
- *
- * @return Conditional[]
- */
- public function getConditionalStyles($pCoordinate)
- {
- $pCoordinate = strtoupper($pCoordinate);
- if (!isset($this->conditionalStylesCollection[$pCoordinate])) {
- $this->conditionalStylesCollection[$pCoordinate] = [];
- }
-
- return $this->conditionalStylesCollection[$pCoordinate];
- }
-
- /**
- * Do conditional styles exist for this cell?
- *
- * @param string $pCoordinate eg: 'A1'
- *
- * @return bool
- */
- public function conditionalStylesExists($pCoordinate)
- {
- return isset($this->conditionalStylesCollection[strtoupper($pCoordinate)]);
- }
-
- /**
- * Removes conditional styles for a cell.
- *
- * @param string $pCoordinate eg: 'A1'
- *
- * @return $this
- */
- public function removeConditionalStyles($pCoordinate)
- {
- unset($this->conditionalStylesCollection[strtoupper($pCoordinate)]);
-
- return $this;
- }
-
- /**
- * Get collection of conditional styles.
- *
- * @return array
- */
- public function getConditionalStylesCollection()
- {
- return $this->conditionalStylesCollection;
- }
-
- /**
- * Set conditional styles.
- *
- * @param string $pCoordinate eg: 'A1'
- * @param $pValue Conditional[]
- *
- * @return $this
- */
- public function setConditionalStyles($pCoordinate, $pValue)
- {
- $this->conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue;
-
- return $this;
- }
-
- /**
- * Get style for cell by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the cell
- * @param int $row1 Numeric row coordinate of the cell
- * @param null|int $columnIndex2 Numeric column coordinate of the range cell
- * @param null|int $row2 Numeric row coordinate of the range cell
- *
- * @return Style
- */
- public function getStyleByColumnAndRow($columnIndex1, $row1, $columnIndex2 = null, $row2 = null)
- {
- if ($columnIndex2 !== null && $row2 !== null) {
- $cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
-
- return $this->getStyle($cellRange);
- }
-
- return $this->getStyle(Coordinate::stringFromColumnIndex($columnIndex1) . $row1);
- }
-
- /**
- * Duplicate cell style to a range of cells.
- *
- * Please note that this will overwrite existing cell styles for cells in range!
- *
- * @param Style $pCellStyle Cell style to duplicate
- * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
- *
- * @return $this
- */
- public function duplicateStyle(Style $pCellStyle, $pRange)
- {
- // Add the style to the workbook if necessary
- $workbook = $this->parent;
- if ($existingStyle = $this->parent->getCellXfByHashCode($pCellStyle->getHashCode())) {
- // there is already such cell Xf in our collection
- $xfIndex = $existingStyle->getIndex();
- } else {
- // we don't have such a cell Xf, need to add
- $workbook->addCellXf($pCellStyle);
- $xfIndex = $pCellStyle->getIndex();
- }
-
- // Calculate range outer borders
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($pRange . ':' . $pRange);
-
- // Make sure we can loop upwards on rows and columns
- if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
- $tmp = $rangeStart;
- $rangeStart = $rangeEnd;
- $rangeEnd = $tmp;
- }
-
- // Loop through cells and apply styles
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $this->getCell(Coordinate::stringFromColumnIndex($col) . $row)->setXfIndex($xfIndex);
- }
- }
-
- return $this;
- }
-
- /**
- * Duplicate conditional style to a range of cells.
- *
- * Please note that this will overwrite existing cell styles for cells in range!
- *
- * @param Conditional[] $pCellStyle Cell style to duplicate
- * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
- *
- * @return $this
- */
- public function duplicateConditionalStyle(array $pCellStyle, $pRange = '')
- {
- foreach ($pCellStyle as $cellStyle) {
- if (!($cellStyle instanceof Conditional)) {
- throw new Exception('Style is not a conditional style');
- }
- }
-
- // Calculate range outer borders
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($pRange . ':' . $pRange);
-
- // Make sure we can loop upwards on rows and columns
- if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
- $tmp = $rangeStart;
- $rangeStart = $rangeEnd;
- $rangeEnd = $tmp;
- }
-
- // Loop through cells and apply styles
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $this->setConditionalStyles(Coordinate::stringFromColumnIndex($col) . $row, $pCellStyle);
- }
- }
-
- return $this;
- }
-
- /**
- * Set break on a cell.
- *
- * @param string $pCoordinate Cell coordinate (e.g. A1)
- * @param int $pBreak Break type (type of Worksheet::BREAK_*)
- *
- * @return $this
- */
- public function setBreak($pCoordinate, $pBreak)
- {
- // Uppercase coordinate
- $pCoordinate = strtoupper($pCoordinate);
-
- if ($pCoordinate != '') {
- if ($pBreak == self::BREAK_NONE) {
- if (isset($this->breaks[$pCoordinate])) {
- unset($this->breaks[$pCoordinate]);
- }
- } else {
- $this->breaks[$pCoordinate] = $pBreak;
- }
- } else {
- throw new Exception('No cell coordinate specified.');
- }
-
- return $this;
- }
-
- /**
- * Set break on a cell by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- * @param int $break Break type (type of Worksheet::BREAK_*)
- *
- * @return $this
- */
- public function setBreakByColumnAndRow($columnIndex, $row, $break)
- {
- return $this->setBreak(Coordinate::stringFromColumnIndex($columnIndex) . $row, $break);
- }
-
- /**
- * Get breaks.
- *
- * @return array[]
- */
- public function getBreaks()
- {
- return $this->breaks;
- }
-
- /**
- * Set merge on a cell range.
- *
- * @param string $pRange Cell range (e.g. A1:E1)
- *
- * @return $this
- */
- public function mergeCells($pRange)
- {
- // Uppercase coordinate
- $pRange = strtoupper($pRange);
-
- if (strpos($pRange, ':') !== false) {
- $this->mergeCells[$pRange] = $pRange;
-
- // make sure cells are created
-
- // get the cells in the range
- $aReferences = Coordinate::extractAllCellReferencesInRange($pRange);
-
- // create upper left cell if it does not already exist
- $upperLeft = $aReferences[0];
- if (!$this->cellExists($upperLeft)) {
- $this->getCell($upperLeft)->setValueExplicit(null, DataType::TYPE_NULL);
- }
-
- // Blank out the rest of the cells in the range (if they exist)
- $count = count($aReferences);
- for ($i = 1; $i < $count; ++$i) {
- if ($this->cellExists($aReferences[$i])) {
- $this->getCell($aReferences[$i])->setValueExplicit(null, DataType::TYPE_NULL);
- }
- }
- } else {
- throw new Exception('Merge must be set on a range of cells.');
- }
-
- return $this;
- }
-
- /**
- * Set merge on a cell range by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the first cell
- * @param int $row1 Numeric row coordinate of the first cell
- * @param int $columnIndex2 Numeric column coordinate of the last cell
- * @param int $row2 Numeric row coordinate of the last cell
- *
- * @return $this
- */
- public function mergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
- {
- $cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
-
- return $this->mergeCells($cellRange);
- }
-
- /**
- * Remove merge on a cell range.
- *
- * @param string $pRange Cell range (e.g. A1:E1)
- *
- * @return $this
- */
- public function unmergeCells($pRange)
- {
- // Uppercase coordinate
- $pRange = strtoupper($pRange);
-
- if (strpos($pRange, ':') !== false) {
- if (isset($this->mergeCells[$pRange])) {
- unset($this->mergeCells[$pRange]);
- } else {
- throw new Exception('Cell range ' . $pRange . ' not known as merged.');
- }
- } else {
- throw new Exception('Merge can only be removed from a range of cells.');
- }
-
- return $this;
- }
-
- /**
- * Remove merge on a cell range by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the first cell
- * @param int $row1 Numeric row coordinate of the first cell
- * @param int $columnIndex2 Numeric column coordinate of the last cell
- * @param int $row2 Numeric row coordinate of the last cell
- *
- * @return $this
- */
- public function unmergeCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
- {
- $cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
-
- return $this->unmergeCells($cellRange);
- }
-
- /**
- * Get merge cells array.
- *
- * @return string[]
- */
- public function getMergeCells()
- {
- return $this->mergeCells;
- }
-
- /**
- * Set merge cells array for the entire sheet. Use instead mergeCells() to merge
- * a single cell range.
- *
- * @param string[] $pValue
- *
- * @return $this
- */
- public function setMergeCells(array $pValue)
- {
- $this->mergeCells = $pValue;
-
- return $this;
- }
-
- /**
- * Set protection on a cell range.
- *
- * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
- * @param string $pPassword Password to unlock the protection
- * @param bool $pAlreadyHashed If the password has already been hashed, set this to true
- *
- * @return $this
- */
- public function protectCells($pRange, $pPassword, $pAlreadyHashed = false)
- {
- // Uppercase coordinate
- $pRange = strtoupper($pRange);
-
- if (!$pAlreadyHashed) {
- $pPassword = Shared\PasswordHasher::hashPassword($pPassword);
- }
- $this->protectedCells[$pRange] = $pPassword;
-
- return $this;
- }
-
- /**
- * Set protection on a cell range by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the first cell
- * @param int $row1 Numeric row coordinate of the first cell
- * @param int $columnIndex2 Numeric column coordinate of the last cell
- * @param int $row2 Numeric row coordinate of the last cell
- * @param string $password Password to unlock the protection
- * @param bool $alreadyHashed If the password has already been hashed, set this to true
- *
- * @return $this
- */
- public function protectCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2, $password, $alreadyHashed = false)
- {
- $cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
-
- return $this->protectCells($cellRange, $password, $alreadyHashed);
- }
-
- /**
- * Remove protection on a cell range.
- *
- * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1)
- *
- * @return $this
- */
- public function unprotectCells($pRange)
- {
- // Uppercase coordinate
- $pRange = strtoupper($pRange);
-
- if (isset($this->protectedCells[$pRange])) {
- unset($this->protectedCells[$pRange]);
- } else {
- throw new Exception('Cell range ' . $pRange . ' not known as protected.');
- }
-
- return $this;
- }
-
- /**
- * Remove protection on a cell range by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the first cell
- * @param int $row1 Numeric row coordinate of the first cell
- * @param int $columnIndex2 Numeric column coordinate of the last cell
- * @param int $row2 Numeric row coordinate of the last cell
- *
- * @return $this
- */
- public function unprotectCellsByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
- {
- $cellRange = Coordinate::stringFromColumnIndex($columnIndex1) . $row1 . ':' . Coordinate::stringFromColumnIndex($columnIndex2) . $row2;
-
- return $this->unprotectCells($cellRange);
- }
-
- /**
- * Get protected cells.
- *
- * @return array[]
- */
- public function getProtectedCells()
- {
- return $this->protectedCells;
- }
-
- /**
- * Get Autofilter.
- *
- * @return AutoFilter
- */
- public function getAutoFilter()
- {
- return $this->autoFilter;
- }
-
- /**
- * Set AutoFilter.
- *
- * @param AutoFilter|string $pValue
- * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility
- *
- * @return $this
- */
- public function setAutoFilter($pValue)
- {
- if (is_string($pValue)) {
- $this->autoFilter->setRange($pValue);
- } elseif (is_object($pValue) && ($pValue instanceof AutoFilter)) {
- $this->autoFilter = $pValue;
- }
-
- return $this;
- }
-
- /**
- * Set Autofilter Range by using numeric cell coordinates.
- *
- * @param int $columnIndex1 Numeric column coordinate of the first cell
- * @param int $row1 Numeric row coordinate of the first cell
- * @param int $columnIndex2 Numeric column coordinate of the second cell
- * @param int $row2 Numeric row coordinate of the second cell
- *
- * @return $this
- */
- public function setAutoFilterByColumnAndRow($columnIndex1, $row1, $columnIndex2, $row2)
- {
- return $this->setAutoFilter(
- Coordinate::stringFromColumnIndex($columnIndex1) . $row1
- . ':' .
- Coordinate::stringFromColumnIndex($columnIndex2) . $row2
- );
- }
-
- /**
- * Remove autofilter.
- *
- * @return $this
- */
- public function removeAutoFilter()
- {
- $this->autoFilter->setRange(null);
-
- return $this;
- }
-
- /**
- * Get Freeze Pane.
- *
- * @return string
- */
- public function getFreezePane()
- {
- return $this->freezePane;
- }
-
- /**
- * Freeze Pane.
- *
- * Examples:
- *
- * - A2 will freeze the rows above cell A2 (i.e row 1)
- * - B1 will freeze the columns to the left of cell B1 (i.e column A)
- * - B2 will freeze the rows above and to the left of cell B2 (i.e row 1 and column A)
- *
- * @param null|string $cell Position of the split
- * @param null|string $topLeftCell default position of the right bottom pane
- *
- * @return $this
- */
- public function freezePane($cell, $topLeftCell = null)
- {
- if (is_string($cell) && Coordinate::coordinateIsRange($cell)) {
- throw new Exception('Freeze pane can not be set on a range of cells.');
- }
-
- if ($cell !== null && $topLeftCell === null) {
- $coordinate = Coordinate::coordinateFromString($cell);
- $topLeftCell = $coordinate[0] . $coordinate[1];
- }
-
- $this->freezePane = $cell;
- $this->topLeftCell = $topLeftCell;
-
- return $this;
- }
-
- /**
- * Freeze Pane by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- *
- * @return $this
- */
- public function freezePaneByColumnAndRow($columnIndex, $row)
- {
- return $this->freezePane(Coordinate::stringFromColumnIndex($columnIndex) . $row);
- }
-
- /**
- * Unfreeze Pane.
- *
- * @return $this
- */
- public function unfreezePane()
- {
- return $this->freezePane(null);
- }
-
- /**
- * Get the default position of the right bottom pane.
- *
- * @return int
- */
- public function getTopLeftCell()
- {
- return $this->topLeftCell;
- }
-
- /**
- * Insert a new row, updating all possible related data.
- *
- * @param int $pBefore Insert before this one
- * @param int $pNumRows Number of rows to insert
- *
- * @return $this
- */
- public function insertNewRowBefore($pBefore, $pNumRows = 1)
- {
- if ($pBefore >= 1) {
- $objReferenceHelper = ReferenceHelper::getInstance();
- $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this);
- } else {
- throw new Exception('Rows can only be inserted before at least row 1.');
- }
-
- return $this;
- }
-
- /**
- * Insert a new column, updating all possible related data.
- *
- * @param string $pBefore Insert before this one, eg: 'A'
- * @param int $pNumCols Number of columns to insert
- *
- * @return $this
- */
- public function insertNewColumnBefore($pBefore, $pNumCols = 1)
- {
- if (!is_numeric($pBefore)) {
- $objReferenceHelper = ReferenceHelper::getInstance();
- $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this);
- } else {
- throw new Exception('Column references should not be numeric.');
- }
-
- return $this;
- }
-
- /**
- * Insert a new column, updating all possible related data.
- *
- * @param int $beforeColumnIndex Insert before this one (numeric column coordinate of the cell)
- * @param int $pNumCols Number of columns to insert
- *
- * @return $this
- */
- public function insertNewColumnBeforeByIndex($beforeColumnIndex, $pNumCols = 1)
- {
- if ($beforeColumnIndex >= 1) {
- return $this->insertNewColumnBefore(Coordinate::stringFromColumnIndex($beforeColumnIndex), $pNumCols);
- }
-
- throw new Exception('Columns can only be inserted before at least column A (1).');
- }
-
- /**
- * Delete a row, updating all possible related data.
- *
- * @param int $pRow Remove starting with this one
- * @param int $pNumRows Number of rows to remove
- *
- * @return $this
- */
- public function removeRow($pRow, $pNumRows = 1)
- {
- if ($pRow < 1) {
- throw new Exception('Rows to be deleted should at least start from row 1.');
- }
-
- $highestRow = $this->getHighestDataRow();
- $removedRowsCounter = 0;
-
- for ($r = 0; $r < $pNumRows; ++$r) {
- if ($pRow + $r <= $highestRow) {
- $this->getCellCollection()->removeRow($pRow + $r);
- ++$removedRowsCounter;
- }
- }
-
- $objReferenceHelper = ReferenceHelper::getInstance();
- $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this);
- for ($r = 0; $r < $removedRowsCounter; ++$r) {
- $this->getCellCollection()->removeRow($highestRow);
- --$highestRow;
- }
-
- return $this;
- }
-
- /**
- * Remove a column, updating all possible related data.
- *
- * @param string $pColumn Remove starting with this one, eg: 'A'
- * @param int $pNumCols Number of columns to remove
- *
- * @return $this
- */
- public function removeColumn($pColumn, $pNumCols = 1)
- {
- if (is_numeric($pColumn)) {
- throw new Exception('Column references should not be numeric.');
- }
-
- $highestColumn = $this->getHighestDataColumn();
- $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
- $pColumnIndex = Coordinate::columnIndexFromString($pColumn);
-
- if ($pColumnIndex > $highestColumnIndex) {
- return $this;
- }
-
- $pColumn = Coordinate::stringFromColumnIndex($pColumnIndex + $pNumCols);
- $objReferenceHelper = ReferenceHelper::getInstance();
- $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);
-
- $maxPossibleColumnsToBeRemoved = $highestColumnIndex - $pColumnIndex + 1;
-
- for ($c = 0, $n = min($maxPossibleColumnsToBeRemoved, $pNumCols); $c < $n; ++$c) {
- $this->getCellCollection()->removeColumn($highestColumn);
- $highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 1);
- }
-
- $this->garbageCollect();
-
- return $this;
- }
-
- /**
- * Remove a column, updating all possible related data.
- *
- * @param int $columnIndex Remove starting with this one (numeric column coordinate of the cell)
- * @param int $numColumns Number of columns to remove
- *
- * @return $this
- */
- public function removeColumnByIndex($columnIndex, $numColumns = 1)
- {
- if ($columnIndex >= 1) {
- return $this->removeColumn(Coordinate::stringFromColumnIndex($columnIndex), $numColumns);
- }
-
- throw new Exception('Columns to be deleted should at least start from column A (1)');
- }
-
- /**
- * Show gridlines?
- *
- * @return bool
- */
- public function getShowGridlines()
- {
- return $this->showGridlines;
- }
-
- /**
- * Set show gridlines.
- *
- * @param bool $pValue Show gridlines (true/false)
- *
- * @return $this
- */
- public function setShowGridlines($pValue)
- {
- $this->showGridlines = $pValue;
-
- return $this;
- }
-
- /**
- * Print gridlines?
- *
- * @return bool
- */
- public function getPrintGridlines()
- {
- return $this->printGridlines;
- }
-
- /**
- * Set print gridlines.
- *
- * @param bool $pValue Print gridlines (true/false)
- *
- * @return $this
- */
- public function setPrintGridlines($pValue)
- {
- $this->printGridlines = $pValue;
-
- return $this;
- }
-
- /**
- * Show row and column headers?
- *
- * @return bool
- */
- public function getShowRowColHeaders()
- {
- return $this->showRowColHeaders;
- }
-
- /**
- * Set show row and column headers.
- *
- * @param bool $pValue Show row and column headers (true/false)
- *
- * @return $this
- */
- public function setShowRowColHeaders($pValue)
- {
- $this->showRowColHeaders = $pValue;
-
- return $this;
- }
-
- /**
- * Show summary below? (Row/Column outlining).
- *
- * @return bool
- */
- public function getShowSummaryBelow()
- {
- return $this->showSummaryBelow;
- }
-
- /**
- * Set show summary below.
- *
- * @param bool $pValue Show summary below (true/false)
- *
- * @return $this
- */
- public function setShowSummaryBelow($pValue)
- {
- $this->showSummaryBelow = $pValue;
-
- return $this;
- }
-
- /**
- * Show summary right? (Row/Column outlining).
- *
- * @return bool
- */
- public function getShowSummaryRight()
- {
- return $this->showSummaryRight;
- }
-
- /**
- * Set show summary right.
- *
- * @param bool $pValue Show summary right (true/false)
- *
- * @return $this
- */
- public function setShowSummaryRight($pValue)
- {
- $this->showSummaryRight = $pValue;
-
- return $this;
- }
-
- /**
- * Get comments.
- *
- * @return Comment[]
- */
- public function getComments()
- {
- return $this->comments;
- }
-
- /**
- * Set comments array for the entire sheet.
- *
- * @param Comment[] $pValue
- *
- * @return $this
- */
- public function setComments(array $pValue)
- {
- $this->comments = $pValue;
-
- return $this;
- }
-
- /**
- * Get comment for cell.
- *
- * @param string $pCellCoordinate Cell coordinate to get comment for, eg: 'A1'
- *
- * @return Comment
- */
- public function getComment($pCellCoordinate)
- {
- // Uppercase coordinate
- $pCellCoordinate = strtoupper($pCellCoordinate);
-
- if (Coordinate::coordinateIsRange($pCellCoordinate)) {
- throw new Exception('Cell coordinate string can not be a range of cells.');
- } elseif (strpos($pCellCoordinate, '$') !== false) {
- throw new Exception('Cell coordinate string must not be absolute.');
- } elseif ($pCellCoordinate == '') {
- throw new Exception('Cell coordinate can not be zero-length string.');
- }
-
- // Check if we already have a comment for this cell.
- if (isset($this->comments[$pCellCoordinate])) {
- return $this->comments[$pCellCoordinate];
- }
-
- // If not, create a new comment.
- $newComment = new Comment();
- $this->comments[$pCellCoordinate] = $newComment;
-
- return $newComment;
- }
-
- /**
- * Get comment for cell by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- *
- * @return Comment
- */
- public function getCommentByColumnAndRow($columnIndex, $row)
- {
- return $this->getComment(Coordinate::stringFromColumnIndex($columnIndex) . $row);
- }
-
- /**
- * Get active cell.
- *
- * @return string Example: 'A1'
- */
- public function getActiveCell()
- {
- return $this->activeCell;
- }
-
- /**
- * Get selected cells.
- *
- * @return string
- */
- public function getSelectedCells()
- {
- return $this->selectedCells;
- }
-
- /**
- * Selected cell.
- *
- * @param string $pCoordinate Cell (i.e. A1)
- *
- * @return $this
- */
- public function setSelectedCell($pCoordinate)
- {
- return $this->setSelectedCells($pCoordinate);
- }
-
- /**
- * Select a range of cells.
- *
- * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6'
- *
- * @return $this
- */
- public function setSelectedCells($pCoordinate)
- {
- // Uppercase coordinate
- $pCoordinate = strtoupper($pCoordinate);
-
- // Convert 'A' to 'A:A'
- $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate);
-
- // Convert '1' to '1:1'
- $pCoordinate = preg_replace('/^(\d+)$/', '${1}:${1}', $pCoordinate);
-
- // Convert 'A:C' to 'A1:C1048576'
- $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate);
-
- // Convert '1:3' to 'A1:XFD3'
- $pCoordinate = preg_replace('/^(\d+):(\d+)$/', 'A${1}:XFD${2}', $pCoordinate);
-
- if (Coordinate::coordinateIsRange($pCoordinate)) {
- [$first] = Coordinate::splitRange($pCoordinate);
- $this->activeCell = $first[0];
- } else {
- $this->activeCell = $pCoordinate;
- }
- $this->selectedCells = $pCoordinate;
-
- return $this;
- }
-
- /**
- * Selected cell by using numeric cell coordinates.
- *
- * @param int $columnIndex Numeric column coordinate of the cell
- * @param int $row Numeric row coordinate of the cell
- *
- * @return $this
- */
- public function setSelectedCellByColumnAndRow($columnIndex, $row)
- {
- return $this->setSelectedCells(Coordinate::stringFromColumnIndex($columnIndex) . $row);
- }
-
- /**
- * Get right-to-left.
- *
- * @return bool
- */
- public function getRightToLeft()
- {
- return $this->rightToLeft;
- }
-
- /**
- * Set right-to-left.
- *
- * @param bool $value Right-to-left true/false
- *
- * @return $this
- */
- public function setRightToLeft($value)
- {
- $this->rightToLeft = $value;
-
- return $this;
- }
-
- /**
- * Fill worksheet from values in array.
- *
- * @param array $source Source array
- * @param mixed $nullValue Value in source array that stands for blank cell
- * @param string $startCell Insert array starting from this cell address as the top left coordinate
- * @param bool $strictNullComparison Apply strict comparison when testing for null values in the array
- *
- * @return $this
- */
- public function fromArray(array $source, $nullValue = null, $startCell = 'A1', $strictNullComparison = false)
- {
- // Convert a 1-D array to 2-D (for ease of looping)
- if (!is_array(end($source))) {
- $source = [$source];
- }
-
- // start coordinate
- [$startColumn, $startRow] = Coordinate::coordinateFromString($startCell);
-
- // Loop through $source
- foreach ($source as $rowData) {
- $currentColumn = $startColumn;
- foreach ($rowData as $cellValue) {
- if ($strictNullComparison) {
- if ($cellValue !== $nullValue) {
- // Set cell value
- $this->getCell($currentColumn . $startRow)->setValue($cellValue);
- }
- } else {
- if ($cellValue != $nullValue) {
- // Set cell value
- $this->getCell($currentColumn . $startRow)->setValue($cellValue);
- }
- }
- ++$currentColumn;
- }
- ++$startRow;
- }
-
- return $this;
- }
-
- /**
- * Create array from a range of cells.
- *
- * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1")
- * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
- * @param bool $calculateFormulas Should formulas be calculated?
- * @param bool $formatData Should formatting be applied to cell values?
- * @param bool $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
- * True - Return rows and columns indexed by their actual row and column IDs
- *
- * @return array
- */
- public function rangeToArray($pRange, $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
- {
- // Returnvalue
- $returnValue = [];
- // Identify the range that we need to extract from the worksheet
- [$rangeStart, $rangeEnd] = Coordinate::rangeBoundaries($pRange);
- $minCol = Coordinate::stringFromColumnIndex($rangeStart[0]);
- $minRow = $rangeStart[1];
- $maxCol = Coordinate::stringFromColumnIndex($rangeEnd[0]);
- $maxRow = $rangeEnd[1];
-
- ++$maxCol;
- // Loop through rows
- $r = -1;
- for ($row = $minRow; $row <= $maxRow; ++$row) {
- $rRef = $returnCellRef ? $row : ++$r;
- $c = -1;
- // Loop through columns in the current row
- for ($col = $minCol; $col != $maxCol; ++$col) {
- $cRef = $returnCellRef ? $col : ++$c;
- // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen
- // so we test and retrieve directly against cellCollection
- if ($this->cellCollection->has($col . $row)) {
- // Cell exists
- $cell = $this->cellCollection->get($col . $row);
- if ($cell->getValue() !== null) {
- if ($cell->getValue() instanceof RichText) {
- $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();
- } else {
- if ($calculateFormulas) {
- $returnValue[$rRef][$cRef] = $cell->getCalculatedValue();
- } else {
- $returnValue[$rRef][$cRef] = $cell->getValue();
- }
- }
-
- if ($formatData) {
- $style = $this->parent->getCellXfByIndex($cell->getXfIndex());
- $returnValue[$rRef][$cRef] = NumberFormat::toFormattedString(
- $returnValue[$rRef][$cRef],
- ($style && $style->getNumberFormat()) ? $style->getNumberFormat()->getFormatCode() : NumberFormat::FORMAT_GENERAL
- );
- }
- } else {
- // Cell holds a NULL
- $returnValue[$rRef][$cRef] = $nullValue;
- }
- } else {
- // Cell doesn't exist
- $returnValue[$rRef][$cRef] = $nullValue;
- }
- }
- }
-
- // Return
- return $returnValue;
- }
-
- /**
- * Create array from a range of cells.
- *
- * @param string $pNamedRange Name of the Named Range
- * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
- * @param bool $calculateFormulas Should formulas be calculated?
- * @param bool $formatData Should formatting be applied to cell values?
- * @param bool $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
- * True - Return rows and columns indexed by their actual row and column IDs
- *
- * @return array
- */
- public function namedRangeToArray($pNamedRange, $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
- {
- $namedRange = DefinedName::resolveName($pNamedRange, $this);
- if ($namedRange !== null) {
- $pWorkSheet = $namedRange->getWorksheet();
- $pCellRange = $namedRange->getValue();
-
- return $pWorkSheet->rangeToArray($pCellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
- }
-
- throw new Exception('Named Range ' . $pNamedRange . ' does not exist.');
- }
-
- /**
- * Create array from worksheet.
- *
- * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
- * @param bool $calculateFormulas Should formulas be calculated?
- * @param bool $formatData Should formatting be applied to cell values?
- * @param bool $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero
- * True - Return rows and columns indexed by their actual row and column IDs
- *
- * @return array
- */
- public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
- {
- // Garbage collect...
- $this->garbageCollect();
-
- // Identify the range that we need to extract from the worksheet
- $maxCol = $this->getHighestColumn();
- $maxRow = $this->getHighestRow();
-
- // Return
- return $this->rangeToArray('A1:' . $maxCol . $maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
- }
-
- /**
- * Get row iterator.
- *
- * @param int $startRow The row number at which to start iterating
- * @param int $endRow The row number at which to stop iterating
- *
- * @return RowIterator
- */
- public function getRowIterator($startRow = 1, $endRow = null)
- {
- return new RowIterator($this, $startRow, $endRow);
- }
-
- /**
- * Get column iterator.
- *
- * @param string $startColumn The column address at which to start iterating
- * @param string $endColumn The column address at which to stop iterating
- *
- * @return ColumnIterator
- */
- public function getColumnIterator($startColumn = 'A', $endColumn = null)
- {
- return new ColumnIterator($this, $startColumn, $endColumn);
- }
-
- /**
- * Run PhpSpreadsheet garbage collector.
- *
- * @return $this
- */
- public function garbageCollect()
- {
- // Flush cache
- $this->cellCollection->get('A1');
-
- // Lookup highest column and highest row if cells are cleaned
- $colRow = $this->cellCollection->getHighestRowAndColumn();
- $highestRow = $colRow['row'];
- $highestColumn = Coordinate::columnIndexFromString($colRow['column']);
-
- // Loop through column dimensions
- foreach ($this->columnDimensions as $dimension) {
- $highestColumn = max($highestColumn, Coordinate::columnIndexFromString($dimension->getColumnIndex()));
- }
-
- // Loop through row dimensions
- foreach ($this->rowDimensions as $dimension) {
- $highestRow = max($highestRow, $dimension->getRowIndex());
- }
-
- // Cache values
- if ($highestColumn < 1) {
- $this->cachedHighestColumn = 'A';
- } else {
- $this->cachedHighestColumn = Coordinate::stringFromColumnIndex($highestColumn);
- }
- $this->cachedHighestRow = $highestRow;
-
- // Return
- return $this;
- }
-
- /**
- * Get hash code.
- *
- * @return string Hash code
- */
- public function getHashCode()
- {
- if ($this->dirty) {
- $this->hash = md5($this->title . $this->autoFilter . ($this->protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__);
- $this->dirty = false;
- }
-
- return $this->hash;
- }
-
- /**
- * Extract worksheet title from range.
- *
- * Example: extractSheetTitle("testSheet!A1") ==> 'A1'
- * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> ['testSheet 1', 'A1'];
- *
- * @param string $pRange Range to extract title from
- * @param bool $returnRange Return range? (see example)
- *
- * @return mixed
- */
- public static function extractSheetTitle($pRange, $returnRange = false)
- {
- // Sheet title included?
- if (($sep = strrpos($pRange, '!')) === false) {
- return $returnRange ? ['', $pRange] : '';
- }
-
- if ($returnRange) {
- return [substr($pRange, 0, $sep), substr($pRange, $sep + 1)];
- }
-
- return substr($pRange, $sep + 1);
- }
-
- /**
- * Get hyperlink.
- *
- * @param string $pCellCoordinate Cell coordinate to get hyperlink for, eg: 'A1'
- *
- * @return Hyperlink
- */
- public function getHyperlink($pCellCoordinate)
- {
- // return hyperlink if we already have one
- if (isset($this->hyperlinkCollection[$pCellCoordinate])) {
- return $this->hyperlinkCollection[$pCellCoordinate];
- }
-
- // else create hyperlink
- $this->hyperlinkCollection[$pCellCoordinate] = new Hyperlink();
-
- return $this->hyperlinkCollection[$pCellCoordinate];
- }
-
- /**
- * Set hyperlink.
- *
- * @param string $pCellCoordinate Cell coordinate to insert hyperlink, eg: 'A1'
- *
- * @return $this
- */
- public function setHyperlink($pCellCoordinate, ?Hyperlink $pHyperlink = null)
- {
- if ($pHyperlink === null) {
- unset($this->hyperlinkCollection[$pCellCoordinate]);
- } else {
- $this->hyperlinkCollection[$pCellCoordinate] = $pHyperlink;
- }
-
- return $this;
- }
-
- /**
- * Hyperlink at a specific coordinate exists?
- *
- * @param string $pCoordinate eg: 'A1'
- *
- * @return bool
- */
- public function hyperlinkExists($pCoordinate)
- {
- return isset($this->hyperlinkCollection[$pCoordinate]);
- }
-
- /**
- * Get collection of hyperlinks.
- *
- * @return Hyperlink[]
- */
- public function getHyperlinkCollection()
- {
- return $this->hyperlinkCollection;
- }
-
- /**
- * Get data validation.
- *
- * @param string $pCellCoordinate Cell coordinate to get data validation for, eg: 'A1'
- *
- * @return DataValidation
- */
- public function getDataValidation($pCellCoordinate)
- {
- // return data validation if we already have one
- if (isset($this->dataValidationCollection[$pCellCoordinate])) {
- return $this->dataValidationCollection[$pCellCoordinate];
- }
-
- // else create data validation
- $this->dataValidationCollection[$pCellCoordinate] = new DataValidation();
-
- return $this->dataValidationCollection[$pCellCoordinate];
- }
-
- /**
- * Set data validation.
- *
- * @param string $pCellCoordinate Cell coordinate to insert data validation, eg: 'A1'
- *
- * @return $this
- */
- public function setDataValidation($pCellCoordinate, ?DataValidation $pDataValidation = null)
- {
- if ($pDataValidation === null) {
- unset($this->dataValidationCollection[$pCellCoordinate]);
- } else {
- $this->dataValidationCollection[$pCellCoordinate] = $pDataValidation;
- }
-
- return $this;
- }
-
- /**
- * Data validation at a specific coordinate exists?
- *
- * @param string $pCoordinate eg: 'A1'
- *
- * @return bool
- */
- public function dataValidationExists($pCoordinate)
- {
- return isset($this->dataValidationCollection[$pCoordinate]);
- }
-
- /**
- * Get collection of data validations.
- *
- * @return DataValidation[]
- */
- public function getDataValidationCollection()
- {
- return $this->dataValidationCollection;
- }
-
- /**
- * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet.
- *
- * @param string $range
- *
- * @return string Adjusted range value
- */
- public function shrinkRangeToFit($range)
- {
- $maxCol = $this->getHighestColumn();
- $maxRow = $this->getHighestRow();
- $maxCol = Coordinate::columnIndexFromString($maxCol);
-
- $rangeBlocks = explode(' ', $range);
- foreach ($rangeBlocks as &$rangeSet) {
- $rangeBoundaries = Coordinate::getRangeBoundaries($rangeSet);
-
- if (Coordinate::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) {
- $rangeBoundaries[0][0] = Coordinate::stringFromColumnIndex($maxCol);
- }
- if ($rangeBoundaries[0][1] > $maxRow) {
- $rangeBoundaries[0][1] = $maxRow;
- }
- if (Coordinate::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) {
- $rangeBoundaries[1][0] = Coordinate::stringFromColumnIndex($maxCol);
- }
- if ($rangeBoundaries[1][1] > $maxRow) {
- $rangeBoundaries[1][1] = $maxRow;
- }
- $rangeSet = $rangeBoundaries[0][0] . $rangeBoundaries[0][1] . ':' . $rangeBoundaries[1][0] . $rangeBoundaries[1][1];
- }
- unset($rangeSet);
-
- return implode(' ', $rangeBlocks);
- }
-
- /**
- * Get tab color.
- *
- * @return Color
- */
- public function getTabColor()
- {
- if ($this->tabColor === null) {
- $this->tabColor = new Color();
- }
-
- return $this->tabColor;
- }
-
- /**
- * Reset tab color.
- *
- * @return $this
- */
- public function resetTabColor()
- {
- $this->tabColor = null;
- $this->tabColor = null;
-
- return $this;
- }
-
- /**
- * Tab color set?
- *
- * @return bool
- */
- public function isTabColorSet()
- {
- return $this->tabColor !== null;
- }
-
- /**
- * Copy worksheet (!= clone!).
- *
- * @return static
- */
- public function copy()
- {
- return clone $this;
- }
-
- /**
- * Implement PHP __clone to create a deep clone, not just a shallow copy.
- */
- public function __clone()
- {
- foreach ($this as $key => $val) {
- if ($key == 'parent') {
- continue;
- }
-
- if (is_object($val) || (is_array($val))) {
- if ($key == 'cellCollection') {
- $newCollection = $this->cellCollection->cloneCellCollection($this);
- $this->cellCollection = $newCollection;
- } elseif ($key == 'drawingCollection') {
- $currentCollection = $this->drawingCollection;
- $this->drawingCollection = new ArrayObject();
- foreach ($currentCollection as $item) {
- if (is_object($item)) {
- $newDrawing = clone $item;
- $newDrawing->setWorksheet($this);
- }
- }
- } elseif (($key == 'autoFilter') && ($this->autoFilter instanceof AutoFilter)) {
- $newAutoFilter = clone $this->autoFilter;
- $this->autoFilter = $newAutoFilter;
- $this->autoFilter->setParent($this);
- } else {
- $this->{$key} = unserialize(serialize($val));
- }
- }
- }
- }
-
- /**
- * Define the code name of the sheet.
- *
- * @param string $pValue Same rule as Title minus space not allowed (but, like Excel, change
- * silently space to underscore)
- * @param bool $validate False to skip validation of new title. WARNING: This should only be set
- * at parse time (by Readers), where titles can be assumed to be valid.
- *
- * @return $this
- */
- public function setCodeName($pValue, $validate = true)
- {
- // Is this a 'rename' or not?
- if ($this->getCodeName() == $pValue) {
- return $this;
- }
-
- if ($validate) {
- $pValue = str_replace(' ', '_', $pValue); //Excel does this automatically without flinching, we are doing the same
-
- // Syntax check
- // throw an exception if not valid
- self::checkSheetCodeName($pValue);
-
- // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_'
-
- if ($this->getParent()) {
- // Is there already such sheet name?
- if ($this->getParent()->sheetCodeNameExists($pValue)) {
- // Use name, but append with lowest possible integer
-
- if (Shared\StringHelper::countCharacters($pValue) > 29) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 29);
- }
- $i = 1;
- while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) {
- ++$i;
- if ($i == 10) {
- if (Shared\StringHelper::countCharacters($pValue) > 28) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 28);
- }
- } elseif ($i == 100) {
- if (Shared\StringHelper::countCharacters($pValue) > 27) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 27);
- }
- }
- }
-
- $pValue .= '_' . $i; // ok, we have a valid name
- }
- }
- }
-
- $this->codeName = $pValue;
-
- return $this;
- }
-
- /**
- * Return the code name of the sheet.
- *
- * @return null|string
- */
- public function getCodeName()
- {
- return $this->codeName;
- }
-
- /**
- * Sheet has a code name ?
- *
- * @return bool
- */
- public function hasCodeName()
- {
- return $this->codeName !== null;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/BaseWriter.php b/vendor/PhpSpreadsheet/Writer/BaseWriter.php
deleted file mode 100644
index afda5c4..0000000
--- a/vendor/PhpSpreadsheet/Writer/BaseWriter.php
+++ /dev/null
@@ -1,131 +0,0 @@
-includeCharts;
- }
-
- public function setIncludeCharts($pValue)
- {
- $this->includeCharts = (bool) $pValue;
-
- return $this;
- }
-
- public function getPreCalculateFormulas()
- {
- return $this->preCalculateFormulas;
- }
-
- public function setPreCalculateFormulas($pValue)
- {
- $this->preCalculateFormulas = (bool) $pValue;
-
- return $this;
- }
-
- public function getUseDiskCaching()
- {
- return $this->useDiskCaching;
- }
-
- public function setUseDiskCaching($pValue, $pDirectory = null)
- {
- $this->useDiskCaching = $pValue;
-
- if ($pDirectory !== null) {
- if (is_dir($pDirectory)) {
- $this->diskCachingDirectory = $pDirectory;
- } else {
- throw new Exception("Directory does not exist: $pDirectory");
- }
- }
-
- return $this;
- }
-
- public function getDiskCachingDirectory()
- {
- return $this->diskCachingDirectory;
- }
-
- /**
- * Open file handle.
- *
- * @param resource|string $filename
- */
- public function openFileHandle($filename): void
- {
- if (is_resource($filename)) {
- $this->fileHandle = $filename;
- $this->shouldCloseFile = false;
-
- return;
- }
-
- $fileHandle = $filename ? fopen($filename, 'wb+') : false;
- if ($fileHandle === false) {
- throw new Exception('Could not open file "' . $filename . '" for writing.');
- }
-
- $this->fileHandle = $fileHandle;
- $this->shouldCloseFile = true;
- }
-
- /**
- * Close file handle only if we opened it ourselves.
- */
- protected function maybeCloseFileHandle(): void
- {
- if ($this->shouldCloseFile) {
- if (!fclose($this->fileHandle)) {
- throw new Exception('Could not close file after writing.');
- }
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Csv.php b/vendor/PhpSpreadsheet/Writer/Csv.php
deleted file mode 100644
index 74f2863..0000000
--- a/vendor/PhpSpreadsheet/Writer/Csv.php
+++ /dev/null
@@ -1,352 +0,0 @@
-spreadsheet = $spreadsheet;
- }
-
- /**
- * Save PhpSpreadsheet to file.
- *
- * @param resource|string $pFilename
- */
- public function save($pFilename): void
- {
- // Fetch sheet
- $sheet = $this->spreadsheet->getSheet($this->sheetIndex);
-
- $saveDebugLog = Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog();
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false);
- $saveArrayReturnType = Calculation::getArrayReturnType();
- Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_VALUE);
-
- // Open file
- $this->openFileHandle($pFilename);
-
- if ($this->excelCompatibility) {
- $this->setUseBOM(true); // Enforce UTF-8 BOM Header
- $this->setIncludeSeparatorLine(true); // Set separator line
- $this->setEnclosure('"'); // Set enclosure to "
- $this->setDelimiter(';'); // Set delimiter to a semi-colon
- $this->setLineEnding("\r\n");
- }
-
- if ($this->useBOM) {
- // Write the UTF-8 BOM code if required
- fwrite($this->fileHandle, "\xEF\xBB\xBF");
- }
-
- if ($this->includeSeparatorLine) {
- // Write the separator line if required
- fwrite($this->fileHandle, 'sep=' . $this->getDelimiter() . $this->lineEnding);
- }
-
- // Identify the range that we need to extract from the worksheet
- $maxCol = $sheet->getHighestDataColumn();
- $maxRow = $sheet->getHighestDataRow();
-
- // Write rows to file
- for ($row = 1; $row <= $maxRow; ++$row) {
- // Convert the row to an array...
- $cellsArray = $sheet->rangeToArray('A' . $row . ':' . $maxCol . $row, '', $this->preCalculateFormulas);
- // ... and write to the file
- $this->writeLine($this->fileHandle, $cellsArray[0]);
- }
-
- $this->maybeCloseFileHandle();
- Calculation::setArrayReturnType($saveArrayReturnType);
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
- }
-
- /**
- * Get delimiter.
- *
- * @return string
- */
- public function getDelimiter()
- {
- return $this->delimiter;
- }
-
- /**
- * Set delimiter.
- *
- * @param string $pValue Delimiter, defaults to ','
- *
- * @return $this
- */
- public function setDelimiter($pValue)
- {
- $this->delimiter = $pValue;
-
- return $this;
- }
-
- /**
- * Get enclosure.
- *
- * @return string
- */
- public function getEnclosure()
- {
- return $this->enclosure;
- }
-
- /**
- * Set enclosure.
- *
- * @param string $pValue Enclosure, defaults to "
- *
- * @return $this
- */
- public function setEnclosure($pValue = '"')
- {
- $this->enclosure = $pValue;
-
- return $this;
- }
-
- /**
- * Get line ending.
- *
- * @return string
- */
- public function getLineEnding()
- {
- return $this->lineEnding;
- }
-
- /**
- * Set line ending.
- *
- * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL)
- *
- * @return $this
- */
- public function setLineEnding($pValue)
- {
- $this->lineEnding = $pValue;
-
- return $this;
- }
-
- /**
- * Get whether BOM should be used.
- *
- * @return bool
- */
- public function getUseBOM()
- {
- return $this->useBOM;
- }
-
- /**
- * Set whether BOM should be used.
- *
- * @param bool $pValue Use UTF-8 byte-order mark? Defaults to false
- *
- * @return $this
- */
- public function setUseBOM($pValue)
- {
- $this->useBOM = $pValue;
-
- return $this;
- }
-
- /**
- * Get whether a separator line should be included.
- *
- * @return bool
- */
- public function getIncludeSeparatorLine()
- {
- return $this->includeSeparatorLine;
- }
-
- /**
- * Set whether a separator line should be included as the first line of the file.
- *
- * @param bool $pValue Use separator line? Defaults to false
- *
- * @return $this
- */
- public function setIncludeSeparatorLine($pValue)
- {
- $this->includeSeparatorLine = $pValue;
-
- return $this;
- }
-
- /**
- * Get whether the file should be saved with full Excel Compatibility.
- *
- * @return bool
- */
- public function getExcelCompatibility()
- {
- return $this->excelCompatibility;
- }
-
- /**
- * Set whether the file should be saved with full Excel Compatibility.
- *
- * @param bool $pValue Set the file to be written as a fully Excel compatible csv file
- * Note that this overrides other settings such as useBOM, enclosure and delimiter
- *
- * @return $this
- */
- public function setExcelCompatibility($pValue)
- {
- $this->excelCompatibility = $pValue;
-
- return $this;
- }
-
- /**
- * Get sheet index.
- *
- * @return int
- */
- public function getSheetIndex()
- {
- return $this->sheetIndex;
- }
-
- /**
- * Set sheet index.
- *
- * @param int $pValue Sheet index
- *
- * @return $this
- */
- public function setSheetIndex($pValue)
- {
- $this->sheetIndex = $pValue;
-
- return $this;
- }
-
- private $enclosureRequired = true;
-
- public function setEnclosureRequired(bool $value): self
- {
- $this->enclosureRequired = $value;
-
- return $this;
- }
-
- public function getEnclosureRequired(): bool
- {
- return $this->enclosureRequired;
- }
-
- /**
- * Write line to CSV file.
- *
- * @param resource $pFileHandle PHP filehandle
- * @param array $pValues Array containing values in a row
- */
- private function writeLine($pFileHandle, array $pValues): void
- {
- // No leading delimiter
- $delimiter = '';
-
- // Build the line
- $line = '';
-
- foreach ($pValues as $element) {
- // Add delimiter
- $line .= $delimiter;
- $delimiter = $this->delimiter;
- // Escape enclosures
- $enclosure = $this->enclosure;
- if ($enclosure) {
- // If enclosure is not required, use enclosure only if
- // element contains newline, delimiter, or enclosure.
- if (!$this->enclosureRequired && strpbrk($element, "$delimiter$enclosure\n") === false) {
- $enclosure = '';
- } else {
- $element = str_replace($enclosure, $enclosure . $enclosure, $element);
- }
- }
- // Add enclosed string
- $line .= $enclosure . $element . $enclosure;
- }
-
- // Add line ending
- $line .= $this->lineEnding;
-
- // Write to file
- fwrite($pFileHandle, $line);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Exception.php b/vendor/PhpSpreadsheet/Writer/Exception.php
deleted file mode 100644
index 92e6f5f..0000000
--- a/vendor/PhpSpreadsheet/Writer/Exception.php
+++ /dev/null
@@ -1,9 +0,0 @@
-spreadsheet = $spreadsheet;
- $this->defaultFont = $this->spreadsheet->getDefaultStyle()->getFont();
- }
-
- /**
- * Save Spreadsheet to file.
- *
- * @param resource|string $pFilename
- */
- public function save($pFilename): void
- {
- // Open file
- $this->openFileHandle($pFilename);
-
- // Write html
- fwrite($this->fileHandle, $this->generateHTMLAll());
-
- // Close file
- $this->maybeCloseFileHandle();
- }
-
- /**
- * Save Spreadsheet as html to variable.
- *
- * @return string
- */
- public function generateHtmlAll()
- {
- // garbage collect
- $this->spreadsheet->garbageCollect();
-
- $saveDebugLog = Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog();
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false);
- $saveArrayReturnType = Calculation::getArrayReturnType();
- Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_VALUE);
-
- // Build CSS
- $this->buildCSS(!$this->useInlineCss);
-
- $html = '';
-
- // Write headers
- $html .= $this->generateHTMLHeader(!$this->useInlineCss);
-
- // Write navigation (tabs)
- if ((!$this->isPdf) && ($this->generateSheetNavigationBlock)) {
- $html .= $this->generateNavigation();
- }
-
- // Write data
- $html .= $this->generateSheetData();
-
- // Write footer
- $html .= $this->generateHTMLFooter();
- $callback = $this->editHtmlCallback;
- if ($callback) {
- $html = $callback($html);
- }
-
- Calculation::setArrayReturnType($saveArrayReturnType);
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
-
- return $html;
- }
-
- /**
- * Set a callback to edit the entire HTML.
- *
- * The callback must accept the HTML as string as first parameter,
- * and it must return the edited HTML as string.
- */
- public function setEditHtmlCallback(?callable $callback): void
- {
- $this->editHtmlCallback = $callback;
- }
-
- const VALIGN_ARR = [
- Alignment::VERTICAL_BOTTOM => 'bottom',
- Alignment::VERTICAL_TOP => 'top',
- Alignment::VERTICAL_CENTER => 'middle',
- Alignment::VERTICAL_JUSTIFY => 'middle',
- ];
-
- /**
- * Map VAlign.
- *
- * @param string $vAlign Vertical alignment
- *
- * @return string
- */
- private function mapVAlign($vAlign)
- {
- return array_key_exists($vAlign, self::VALIGN_ARR) ? self::VALIGN_ARR[$vAlign] : 'baseline';
- }
-
- const HALIGN_ARR = [
- Alignment::HORIZONTAL_LEFT => 'left',
- Alignment::HORIZONTAL_RIGHT => 'right',
- Alignment::HORIZONTAL_CENTER => 'center',
- Alignment::HORIZONTAL_CENTER_CONTINUOUS => 'center',
- Alignment::HORIZONTAL_JUSTIFY => 'justify',
- ];
-
- /**
- * Map HAlign.
- *
- * @param string $hAlign Horizontal alignment
- *
- * @return string
- */
- private function mapHAlign($hAlign)
- {
- return array_key_exists($hAlign, self::HALIGN_ARR) ? self::HALIGN_ARR[$hAlign] : '';
- }
-
- const BORDER_ARR = [
- Border::BORDER_NONE => 'none',
- Border::BORDER_DASHDOT => '1px dashed',
- Border::BORDER_DASHDOTDOT => '1px dotted',
- Border::BORDER_DASHED => '1px dashed',
- Border::BORDER_DOTTED => '1px dotted',
- Border::BORDER_DOUBLE => '3px double',
- Border::BORDER_HAIR => '1px solid',
- Border::BORDER_MEDIUM => '2px solid',
- Border::BORDER_MEDIUMDASHDOT => '2px dashed',
- Border::BORDER_MEDIUMDASHDOTDOT => '2px dotted',
- Border::BORDER_SLANTDASHDOT => '2px dashed',
- Border::BORDER_THICK => '3px solid',
- ];
-
- /**
- * Map border style.
- *
- * @param int $borderStyle Sheet index
- *
- * @return string
- */
- private function mapBorderStyle($borderStyle)
- {
- return array_key_exists($borderStyle, self::BORDER_ARR) ? self::BORDER_ARR[$borderStyle] : '1px solid';
- }
-
- /**
- * Get sheet index.
- *
- * @return int
- */
- public function getSheetIndex()
- {
- return $this->sheetIndex;
- }
-
- /**
- * Set sheet index.
- *
- * @param int $pValue Sheet index
- *
- * @return $this
- */
- public function setSheetIndex($pValue)
- {
- $this->sheetIndex = $pValue;
-
- return $this;
- }
-
- /**
- * Get sheet index.
- *
- * @return bool
- */
- public function getGenerateSheetNavigationBlock()
- {
- return $this->generateSheetNavigationBlock;
- }
-
- /**
- * Set sheet index.
- *
- * @param bool $pValue Flag indicating whether the sheet navigation block should be generated or not
- *
- * @return $this
- */
- public function setGenerateSheetNavigationBlock($pValue)
- {
- $this->generateSheetNavigationBlock = (bool) $pValue;
-
- return $this;
- }
-
- /**
- * Write all sheets (resets sheetIndex to NULL).
- *
- * @return $this
- */
- public function writeAllSheets()
- {
- $this->sheetIndex = null;
-
- return $this;
- }
-
- private static function generateMeta($val, $desc)
- {
- return $val ? (' ' . PHP_EOL) : '';
- }
-
- /**
- * Generate HTML header.
- *
- * @param bool $pIncludeStyles Include styles?
- *
- * @return string
- */
- public function generateHTMLHeader($pIncludeStyles = false)
- {
- // Construct HTML
- $properties = $this->spreadsheet->getProperties();
- $html = '' . PHP_EOL;
- $html .= '' . PHP_EOL;
- $html .= ' ' . PHP_EOL;
- $html .= ' ' . PHP_EOL;
- $html .= ' ' . PHP_EOL;
- $html .= ' ' . htmlspecialchars($properties->getTitle()) . '' . PHP_EOL;
- $html .= self::generateMeta($properties->getCreator(), 'author');
- $html .= self::generateMeta($properties->getTitle(), 'title');
- $html .= self::generateMeta($properties->getDescription(), 'description');
- $html .= self::generateMeta($properties->getSubject(), 'subject');
- $html .= self::generateMeta($properties->getKeywords(), 'keywords');
- $html .= self::generateMeta($properties->getCategory(), 'category');
- $html .= self::generateMeta($properties->getCompany(), 'company');
- $html .= self::generateMeta($properties->getManager(), 'manager');
-
- $html .= $pIncludeStyles ? $this->generateStyles(true) : $this->generatePageDeclarations(true);
-
- $html .= ' ' . PHP_EOL;
- $html .= '' . PHP_EOL;
- $html .= ' ' . PHP_EOL;
-
- return $html;
- }
-
- private function generateSheetPrep()
- {
- // Ensure that Spans have been calculated?
- $this->calculateSpans();
-
- // Fetch sheets
- if ($this->sheetIndex === null) {
- $sheets = $this->spreadsheet->getAllSheets();
- } else {
- $sheets = [$this->spreadsheet->getSheet($this->sheetIndex)];
- }
-
- return $sheets;
- }
-
- private function generateSheetStarts($sheet, $rowMin)
- {
- // calculate start of ,
- $tbodyStart = $rowMin;
- $theadStart = $theadEnd = 0; // default: no no
- if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
- $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop();
-
- // we can only support repeating rows that start at top row
- if ($rowsToRepeatAtTop[0] == 1) {
- $theadStart = $rowsToRepeatAtTop[0];
- $theadEnd = $rowsToRepeatAtTop[1];
- $tbodyStart = $rowsToRepeatAtTop[1] + 1;
- }
- }
-
- return [$theadStart, $theadEnd, $tbodyStart];
- }
-
- private function generateSheetTags($row, $theadStart, $theadEnd, $tbodyStart)
- {
- // ?
- $startTag = ($row == $theadStart) ? (' ' . PHP_EOL) : '';
- if (!$startTag) {
- $startTag = ($row == $tbodyStart) ? (' ' . PHP_EOL) : '';
- }
- $endTag = ($row == $theadEnd) ? (' ' . PHP_EOL) : '';
- $cellType = ($row >= $tbodyStart) ? 'td' : 'th';
-
- return [$cellType, $startTag, $endTag];
- }
-
- /**
- * Generate sheet data.
- *
- * @return string
- */
- public function generateSheetData()
- {
- $sheets = $this->generateSheetPrep();
-
- // Construct HTML
- $html = '';
-
- // Loop all sheets
- $sheetId = 0;
- foreach ($sheets as $sheet) {
- // Write table header
- $html .= $this->generateTableHeader($sheet);
-
- // Get worksheet dimension
- [$min, $max] = explode(':', $sheet->calculateWorksheetDataDimension());
- [$minCol, $minRow] = Coordinate::coordinateFromString($min);
- $minCol = Coordinate::columnIndexFromString($minCol);
- [$maxCol, $maxRow] = Coordinate::coordinateFromString($max);
- $maxCol = Coordinate::columnIndexFromString($maxCol);
-
- [$theadStart, $theadEnd, $tbodyStart] = $this->generateSheetStarts($sheet, $minRow);
-
- // Loop through cells
- $row = $minRow - 1;
- while ($row++ < $maxRow) {
- [$cellType, $startTag, $endTag] = $this->generateSheetTags($row, $theadStart, $theadEnd, $tbodyStart);
- $html .= $startTag;
-
- // Write row if there are HTML table cells in it
- if (!isset($this->isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row])) {
- // Start a new rowData
- $rowData = [];
- // Loop through columns
- $column = $minCol;
- while ($column <= $maxCol) {
- // Cell exists?
- if ($sheet->cellExistsByColumnAndRow($column, $row)) {
- $rowData[$column] = Coordinate::stringFromColumnIndex($column) . $row;
- } else {
- $rowData[$column] = '';
- }
- ++$column;
- }
- $html .= $this->generateRow($sheet, $rowData, $row - 1, $cellType);
- }
-
- $html .= $endTag;
- }
- $html .= $this->extendRowsForChartsAndImages($sheet, $row);
-
- // Write table footer
- $html .= $this->generateTableFooter();
- // Writing PDF?
- if ($this->isPdf && $this->useInlineCss) {
- if ($this->sheetIndex === null && $sheetId + 1 < $this->spreadsheet->getSheetCount()) {
- $html .= '';
- }
- }
-
- // Next sheet
- ++$sheetId;
- }
-
- return $html;
- }
-
- /**
- * Generate sheet tabs.
- *
- * @return string
- */
- public function generateNavigation()
- {
- // Fetch sheets
- $sheets = [];
- if ($this->sheetIndex === null) {
- $sheets = $this->spreadsheet->getAllSheets();
- } else {
- $sheets[] = $this->spreadsheet->getSheet($this->sheetIndex);
- }
-
- // Construct HTML
- $html = '';
-
- // Only if there are more than 1 sheets
- if (count($sheets) > 1) {
- // Loop all sheets
- $sheetId = 0;
-
- $html .= '' . PHP_EOL;
-
- foreach ($sheets as $sheet) {
- $html .= ' - ' . $sheet->getTitle() . '
' . PHP_EOL;
- ++$sheetId;
- }
-
- $html .= '
' . PHP_EOL;
- }
-
- return $html;
- }
-
- /**
- * Extend Row if chart is placed after nominal end of row.
- * This code should be exercised by sample:
- * Chart/32_Chart_read_write_PDF.php.
- * However, that test is suppressed due to out-of-date
- * Jpgraph code issuing warnings. So, don't measure
- * code coverage for this function till that is fixed.
- *
- * @param Worksheet $pSheet \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- * @param int $row Row to check for charts
- *
- * @return array
- *
- * @codeCoverageIgnore
- */
- private function extendRowsForCharts(Worksheet $pSheet, int $row)
- {
- $rowMax = $row;
- $colMax = 'A';
- $anyfound = false;
- if ($this->includeCharts) {
- foreach ($pSheet->getChartCollection() as $chart) {
- if ($chart instanceof Chart) {
- $anyfound = true;
- $chartCoordinates = $chart->getTopLeftPosition();
- $chartTL = Coordinate::coordinateFromString($chartCoordinates['cell']);
- $chartCol = Coordinate::columnIndexFromString($chartTL[0]);
- if ($chartTL[1] > $rowMax) {
- $rowMax = $chartTL[1];
- if ($chartCol > Coordinate::columnIndexFromString($colMax)) {
- $colMax = $chartTL[0];
- }
- }
- }
- }
- }
-
- return [$rowMax, $colMax, $anyfound];
- }
-
- private function extendRowsForChartsAndImages(Worksheet $pSheet, int $row): string
- {
- [$rowMax, $colMax, $anyfound] = $this->extendRowsForCharts($pSheet, $row);
-
- foreach ($pSheet->getDrawingCollection() as $drawing) {
- $anyfound = true;
- $imageTL = Coordinate::coordinateFromString($drawing->getCoordinates());
- $imageCol = Coordinate::columnIndexFromString($imageTL[0]);
- if ($imageTL[1] > $rowMax) {
- $rowMax = $imageTL[1];
- if ($imageCol > Coordinate::columnIndexFromString($colMax)) {
- $colMax = $imageTL[0];
- }
- }
- }
-
- // Don't extend rows if not needed
- if ($row === $rowMax || !$anyfound) {
- return '';
- }
-
- $html = '';
- ++$colMax;
- ++$row;
- while ($row <= $rowMax) {
- $html .= '';
- for ($col = 'A'; $col != $colMax; ++$col) {
- $htmlx = $this->writeImageInCell($pSheet, $col . $row);
- $htmlx .= $this->includeCharts ? $this->writeChartInCell($pSheet, $col . $row) : '';
- if ($htmlx) {
- $html .= "$htmlx | ";
- } else {
- $html .= " | ";
- }
- }
- ++$row;
- $html .= '
' . PHP_EOL;
- }
-
- return $html;
- }
-
- /**
- * Convert Windows file name to file protocol URL.
- *
- * @param string $filename file name on local system
- *
- * @return string
- */
- public static function winFileToUrl($filename)
- {
- // Windows filename
- if (substr($filename, 1, 2) === ':\\') {
- $filename = 'file:///' . str_replace('\\', '/', $filename);
- }
-
- return $filename;
- }
-
- /**
- * Generate image tag in cell.
- *
- * @param Worksheet $pSheet \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- * @param string $coordinates Cell coordinates
- *
- * @return string
- */
- private function writeImageInCell(Worksheet $pSheet, $coordinates)
- {
- // Construct HTML
- $html = '';
-
- // Write images
- foreach ($pSheet->getDrawingCollection() as $drawing) {
- if ($drawing->getCoordinates() != $coordinates) {
- continue;
- }
- $filedesc = $drawing->getDescription();
- $filedesc = $filedesc ? htmlspecialchars($filedesc, ENT_QUOTES) : 'Embedded image';
- if ($drawing instanceof Drawing) {
- $filename = $drawing->getPath();
-
- // Strip off eventual '.'
- $filename = preg_replace('/^[.]/', '', $filename);
-
- // Prepend images root
- $filename = $this->getImagesRoot() . $filename;
-
- // Strip off eventual '.' if followed by non-/
- $filename = preg_replace('@^[.]([^/])@', '$1', $filename);
-
- // Convert UTF8 data to PCDATA
- $filename = htmlspecialchars($filename);
-
- $html .= PHP_EOL;
- $imageData = self::winFileToUrl($filename);
-
- if ($this->embedImages && !$this->isPdf) {
- $picture = @file_get_contents($filename);
- if ($picture !== false) {
- $imageDetails = getimagesize($filename);
- // base64 encode the binary data
- $base64 = base64_encode($picture);
- $imageData = 'data:' . $imageDetails['mime'] . ';base64,' . $base64;
- }
- }
-
- $html .= '';
- } elseif ($drawing instanceof MemoryDrawing) {
- ob_start(); // Let's start output buffering.
- imagepng($drawing->getImageResource()); // This will normally output the image, but because of ob_start(), it won't.
- $contents = ob_get_contents(); // Instead, output above is saved to $contents
- ob_end_clean(); // End the output buffer.
-
- $dataUri = 'data:image/jpeg;base64,' . base64_encode($contents);
-
- // Because of the nature of tables, width is more important than height.
- // max-width: 100% ensures that image doesnt overflow containing cell
- // width: X sets width of supplied image.
- // As a result, images bigger than cell will be contained and images smaller will not get stretched
- $html .= '';
- }
- }
-
- return $html;
- }
-
- /**
- * Generate chart tag in cell.
- * This code should be exercised by sample:
- * Chart/32_Chart_read_write_PDF.php.
- * However, that test is suppressed due to out-of-date
- * Jpgraph code issuing warnings. So, don't measure
- * code coverage for this function till that is fixed.
- *
- * @param Worksheet $pSheet \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- * @param string $coordinates Cell coordinates
- *
- * @return string
- *
- * @codeCoverageIgnore
- */
- private function writeChartInCell(Worksheet $pSheet, $coordinates)
- {
- // Construct HTML
- $html = '';
-
- // Write charts
- foreach ($pSheet->getChartCollection() as $chart) {
- if ($chart instanceof Chart) {
- $chartCoordinates = $chart->getTopLeftPosition();
- if ($chartCoordinates['cell'] == $coordinates) {
- $chartFileName = File::sysGetTempDir() . '/' . uniqid('', true) . '.png';
- if (!$chart->render($chartFileName)) {
- return;
- }
-
- $html .= PHP_EOL;
- $imageDetails = getimagesize($chartFileName);
- $filedesc = $chart->getTitle();
- $filedesc = $filedesc ? self::getChartCaption($filedesc->getCaption()) : '';
- $filedesc = $filedesc ? htmlspecialchars($filedesc, ENT_QUOTES) : 'Embedded chart';
- if ($fp = fopen($chartFileName, 'rb', 0)) {
- $picture = fread($fp, filesize($chartFileName));
- fclose($fp);
- // base64 encode the binary data
- $base64 = base64_encode($picture);
- $imageData = 'data:' . $imageDetails['mime'] . ';base64,' . $base64;
-
- $html .= '' . PHP_EOL;
-
- unlink($chartFileName);
- }
- }
- }
- }
-
- // Return
- return $html;
- }
-
- /**
- * Extend Row if chart is placed after nominal end of row.
- * This code should be exercised by sample:
- * Chart/32_Chart_read_write_PDF.php.
- * However, that test is suppressed due to out-of-date
- * Jpgraph code issuing warnings. So, don't measure
- * code coverage for this function till that is fixed.
- * Caption is described in documentation as fixed,
- * but in 32_Chart it is somehow an array of RichText.
- *
- * @param mixed $cap
- *
- * @return string
- *
- * @codeCoverageIgnore
- */
- private static function getChartCaption($cap)
- {
- return is_array($cap) ? implode(' ', $cap) : $cap;
- }
-
- /**
- * Generate CSS styles.
- *
- * @param bool $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>)
- *
- * @return string
- */
- public function generateStyles($generateSurroundingHTML = true)
- {
- // Build CSS
- $css = $this->buildCSS($generateSurroundingHTML);
-
- // Construct HTML
- $html = '';
-
- // Start styles
- if ($generateSurroundingHTML) {
- $html .= ' ' . PHP_EOL;
- }
-
- // Return
- return $html;
- }
-
- private function buildCssRowHeights(Worksheet $sheet, array &$css, int $sheetIndex): void
- {
- // Calculate row heights
- foreach ($sheet->getRowDimensions() as $rowDimension) {
- $row = $rowDimension->getRowIndex() - 1;
-
- // table.sheetN tr.rowYYYYYY { }
- $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = [];
-
- if ($rowDimension->getRowHeight() != -1) {
- $pt_height = $rowDimension->getRowHeight();
- $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt';
- }
- if ($rowDimension->getVisible() === false) {
- $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none';
- $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden';
- }
- }
- }
-
- private function buildCssPerSheet(Worksheet $sheet, array &$css): void
- {
- // Calculate hash code
- $sheetIndex = $sheet->getParent()->getIndex($sheet);
-
- // Build styles
- // Calculate column widths
- $sheet->calculateColumnWidths();
-
- // col elements, initialize
- $highestColumnIndex = Coordinate::columnIndexFromString($sheet->getHighestColumn()) - 1;
- $column = -1;
- while ($column++ < $highestColumnIndex) {
- $this->columnWidths[$sheetIndex][$column] = 42; // approximation
- $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt';
- }
-
- // col elements, loop through columnDimensions and set width
- foreach ($sheet->getColumnDimensions() as $columnDimension) {
- $column = Coordinate::columnIndexFromString($columnDimension->getColumnIndex()) - 1;
- $width = SharedDrawing::cellDimensionToPixels($columnDimension->getWidth(), $this->defaultFont);
- $width = SharedDrawing::pixelsToPoints($width);
- if ($columnDimension->getVisible() === false) {
- $css['table.sheet' . $sheetIndex . ' .column' . $column]['display'] = 'none';
- }
- if ($width >= 0) {
- $this->columnWidths[$sheetIndex][$column] = $width;
- $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt';
- }
- }
-
- // Default row height
- $rowDimension = $sheet->getDefaultRowDimension();
-
- // table.sheetN tr { }
- $css['table.sheet' . $sheetIndex . ' tr'] = [];
-
- if ($rowDimension->getRowHeight() == -1) {
- $pt_height = SharedFont::getDefaultRowHeightByFont($this->spreadsheet->getDefaultStyle()->getFont());
- } else {
- $pt_height = $rowDimension->getRowHeight();
- }
- $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt';
- if ($rowDimension->getVisible() === false) {
- $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none';
- $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden';
- }
-
- $this->buildCssRowHeights($sheet, $css, $sheetIndex);
- }
-
- /**
- * Build CSS styles.
- *
- * @param bool $generateSurroundingHTML Generate surrounding HTML style? (html { })
- *
- * @return array
- */
- public function buildCSS($generateSurroundingHTML = true)
- {
- // Cached?
- if ($this->cssStyles !== null) {
- return $this->cssStyles;
- }
-
- // Ensure that spans have been calculated
- $this->calculateSpans();
-
- // Construct CSS
- $css = [];
-
- // Start styles
- if ($generateSurroundingHTML) {
- // html { }
- $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif';
- $css['html']['font-size'] = '11pt';
- $css['html']['background-color'] = 'white';
- }
-
- // CSS for comments as found in LibreOffice
- $css['a.comment-indicator:hover + div.comment'] = [
- 'background' => '#ffd',
- 'position' => 'absolute',
- 'display' => 'block',
- 'border' => '1px solid black',
- 'padding' => '0.5em',
- ];
-
- $css['a.comment-indicator'] = [
- 'background' => 'red',
- 'display' => 'inline-block',
- 'border' => '1px solid black',
- 'width' => '0.5em',
- 'height' => '0.5em',
- ];
-
- $css['div.comment']['display'] = 'none';
-
- // table { }
- $css['table']['border-collapse'] = 'collapse';
-
- // .b {}
- $css['.b']['text-align'] = 'center'; // BOOL
-
- // .e {}
- $css['.e']['text-align'] = 'center'; // ERROR
-
- // .f {}
- $css['.f']['text-align'] = 'right'; // FORMULA
-
- // .inlineStr {}
- $css['.inlineStr']['text-align'] = 'left'; // INLINE
-
- // .n {}
- $css['.n']['text-align'] = 'right'; // NUMERIC
-
- // .s {}
- $css['.s']['text-align'] = 'left'; // STRING
-
- // Calculate cell style hashes
- foreach ($this->spreadsheet->getCellXfCollection() as $index => $style) {
- $css['td.style' . $index] = $this->createCSSStyle($style);
- $css['th.style' . $index] = $this->createCSSStyle($style);
- }
-
- // Fetch sheets
- $sheets = [];
- if ($this->sheetIndex === null) {
- $sheets = $this->spreadsheet->getAllSheets();
- } else {
- $sheets[] = $this->spreadsheet->getSheet($this->sheetIndex);
- }
-
- // Build styles per sheet
- foreach ($sheets as $sheet) {
- $this->buildCssPerSheet($sheet, $css);
- }
-
- // Cache
- if ($this->cssStyles === null) {
- $this->cssStyles = $css;
- }
-
- // Return
- return $css;
- }
-
- /**
- * Create CSS style.
- *
- * @return array
- */
- private function createCSSStyle(Style $pStyle)
- {
- // Create CSS
- return array_merge(
- $this->createCSSStyleAlignment($pStyle->getAlignment()),
- $this->createCSSStyleBorders($pStyle->getBorders()),
- $this->createCSSStyleFont($pStyle->getFont()),
- $this->createCSSStyleFill($pStyle->getFill())
- );
- }
-
- /**
- * Create CSS style (\PhpOffice\PhpSpreadsheet\Style\Alignment).
- *
- * @param Alignment $pStyle \PhpOffice\PhpSpreadsheet\Style\Alignment
- *
- * @return array
- */
- private function createCSSStyleAlignment(Alignment $pStyle)
- {
- // Construct CSS
- $css = [];
-
- // Create CSS
- $css['vertical-align'] = $this->mapVAlign($pStyle->getVertical());
- $textAlign = $this->mapHAlign($pStyle->getHorizontal());
- if ($textAlign) {
- $css['text-align'] = $textAlign;
- if (in_array($textAlign, ['left', 'right'])) {
- $css['padding-' . $textAlign] = (string) ((int) $pStyle->getIndent() * 9) . 'px';
- }
- }
-
- return $css;
- }
-
- /**
- * Create CSS style (\PhpOffice\PhpSpreadsheet\Style\Font).
- *
- * @return array
- */
- private function createCSSStyleFont(Font $pStyle)
- {
- // Construct CSS
- $css = [];
-
- // Create CSS
- if ($pStyle->getBold()) {
- $css['font-weight'] = 'bold';
- }
- if ($pStyle->getUnderline() != Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) {
- $css['text-decoration'] = 'underline line-through';
- } elseif ($pStyle->getUnderline() != Font::UNDERLINE_NONE) {
- $css['text-decoration'] = 'underline';
- } elseif ($pStyle->getStrikethrough()) {
- $css['text-decoration'] = 'line-through';
- }
- if ($pStyle->getItalic()) {
- $css['font-style'] = 'italic';
- }
-
- $css['color'] = '#' . $pStyle->getColor()->getRGB();
- $css['font-family'] = '\'' . $pStyle->getName() . '\'';
- $css['font-size'] = $pStyle->getSize() . 'pt';
-
- return $css;
- }
-
- /**
- * Create CSS style (Borders).
- *
- * @param Borders $pStyle Borders
- *
- * @return array
- */
- private function createCSSStyleBorders(Borders $pStyle)
- {
- // Construct CSS
- $css = [];
-
- // Create CSS
- $css['border-bottom'] = $this->createCSSStyleBorder($pStyle->getBottom());
- $css['border-top'] = $this->createCSSStyleBorder($pStyle->getTop());
- $css['border-left'] = $this->createCSSStyleBorder($pStyle->getLeft());
- $css['border-right'] = $this->createCSSStyleBorder($pStyle->getRight());
-
- return $css;
- }
-
- /**
- * Create CSS style (Border).
- *
- * @param Border $pStyle Border
- *
- * @return string
- */
- private function createCSSStyleBorder(Border $pStyle)
- {
- // Create CSS - add !important to non-none border styles for merged cells
- $borderStyle = $this->mapBorderStyle($pStyle->getBorderStyle());
-
- return $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important');
- }
-
- /**
- * Create CSS style (Fill).
- *
- * @param Fill $pStyle Fill
- *
- * @return array
- */
- private function createCSSStyleFill(Fill $pStyle)
- {
- // Construct HTML
- $css = [];
-
- // Create CSS
- $value = $pStyle->getFillType() == Fill::FILL_NONE ?
- 'white' : '#' . $pStyle->getStartColor()->getRGB();
- $css['background-color'] = $value;
-
- return $css;
- }
-
- /**
- * Generate HTML footer.
- */
- public function generateHTMLFooter()
- {
- // Construct HTML
- $html = '';
- $html .= ' ' . PHP_EOL;
- $html .= '' . PHP_EOL;
-
- return $html;
- }
-
- private function generateTableTagInline($pSheet, $id)
- {
- $style = isset($this->cssStyles['table']) ?
- $this->assembleCSS($this->cssStyles['table']) : '';
-
- $prntgrid = $pSheet->getPrintGridlines();
- $viewgrid = $this->isPdf ? $prntgrid : $pSheet->getShowGridlines();
- if ($viewgrid && $prntgrid) {
- $html = " " . PHP_EOL;
- } elseif ($viewgrid) {
- $html = " " . PHP_EOL;
- } elseif ($prntgrid) {
- $html = " " . PHP_EOL;
- } else {
- $html = " " . PHP_EOL;
- }
-
- return $html;
- }
-
- private function generateTableTag($pSheet, $id, &$html, $sheetIndex): void
- {
- if (!$this->useInlineCss) {
- $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : '';
- $gridlinesp = $pSheet->getPrintGridlines() ? ' gridlinesp' : '';
- $html .= " " . PHP_EOL;
- } else {
- $html .= $this->generateTableTagInline($pSheet, $id);
- }
- }
-
- /**
- * Generate table header.
- *
- * @param Worksheet $pSheet The worksheet for the table we are writing
- * @param bool $showid whether or not to add id to table tag
- *
- * @return string
- */
- private function generateTableHeader($pSheet, $showid = true)
- {
- $sheetIndex = $pSheet->getParent()->getIndex($pSheet);
-
- // Construct HTML
- $html = '';
- $id = $showid ? "id='sheet$sheetIndex'" : '';
- if ($showid) {
- $html .= "\n";
- } else {
- $html .= "
\n";
- }
-
- $this->generateTableTag($pSheet, $id, $html, $sheetIndex);
-
- // Write
elements
- $highestColumnIndex = Coordinate::columnIndexFromString($pSheet->getHighestColumn()) - 1;
- $i = -1;
- while ($i++ < $highestColumnIndex) {
- if (!$this->useInlineCss) {
- $html .= ' ' . PHP_EOL;
- } else {
- $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ?
- $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : '';
- $html .= ' ' . PHP_EOL;
- }
- }
-
- return $html;
- }
-
- /**
- * Generate table footer.
- */
- private function generateTableFooter()
- {
- return '
' . PHP_EOL . '' . PHP_EOL;
- }
-
- /**
- * Generate row start.
- *
- * @param Worksheet $pSheet \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- * @param int $sheetIndex Sheet index (0-based)
- * @param int $pRow row number
- *
- * @return string
- */
- private function generateRowStart(Worksheet $pSheet, $sheetIndex, $pRow)
- {
- $html = '';
- if (count($pSheet->getBreaks()) > 0) {
- $breaks = $pSheet->getBreaks();
-
- // check if a break is needed before this row
- if (isset($breaks['A' . $pRow])) {
- // close table:
- $html .= $this->generateTableFooter();
- if ($this->isPdf && $this->useInlineCss) {
- $html .= '';
- }
-
- // open table again: + etc.
- $html .= $this->generateTableHeader($pSheet, false);
- $html .= '' . PHP_EOL;
- }
- }
-
- // Write row start
- if (!$this->useInlineCss) {
- $html .= ' ' . PHP_EOL;
- } else {
- $style = isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow])
- ? $this->assembleCSS($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : '';
-
- $html .= '
' . PHP_EOL;
- }
-
- return $html;
- }
-
- private function generateRowCellCss($pSheet, $cellAddress, $pRow, $colNum)
- {
- $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : '';
- $coordinate = Coordinate::stringFromColumnIndex($colNum + 1) . ($pRow + 1);
- if (!$this->useInlineCss) {
- $cssClass = 'column' . $colNum;
- } else {
- $cssClass = [];
- // The statements below do nothing.
- // Commenting out the code rather than deleting it
- // in case someone can figure out what their intent was.
- //if ($cellType == 'th') {
- // if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) {
- // $this->cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum];
- // }
- //} else {
- // if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) {
- // $this->cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum];
- // }
- //}
- // End of mystery statements.
- }
-
- return [$cell, $cssClass, $coordinate];
- }
-
- private function generateRowCellDataValueRich($cell, &$cellData): void
- {
- // Loop through rich text elements
- $elements = $cell->getValue()->getRichTextElements();
- foreach ($elements as $element) {
- // Rich text start?
- if ($element instanceof Run) {
- $cellData .= '';
-
- $cellEnd = '';
- if ($element->getFont()->getSuperscript()) {
- $cellData .= '';
- $cellEnd = '';
- } elseif ($element->getFont()->getSubscript()) {
- $cellData .= '';
- $cellEnd = '';
- }
-
- // Convert UTF8 data to PCDATA
- $cellText = $element->getText();
- $cellData .= htmlspecialchars($cellText);
-
- $cellData .= $cellEnd;
-
- $cellData .= '';
- } else {
- // Convert UTF8 data to PCDATA
- $cellText = $element->getText();
- $cellData .= htmlspecialchars($cellText);
- }
- }
- }
-
- private function generateRowCellDataValue($pSheet, $cell, &$cellData): void
- {
- if ($cell->getValue() instanceof RichText) {
- $this->generateRowCellDataValueRich($cell, $cellData);
- } else {
- $origData = $this->preCalculateFormulas ? $cell->getCalculatedValue() : $cell->getValue();
- $cellData = NumberFormat::toFormattedString(
- $origData,
- $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode(),
- [$this, 'formatColor']
- );
- if ($cellData === $origData) {
- $cellData = htmlspecialchars($cellData);
- }
- if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperscript()) {
- $cellData = '' . $cellData . '';
- } elseif ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSubscript()) {
- $cellData = '' . $cellData . '';
- }
- }
- }
-
- private function generateRowCellData($pSheet, $cell, &$cssClass, $cellType)
- {
- $cellData = ' ';
- if ($cell instanceof Cell) {
- $cellData = '';
- // Don't know what this does, and no test cases.
- //if ($cell->getParent() === null) {
- // $cell->attach($pSheet);
- //}
- // Value
- $this->generateRowCellDataValue($pSheet, $cell, $cellData);
-
- // Converts the cell content so that spaces occuring at beginning of each new line are replaced by
- // Example: " Hello\n to the world" is converted to " Hello\n to the world"
- $cellData = preg_replace('/(?m)(?:^|\\G) /', ' ', $cellData);
-
- // convert newline "\n" to '
'
- $cellData = nl2br($cellData);
-
- // Extend CSS class?
- if (!$this->useInlineCss) {
- $cssClass .= ' style' . $cell->getXfIndex();
- $cssClass .= ' ' . $cell->getDataType();
- } else {
- if ($cellType == 'th') {
- if (isset($this->cssStyles['th.style' . $cell->getXfIndex()])) {
- $cssClass = array_merge($cssClass, $this->cssStyles['th.style' . $cell->getXfIndex()]);
- }
- } else {
- if (isset($this->cssStyles['td.style' . $cell->getXfIndex()])) {
- $cssClass = array_merge($cssClass, $this->cssStyles['td.style' . $cell->getXfIndex()]);
- }
- }
-
- // General horizontal alignment: Actual horizontal alignment depends on dataType
- $sharedStyle = $pSheet->getParent()->getCellXfByIndex($cell->getXfIndex());
- if (
- $sharedStyle->getAlignment()->getHorizontal() == Alignment::HORIZONTAL_GENERAL
- && isset($this->cssStyles['.' . $cell->getDataType()]['text-align'])
- ) {
- $cssClass['text-align'] = $this->cssStyles['.' . $cell->getDataType()]['text-align'];
- }
- }
- } else {
- // Use default borders for empty cell
- if (is_string($cssClass)) {
- $cssClass .= ' style0';
- }
- }
-
- return $cellData;
- }
-
- private function generateRowIncludeCharts($pSheet, $coordinate)
- {
- return $this->includeCharts ? $this->writeChartInCell($pSheet, $coordinate) : '';
- }
-
- private function generateRowSpans($html, $rowSpan, $colSpan)
- {
- $html .= ($colSpan > 1) ? (' colspan="' . $colSpan . '"') : '';
- $html .= ($rowSpan > 1) ? (' rowspan="' . $rowSpan . '"') : '';
-
- return $html;
- }
-
- private function generateRowWriteCell(&$html, $pSheet, $coordinate, $cellType, $cellData, $colSpan, $rowSpan, $cssClass, $colNum, $sheetIndex, $pRow): void
- {
- // Image?
- $htmlx = $this->writeImageInCell($pSheet, $coordinate);
- // Chart?
- $htmlx .= $this->generateRowIncludeCharts($pSheet, $coordinate);
- // Column start
- $html .= ' <' . $cellType;
- if (!$this->useInlineCss && !$this->isPdf) {
- $html .= ' class="' . $cssClass . '"';
- if ($htmlx) {
- $html .= " style='position: relative;'";
- }
- } else {
- //** Necessary redundant code for the sake of \PhpOffice\PhpSpreadsheet\Writer\Pdf **
- // We must explicitly write the width of the element because TCPDF
- // does not recognize e.g.
- if ($this->useInlineCss) {
- $xcssClass = $cssClass;
- } else {
- $html .= ' class="' . $cssClass . '"';
- $xcssClass = [];
- }
- $width = 0;
- $i = $colNum - 1;
- $e = $colNum + $colSpan - 1;
- while ($i++ < $e) {
- if (isset($this->columnWidths[$sheetIndex][$i])) {
- $width += $this->columnWidths[$sheetIndex][$i];
- }
- }
- $xcssClass['width'] = $width . 'pt';
-
- // We must also explicitly write the height of the | element because TCPDF
- // does not recognize e.g. |
- if (isset($this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) {
- $height = $this->cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'];
- $xcssClass['height'] = $height;
- }
- //** end of redundant code **
-
- if ($htmlx) {
- $xcssClass['position'] = 'relative';
- }
- $html .= ' style="' . $this->assembleCSS($xcssClass) . '"';
- }
- $html = $this->generateRowSpans($html, $rowSpan, $colSpan);
-
- $html .= '>';
- $html .= $htmlx;
-
- $html .= $this->writeComment($pSheet, $coordinate);
-
- // Cell data
- $html .= $cellData;
-
- // Column end
- $html .= '' . $cellType . '>' . PHP_EOL;
- }
-
- /**
- * Generate row.
- *
- * @param Worksheet $pSheet \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- * @param array $pValues Array containing cells in a row
- * @param int $pRow Row number (0-based)
- * @param string $cellType eg: 'td'
- *
- * @return string
- */
- private function generateRow(Worksheet $pSheet, array $pValues, $pRow, $cellType)
- {
- // Sheet index
- $sheetIndex = $pSheet->getParent()->getIndex($pSheet);
- $html = $this->generateRowStart($pSheet, $sheetIndex, $pRow);
-
- // Write cells
- $colNum = 0;
- foreach ($pValues as $cellAddress) {
- [$cell, $cssClass, $coordinate] = $this->generateRowCellCss($pSheet, $cellAddress, $pRow, $colNum);
-
- $colSpan = 1;
- $rowSpan = 1;
-
- // Cell Data
- $cellData = $this->generateRowCellData($pSheet, $cell, $cssClass, $cellType);
-
- // Hyperlink?
- if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) {
- $cellData = '' . $cellData . '';
- }
-
- // Should the cell be written or is it swallowed by a rowspan or colspan?
- $writeCell = !(isset($this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])
- && $this->isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]);
-
- // Colspan and Rowspan
- $colspan = 1;
- $rowspan = 1;
- if (isset($this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) {
- $spans = $this->isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum];
- $rowSpan = $spans['rowspan'];
- $colSpan = $spans['colspan'];
-
- // Also apply style from last cell in merge to fix borders -
- // relies on !important for non-none border declarations in createCSSStyleBorder
- $endCellCoord = Coordinate::stringFromColumnIndex($colNum + $colSpan) . ($pRow + $rowSpan);
- if (!$this->useInlineCss) {
- $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex();
- }
- }
-
- // Write
- if ($writeCell) {
- $this->generateRowWriteCell($html, $pSheet, $coordinate, $cellType, $cellData, $colSpan, $rowSpan, $cssClass, $colNum, $sheetIndex, $pRow);
- }
-
- // Next column
- ++$colNum;
- }
-
- // Write row end
- $html .= '
' . PHP_EOL;
-
- // Return
- return $html;
- }
-
- /**
- * Takes array where of CSS properties / values and converts to CSS string.
- *
- * @return string
- */
- private function assembleCSS(array $pValue = [])
- {
- $pairs = [];
- foreach ($pValue as $property => $value) {
- $pairs[] = $property . ':' . $value;
- }
- $string = implode('; ', $pairs);
-
- return $string;
- }
-
- /**
- * Get images root.
- *
- * @return string
- */
- public function getImagesRoot()
- {
- return $this->imagesRoot;
- }
-
- /**
- * Set images root.
- *
- * @param string $pValue
- *
- * @return $this
- */
- public function setImagesRoot($pValue)
- {
- $this->imagesRoot = $pValue;
-
- return $this;
- }
-
- /**
- * Get embed images.
- *
- * @return bool
- */
- public function getEmbedImages()
- {
- return $this->embedImages;
- }
-
- /**
- * Set embed images.
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setEmbedImages($pValue)
- {
- $this->embedImages = $pValue;
-
- return $this;
- }
-
- /**
- * Get use inline CSS?
- *
- * @return bool
- */
- public function getUseInlineCss()
- {
- return $this->useInlineCss;
- }
-
- /**
- * Set use inline CSS?
- *
- * @param bool $pValue
- *
- * @return $this
- */
- public function setUseInlineCss($pValue)
- {
- $this->useInlineCss = $pValue;
-
- return $this;
- }
-
- /**
- * Get use embedded CSS?
- *
- * @return bool
- *
- * @codeCoverageIgnore
- *
- * @deprecated no longer used
- */
- public function getUseEmbeddedCSS()
- {
- return $this->useEmbeddedCSS;
- }
-
- /**
- * Set use embedded CSS?
- *
- * @param bool $pValue
- *
- * @return $this
- *
- * @codeCoverageIgnore
- *
- * @deprecated no longer used
- */
- public function setUseEmbeddedCSS($pValue)
- {
- $this->useEmbeddedCSS = $pValue;
-
- return $this;
- }
-
- /**
- * Add color to formatted string as inline style.
- *
- * @param string $pValue Plain formatted value without color
- * @param string $pFormat Format code
- *
- * @return string
- */
- public function formatColor($pValue, $pFormat)
- {
- // Color information, e.g. [Red] is always at the beginning
- $color = null; // initialize
- $matches = [];
-
- $color_regex = '/^\\[[a-zA-Z]+\\]/';
- if (preg_match($color_regex, $pFormat, $matches)) {
- $color = str_replace(['[', ']'], '', $matches[0]);
- $color = strtolower($color);
- }
-
- // convert to PCDATA
- $value = htmlspecialchars($pValue);
-
- // color span tag
- if ($color !== null) {
- $value = '' . $value . '';
- }
-
- return $value;
- }
-
- /**
- * Calculate information about HTML colspan and rowspan which is not always the same as Excel's.
- */
- private function calculateSpans(): void
- {
- if ($this->spansAreCalculated) {
- return;
- }
- // Identify all cells that should be omitted in HTML due to cell merge.
- // In HTML only the upper-left cell should be written and it should have
- // appropriate rowspan / colspan attribute
- $sheetIndexes = $this->sheetIndex !== null ?
- [$this->sheetIndex] : range(0, $this->spreadsheet->getSheetCount() - 1);
-
- foreach ($sheetIndexes as $sheetIndex) {
- $sheet = $this->spreadsheet->getSheet($sheetIndex);
-
- $candidateSpannedRow = [];
-
- // loop through all Excel merged cells
- foreach ($sheet->getMergeCells() as $cells) {
- [$cells] = Coordinate::splitRange($cells);
- $first = $cells[0];
- $last = $cells[1];
-
- [$fc, $fr] = Coordinate::coordinateFromString($first);
- $fc = Coordinate::columnIndexFromString($fc) - 1;
-
- [$lc, $lr] = Coordinate::coordinateFromString($last);
- $lc = Coordinate::columnIndexFromString($lc) - 1;
-
- // loop through the individual cells in the individual merge
- $r = $fr - 1;
- while ($r++ < $lr) {
- // also, flag this row as a HTML row that is candidate to be omitted
- $candidateSpannedRow[$r] = $r;
-
- $c = $fc - 1;
- while ($c++ < $lc) {
- if (!($c == $fc && $r == $fr)) {
- // not the upper-left cell (should not be written in HTML)
- $this->isSpannedCell[$sheetIndex][$r][$c] = [
- 'baseCell' => [$fr, $fc],
- ];
- } else {
- // upper-left is the base cell that should hold the colspan/rowspan attribute
- $this->isBaseCell[$sheetIndex][$r][$c] = [
- 'xlrowspan' => $lr - $fr + 1, // Excel rowspan
- 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change
- 'xlcolspan' => $lc - $fc + 1, // Excel colspan
- 'colspan' => $lc - $fc + 1, // HTML colspan, value may change
- ];
- }
- }
- }
- }
-
- $this->calculateSpansOmitRows($sheet, $sheetIndex, $candidateSpannedRow);
-
- // TODO: Same for columns
- }
-
- // We have calculated the spans
- $this->spansAreCalculated = true;
- }
-
- private function calculateSpansOmitRows($sheet, $sheetIndex, $candidateSpannedRow): void
- {
- // Identify which rows should be omitted in HTML. These are the rows where all the cells
- // participate in a merge and the where base cells are somewhere above.
- $countColumns = Coordinate::columnIndexFromString($sheet->getHighestColumn());
- foreach ($candidateSpannedRow as $rowIndex) {
- if (isset($this->isSpannedCell[$sheetIndex][$rowIndex])) {
- if (count($this->isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) {
- $this->isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex;
- }
- }
- }
-
- // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1
- if (isset($this->isSpannedRow[$sheetIndex])) {
- foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) {
- $adjustedBaseCells = [];
- $c = -1;
- $e = $countColumns - 1;
- while ($c++ < $e) {
- $baseCell = $this->isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];
-
- if (!in_array($baseCell, $adjustedBaseCells)) {
- // subtract rowspan by 1
- --$this->isBaseCell[$sheetIndex][$baseCell[0]][$baseCell[1]]['rowspan'];
- $adjustedBaseCells[] = $baseCell;
- }
- }
- }
- }
- }
-
- /**
- * Write a comment in the same format as LibreOffice.
- *
- * @see https://github.com/LibreOffice/core/blob/9fc9bf3240f8c62ad7859947ab8a033ac1fe93fa/sc/source/filter/html/htmlexp.cxx#L1073-L1092
- *
- * @param string $coordinate
- *
- * @return string
- */
- private function writeComment(Worksheet $pSheet, $coordinate)
- {
- $result = '';
- if (!$this->isPdf && isset($pSheet->getComments()[$coordinate])) {
- $result .= '';
- $result .= '';
- $result .= PHP_EOL;
- }
-
- return $result;
- }
-
- /**
- * Generate @page declarations.
- *
- * @param bool $generateSurroundingHTML
- *
- * @return string
- */
- private function generatePageDeclarations($generateSurroundingHTML)
- {
- // Ensure that Spans have been calculated?
- $this->calculateSpans();
-
- // Fetch sheets
- $sheets = [];
- if ($this->sheetIndex === null) {
- $sheets = $this->spreadsheet->getAllSheets();
- } else {
- $sheets[] = $this->spreadsheet->getSheet($this->sheetIndex);
- }
-
- // Construct HTML
- $htmlPage = $generateSurroundingHTML ? ('' . PHP_EOL) : '';
-
- return $htmlPage;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/IWriter.php b/vendor/PhpSpreadsheet/Writer/IWriter.php
deleted file mode 100644
index 5129d65..0000000
--- a/vendor/PhpSpreadsheet/Writer/IWriter.php
+++ /dev/null
@@ -1,87 +0,0 @@
-setSpreadsheet($spreadsheet);
-
- $writerPartsArray = [
- 'content' => Content::class,
- 'meta' => Meta::class,
- 'meta_inf' => MetaInf::class,
- 'mimetype' => Mimetype::class,
- 'settings' => Settings::class,
- 'styles' => Styles::class,
- 'thumbnails' => Thumbnails::class,
- ];
-
- foreach ($writerPartsArray as $writer => $class) {
- $this->writerParts[$writer] = new $class($this);
- }
- }
-
- /**
- * Get writer part.
- *
- * @param string $pPartName Writer part name
- *
- * @return null|Ods\WriterPart
- */
- public function getWriterPart($pPartName)
- {
- if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
- return $this->writerParts[strtolower($pPartName)];
- }
-
- return null;
- }
-
- /**
- * Save PhpSpreadsheet to file.
- *
- * @param resource|string $pFilename
- */
- public function save($pFilename): void
- {
- if (!$this->spreadSheet) {
- throw new WriterException('PhpSpreadsheet object unassigned.');
- }
-
- // garbage collect
- $this->spreadSheet->garbageCollect();
-
- $this->openFileHandle($pFilename);
-
- $zip = $this->createZip();
-
- $zip->addFile('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
- $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
- $zip->addFile('content.xml', $this->getWriterPart('content')->write());
- $zip->addFile('meta.xml', $this->getWriterPart('meta')->write());
- $zip->addFile('mimetype', $this->getWriterPart('mimetype')->write());
- $zip->addFile('settings.xml', $this->getWriterPart('settings')->write());
- $zip->addFile('styles.xml', $this->getWriterPart('styles')->write());
-
- // Close file
- try {
- $zip->finish();
- } catch (OverflowException $e) {
- throw new WriterException('Could not close resource.');
- }
-
- $this->maybeCloseFileHandle();
- }
-
- /**
- * Create zip object.
- *
- * @return ZipStream
- */
- private function createZip()
- {
- // Try opening the ZIP file
- if (!is_resource($this->fileHandle)) {
- throw new WriterException('Could not open resource for writing.');
- }
-
- // Create new ZIP stream
- $options = new Archive();
- $options->setEnableZip64(false);
- $options->setOutputStream($this->fileHandle);
-
- return new ZipStream(null, $options);
- }
-
- /**
- * Get Spreadsheet object.
- *
- * @return Spreadsheet
- */
- public function getSpreadsheet()
- {
- if ($this->spreadSheet !== null) {
- return $this->spreadSheet;
- }
-
- throw new WriterException('No PhpSpreadsheet assigned.');
- }
-
- /**
- * Set Spreadsheet object.
- *
- * @param Spreadsheet $spreadsheet PhpSpreadsheet object
- *
- * @return $this
- */
- public function setSpreadsheet(Spreadsheet $spreadsheet)
- {
- $this->spreadSheet = $spreadsheet;
-
- return $this;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Cell/Comment.php b/vendor/PhpSpreadsheet/Writer/Ods/Cell/Comment.php
deleted file mode 100644
index b0829bf..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Cell/Comment.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
- */
-class Comment
-{
- public static function write(XMLWriter $objWriter, Cell $cell): void
- {
- $comments = $cell->getWorksheet()->getComments();
- if (!isset($comments[$cell->getCoordinate()])) {
- return;
- }
- $comment = $comments[$cell->getCoordinate()];
-
- $objWriter->startElement('office:annotation');
- $objWriter->writeAttribute('svg:width', $comment->getWidth());
- $objWriter->writeAttribute('svg:height', $comment->getHeight());
- $objWriter->writeAttribute('svg:x', $comment->getMarginLeft());
- $objWriter->writeAttribute('svg:y', $comment->getMarginTop());
- $objWriter->writeElement('dc:creator', $comment->getAuthor());
- $objWriter->writeElement('text:p', $comment->getText()->getPlainText());
- $objWriter->endElement();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Content.php b/vendor/PhpSpreadsheet/Writer/Ods/Content.php
deleted file mode 100644
index 96e6685..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Content.php
+++ /dev/null
@@ -1,382 +0,0 @@
-
- */
-class Content extends WriterPart
-{
- const NUMBER_COLS_REPEATED_MAX = 1024;
- const NUMBER_ROWS_REPEATED_MAX = 1048576;
- const CELL_STYLE_PREFIX = 'ce';
-
- private $formulaConvertor;
-
- /**
- * Set parent Ods writer.
- */
- public function __construct(Ods $writer)
- {
- parent::__construct($writer);
-
- $this->formulaConvertor = new Formula($this->getParentWriter()->getSpreadsheet()->getDefinedNames());
- }
-
- /**
- * Write content.xml to XML format.
- *
- * @return string XML Output
- */
- public function write()
- {
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8');
-
- // Content
- $objWriter->startElement('office:document-content');
- $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
- $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
- $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
- $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
- $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
- $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
- $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
- $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
- $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
- $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
- $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
- $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
- $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
- $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
- $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
- $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
- $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
- $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
- $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
- $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
- $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
- $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');
- $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
- $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
- $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
- $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
- $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
- $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
- $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');
- $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');
- $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0');
- $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');
- $objWriter->writeAttribute('office:version', '1.2');
-
- $objWriter->writeElement('office:scripts');
- $objWriter->writeElement('office:font-face-decls');
-
- // Styles XF
- $objWriter->startElement('office:automatic-styles');
- $this->writeXfStyles($objWriter, $this->getParentWriter()->getSpreadsheet());
- $objWriter->endElement();
-
- $objWriter->startElement('office:body');
- $objWriter->startElement('office:spreadsheet');
- $objWriter->writeElement('table:calculation-settings');
-
- $this->writeSheets($objWriter);
-
- // Defined names (ranges and formulae)
- (new NamedExpressions($objWriter, $this->getParentWriter()->getSpreadsheet(), $this->formulaConvertor))->write();
-
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write sheets.
- */
- private function writeSheets(XMLWriter $objWriter): void
- {
- $spreadsheet = $this->getParentWriter()->getSpreadsheet(); /** @var Spreadsheet $spreadsheet */
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- $objWriter->startElement('table:table');
- $objWriter->writeAttribute('table:name', $spreadsheet->getSheet($i)->getTitle());
- $objWriter->writeElement('office:forms');
- $objWriter->startElement('table:table-column');
- $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
- $objWriter->endElement();
- $this->writeRows($objWriter, $spreadsheet->getSheet($i));
- $objWriter->endElement();
- }
- }
-
- /**
- * Write rows of the specified sheet.
- */
- private function writeRows(XMLWriter $objWriter, Worksheet $sheet): void
- {
- $numberRowsRepeated = self::NUMBER_ROWS_REPEATED_MAX;
- $span_row = 0;
- $rows = $sheet->getRowIterator();
- while ($rows->valid()) {
- --$numberRowsRepeated;
- $row = $rows->current();
- if ($row->getCellIterator()->valid()) {
- if ($span_row) {
- $objWriter->startElement('table:table-row');
- if ($span_row > 1) {
- $objWriter->writeAttribute('table:number-rows-repeated', $span_row);
- }
- $objWriter->startElement('table:table-cell');
- $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
- $objWriter->endElement();
- $objWriter->endElement();
- $span_row = 0;
- }
- $objWriter->startElement('table:table-row');
- $this->writeCells($objWriter, $row);
- $objWriter->endElement();
- } else {
- ++$span_row;
- }
- $rows->next();
- }
- }
-
- /**
- * Write cells of the specified row.
- */
- private function writeCells(XMLWriter $objWriter, Row $row): void
- {
- $numberColsRepeated = self::NUMBER_COLS_REPEATED_MAX;
- $prevColumn = -1;
- $cells = $row->getCellIterator();
- while ($cells->valid()) {
- /** @var \PhpOffice\PhpSpreadsheet\Cell\Cell $cell */
- $cell = $cells->current();
- $column = Coordinate::columnIndexFromString($cell->getColumn()) - 1;
-
- $this->writeCellSpan($objWriter, $column, $prevColumn);
- $objWriter->startElement('table:table-cell');
- $this->writeCellMerge($objWriter, $cell);
-
- // Style XF
- $style = $cell->getXfIndex();
- if ($style !== null) {
- $objWriter->writeAttribute('table:style-name', self::CELL_STYLE_PREFIX . $style);
- }
-
- switch ($cell->getDataType()) {
- case DataType::TYPE_BOOL:
- $objWriter->writeAttribute('office:value-type', 'boolean');
- $objWriter->writeAttribute('office:value', $cell->getValue());
- $objWriter->writeElement('text:p', $cell->getValue());
-
- break;
- case DataType::TYPE_ERROR:
- throw new Exception('Writing of error not implemented yet.');
-
- break;
- case DataType::TYPE_FORMULA:
- $formulaValue = $cell->getValue();
- if ($this->getParentWriter()->getPreCalculateFormulas()) {
- try {
- $formulaValue = $cell->getCalculatedValue();
- } catch (Exception $e) {
- // don't do anything
- }
- }
- $objWriter->writeAttribute('table:formula', $this->formulaConvertor->convertFormula($cell->getValue()));
- if (is_numeric($formulaValue)) {
- $objWriter->writeAttribute('office:value-type', 'float');
- } else {
- $objWriter->writeAttribute('office:value-type', 'string');
- }
- $objWriter->writeAttribute('office:value', $formulaValue);
- $objWriter->writeElement('text:p', $formulaValue);
-
- break;
- case DataType::TYPE_INLINE:
- throw new Exception('Writing of inline not implemented yet.');
-
- break;
- case DataType::TYPE_NUMERIC:
- $objWriter->writeAttribute('office:value-type', 'float');
- $objWriter->writeAttribute('office:value', $cell->getValue());
- $objWriter->writeElement('text:p', $cell->getValue());
-
- break;
- case DataType::TYPE_STRING:
- $objWriter->writeAttribute('office:value-type', 'string');
- $objWriter->writeElement('text:p', $cell->getValue());
-
- break;
- }
- Comment::write($objWriter, $cell);
- $objWriter->endElement();
- $prevColumn = $column;
- $cells->next();
- }
- $numberColsRepeated = $numberColsRepeated - $prevColumn - 1;
- if ($numberColsRepeated > 0) {
- if ($numberColsRepeated > 1) {
- $objWriter->startElement('table:table-cell');
- $objWriter->writeAttribute('table:number-columns-repeated', $numberColsRepeated);
- $objWriter->endElement();
- } else {
- $objWriter->writeElement('table:table-cell');
- }
- }
- }
-
- /**
- * Write span.
- *
- * @param int $curColumn
- * @param int $prevColumn
- */
- private function writeCellSpan(XMLWriter $objWriter, $curColumn, $prevColumn): void
- {
- $diff = $curColumn - $prevColumn - 1;
- if (1 === $diff) {
- $objWriter->writeElement('table:table-cell');
- } elseif ($diff > 1) {
- $objWriter->startElement('table:table-cell');
- $objWriter->writeAttribute('table:number-columns-repeated', $diff);
- $objWriter->endElement();
- }
- }
-
- /**
- * Write XF cell styles.
- */
- private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet): void
- {
- foreach ($spreadsheet->getCellXfCollection() as $style) {
- $writer->startElement('style:style');
- $writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex());
- $writer->writeAttribute('style:family', 'table-cell');
- $writer->writeAttribute('style:parent-style-name', 'Default');
-
- // style:text-properties
-
- // Font
- $writer->startElement('style:text-properties');
-
- $font = $style->getFont();
-
- if ($font->getBold()) {
- $writer->writeAttribute('fo:font-weight', 'bold');
- $writer->writeAttribute('style:font-weight-complex', 'bold');
- $writer->writeAttribute('style:font-weight-asian', 'bold');
- }
-
- if ($font->getItalic()) {
- $writer->writeAttribute('fo:font-style', 'italic');
- }
-
- if ($color = $font->getColor()) {
- $writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB()));
- }
-
- if ($family = $font->getName()) {
- $writer->writeAttribute('fo:font-family', $family);
- }
-
- if ($size = $font->getSize()) {
- $writer->writeAttribute('fo:font-size', sprintf('%.1Fpt', $size));
- }
-
- if ($font->getUnderline() && $font->getUnderline() != Font::UNDERLINE_NONE) {
- $writer->writeAttribute('style:text-underline-style', 'solid');
- $writer->writeAttribute('style:text-underline-width', 'auto');
- $writer->writeAttribute('style:text-underline-color', 'font-color');
-
- switch ($font->getUnderline()) {
- case Font::UNDERLINE_DOUBLE:
- $writer->writeAttribute('style:text-underline-type', 'double');
-
- break;
- case Font::UNDERLINE_SINGLE:
- $writer->writeAttribute('style:text-underline-type', 'single');
-
- break;
- }
- }
-
- $writer->endElement(); // Close style:text-properties
-
- // style:table-cell-properties
-
- $writer->startElement('style:table-cell-properties');
- $writer->writeAttribute('style:rotation-align', 'none');
-
- // Fill
- if ($fill = $style->getFill()) {
- switch ($fill->getFillType()) {
- case Fill::FILL_SOLID:
- $writer->writeAttribute('fo:background-color', sprintf(
- '#%s',
- strtolower($fill->getStartColor()->getRGB())
- ));
-
- break;
- case Fill::FILL_GRADIENT_LINEAR:
- case Fill::FILL_GRADIENT_PATH:
- /// TODO :: To be implemented
- break;
- case Fill::FILL_NONE:
- default:
- }
- }
-
- $writer->endElement(); // Close style:table-cell-properties
-
- // End
-
- $writer->endElement(); // Close style:style
- }
- }
-
- /**
- * Write attributes for merged cell.
- */
- private function writeCellMerge(XMLWriter $objWriter, Cell $cell): void
- {
- if (!$cell->isMergeRangeValueCell()) {
- return;
- }
-
- $mergeRange = Coordinate::splitRange($cell->getMergeRange());
- [$startCell, $endCell] = $mergeRange[0];
- $start = Coordinate::coordinateFromString($startCell);
- $end = Coordinate::coordinateFromString($endCell);
- $columnSpan = Coordinate::columnIndexFromString($end[0]) - Coordinate::columnIndexFromString($start[0]) + 1;
- $rowSpan = $end[1] - $start[1] + 1;
-
- $objWriter->writeAttribute('table:number-columns-spanned', $columnSpan);
- $objWriter->writeAttribute('table:number-rows-spanned', $rowSpan);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Formula.php b/vendor/PhpSpreadsheet/Writer/Ods/Formula.php
deleted file mode 100644
index db766fb..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Formula.php
+++ /dev/null
@@ -1,119 +0,0 @@
-definedNames[] = $definedName->getName();
- }
- }
-
- public function convertFormula(string $formula, string $worksheetName = ''): string
- {
- $formula = $this->convertCellReferences($formula, $worksheetName);
- $formula = $this->convertDefinedNames($formula);
-
- if (substr($formula, 0, 1) !== '=') {
- $formula = '=' . $formula;
- }
-
- return 'of:' . $formula;
- }
-
- private function convertDefinedNames(string $formula): string
- {
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '/mui',
- $formula,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
- $values = array_column($splitRanges[0], 0);
-
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $value = $values[$splitCount];
-
- if (in_array($value, $this->definedNames, true)) {
- $formula = substr($formula, 0, $offset) . '$$' . $value . substr($formula, $offset + $length);
- }
- }
-
- return $formula;
- }
-
- private function convertCellReferences(string $formula, string $worksheetName): string
- {
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
- $formula,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
-
- $worksheets = $splitRanges[2];
- $columns = $splitRanges[6];
- $rows = $splitRanges[7];
-
- // Replace any commas in the formula with semi-colons for Ods
- // If by chance there are commas in worksheet names, then they will be "fixed" again in the loop
- // because we've already extracted worksheet names with our preg_match_all()
- $formula = str_replace(',', ';', $formula);
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $worksheet = $worksheets[$splitCount][0];
- $column = $columns[$splitCount][0];
- $row = $rows[$splitCount][0];
-
- $newRange = '';
- if (empty($worksheet)) {
- if (($offset === 0) || ($formula[$offset - 1] !== ':')) {
- // We need a worksheet
- $worksheet = $worksheetName;
- }
- } else {
- $worksheet = str_replace("''", "'", trim($worksheet, "'"));
- }
- if (!empty($worksheet)) {
- $newRange = "['" . str_replace("'", "''", $worksheet) . "'";
- } elseif (substr($formula, $offset - 1, 1) !== ':') {
- $newRange = '[';
- }
- $newRange .= '.';
-
- if (!empty($column)) {
- $newRange .= $column;
- }
- if (!empty($row)) {
- $newRange .= $row;
- }
- // close the wrapping [] unless this is the first part of a range
- $newRange .= substr($formula, $offset + $length, 1) !== ':' ? ']' : '';
-
- $formula = substr($formula, 0, $offset) . $newRange . substr($formula, $offset + $length);
- }
-
- return $formula;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Meta.php b/vendor/PhpSpreadsheet/Writer/Ods/Meta.php
deleted file mode 100644
index 365221f..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Meta.php
+++ /dev/null
@@ -1,75 +0,0 @@
-getParentWriter()->getSpreadsheet();
- }
-
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8');
-
- // Meta
- $objWriter->startElement('office:document-meta');
-
- $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
- $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
- $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
- $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
- $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
- $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
- $objWriter->writeAttribute('office:version', '1.2');
-
- $objWriter->startElement('office:meta');
-
- $objWriter->writeElement('meta:initial-creator', $spreadsheet->getProperties()->getCreator());
- $objWriter->writeElement('dc:creator', $spreadsheet->getProperties()->getCreator());
- $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $spreadsheet->getProperties()->getCreated()));
- $objWriter->writeElement('dc:date', date(DATE_W3C, $spreadsheet->getProperties()->getCreated()));
- $objWriter->writeElement('dc:title', $spreadsheet->getProperties()->getTitle());
- $objWriter->writeElement('dc:description', $spreadsheet->getProperties()->getDescription());
- $objWriter->writeElement('dc:subject', $spreadsheet->getProperties()->getSubject());
- $keywords = explode(' ', $spreadsheet->getProperties()->getKeywords());
- foreach ($keywords as $keyword) {
- $objWriter->writeElement('meta:keyword', $keyword);
- }
-
- //
- $objWriter->startElement('meta:user-defined');
- $objWriter->writeAttribute('meta:name', 'Company');
- $objWriter->writeRaw($spreadsheet->getProperties()->getCompany());
- $objWriter->endElement();
-
- $objWriter->startElement('meta:user-defined');
- $objWriter->writeAttribute('meta:name', 'category');
- $objWriter->writeRaw($spreadsheet->getProperties()->getCategory());
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/MetaInf.php b/vendor/PhpSpreadsheet/Writer/Ods/MetaInf.php
deleted file mode 100644
index c9085cf..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/MetaInf.php
+++ /dev/null
@@ -1,60 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8');
-
- // Manifest
- $objWriter->startElement('manifest:manifest');
- $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0');
- $objWriter->writeAttribute('manifest:version', '1.2');
-
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', '/');
- $objWriter->writeAttribute('manifest:version', '1.2');
- $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.spreadsheet');
- $objWriter->endElement();
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', 'meta.xml');
- $objWriter->writeAttribute('manifest:media-type', 'text/xml');
- $objWriter->endElement();
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', 'settings.xml');
- $objWriter->writeAttribute('manifest:media-type', 'text/xml');
- $objWriter->endElement();
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', 'content.xml');
- $objWriter->writeAttribute('manifest:media-type', 'text/xml');
- $objWriter->endElement();
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', 'Thumbnails/thumbnail.png');
- $objWriter->writeAttribute('manifest:media-type', 'image/png');
- $objWriter->endElement();
- $objWriter->startElement('manifest:file-entry');
- $objWriter->writeAttribute('manifest:full-path', 'styles.xml');
- $objWriter->writeAttribute('manifest:media-type', 'text/xml');
- $objWriter->endElement();
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Mimetype.php b/vendor/PhpSpreadsheet/Writer/Ods/Mimetype.php
deleted file mode 100644
index 4aac368..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Mimetype.php
+++ /dev/null
@@ -1,20 +0,0 @@
-objWriter = $objWriter;
- $this->spreadsheet = $spreadsheet;
- $this->formulaConvertor = $formulaConvertor;
- }
-
- public function write(): void
- {
- $this->objWriter->startElement('table:named-expressions');
- $this->writeExpressions();
- $this->objWriter->endElement();
- }
-
- private function writeExpressions(): void
- {
- $definedNames = $this->spreadsheet->getDefinedNames();
-
- foreach ($definedNames as $definedName) {
- if ($definedName->isFormula()) {
- $this->objWriter->startElement('table:named-expression');
- $this->writeNamedFormula($definedName, $this->spreadsheet->getActiveSheet());
- } else {
- $this->objWriter->startElement('table:named-range');
- $this->writeNamedRange($definedName);
- }
-
- $this->objWriter->endElement();
- }
- }
-
- private function writeNamedFormula(DefinedName $definedName, Worksheet $defaultWorksheet): void
- {
- $this->objWriter->writeAttribute('table:name', $definedName->getName());
- $this->objWriter->writeAttribute(
- 'table:expression',
- $this->formulaConvertor->convertFormula($definedName->getValue(), $definedName->getWorksheet()->getTitle())
- );
- $this->objWriter->writeAttribute('table:base-cell-address', $this->convertAddress(
- $definedName,
- "'" . (($definedName->getWorksheet() !== null) ? $definedName->getWorksheet()->getTitle() : $defaultWorksheet->getTitle()) . "'!\$A\$1"
- ));
- }
-
- private function writeNamedRange(DefinedName $definedName): void
- {
- $this->objWriter->writeAttribute('table:name', $definedName->getName());
- $this->objWriter->writeAttribute('table:base-cell-address', $this->convertAddress(
- $definedName,
- "'" . $definedName->getWorksheet()->getTitle() . "'!\$A\$1"
- ));
- $this->objWriter->writeAttribute('table:cell-range-address', $this->convertAddress($definedName, $definedName->getValue()));
- }
-
- private function convertAddress(DefinedName $definedName, string $address): string
- {
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
- $address,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
-
- $worksheets = $splitRanges[2];
- $columns = $splitRanges[6];
- $rows = $splitRanges[7];
-
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $worksheet = $worksheets[$splitCount][0];
- $column = $columns[$splitCount][0];
- $row = $rows[$splitCount][0];
-
- $newRange = '';
- if (empty($worksheet)) {
- if (($offset === 0) || ($address[$offset - 1] !== ':')) {
- // We need a worksheet
- $worksheet = $definedName->getWorksheet()->getTitle();
- }
- } else {
- $worksheet = str_replace("''", "'", trim($worksheet, "'"));
- }
- if (!empty($worksheet)) {
- $newRange = "'" . str_replace("'", "''", $worksheet) . "'.";
- }
-
- if (!empty($column)) {
- $newRange .= $column;
- }
- if (!empty($row)) {
- $newRange .= $row;
- }
-
- $address = substr($address, 0, $offset) . $newRange . substr($address, $offset + $length);
- }
-
- if (substr($address, 0, 1) === '=') {
- $address = substr($address, 1);
- }
-
- return $address;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Settings.php b/vendor/PhpSpreadsheet/Writer/Ods/Settings.php
deleted file mode 100644
index d458e8c..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Settings.php
+++ /dev/null
@@ -1,52 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8');
-
- // Settings
- $objWriter->startElement('office:document-settings');
- $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
- $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
- $objWriter->writeAttribute('xmlns:config', 'urn:oasis:names:tc:opendocument:xmlns:config:1.0');
- $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
- $objWriter->writeAttribute('office:version', '1.2');
-
- $objWriter->startElement('office:settings');
- $objWriter->startElement('config:config-item-set');
- $objWriter->writeAttribute('config:name', 'ooo:view-settings');
- $objWriter->startElement('config:config-item-map-indexed');
- $objWriter->writeAttribute('config:name', 'Views');
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->startElement('config:config-item-set');
- $objWriter->writeAttribute('config:name', 'ooo:configuration-settings');
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Styles.php b/vendor/PhpSpreadsheet/Writer/Ods/Styles.php
deleted file mode 100644
index 7ba7eba..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Styles.php
+++ /dev/null
@@ -1,68 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8');
-
- // Content
- $objWriter->startElement('office:document-styles');
- $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
- $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
- $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
- $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
- $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
- $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
- $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
- $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
- $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
- $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
- $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
- $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
- $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
- $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
- $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
- $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
- $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
- $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
- $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
- $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
- $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
- $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
- $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
- $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
- $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
- $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');
- $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');
- $objWriter->writeAttribute('office:version', '1.2');
-
- $objWriter->writeElement('office:font-face-decls');
- $objWriter->writeElement('office:styles');
- $objWriter->writeElement('office:automatic-styles');
- $objWriter->writeElement('office:master-styles');
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Ods/Thumbnails.php b/vendor/PhpSpreadsheet/Writer/Ods/Thumbnails.php
deleted file mode 100644
index dfab065..0000000
--- a/vendor/PhpSpreadsheet/Writer/Ods/Thumbnails.php
+++ /dev/null
@@ -1,20 +0,0 @@
-parentWriter;
- }
-
- /**
- * Set parent Ods writer.
- */
- public function __construct(Ods $writer)
- {
- $this->parentWriter = $writer;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Pdf.php b/vendor/PhpSpreadsheet/Writer/Pdf.php
deleted file mode 100644
index 8722045..0000000
--- a/vendor/PhpSpreadsheet/Writer/Pdf.php
+++ /dev/null
@@ -1,253 +0,0 @@
- 'LETTER', // (8.5 in. by 11 in.)
- PageSetup::PAPERSIZE_LETTER_SMALL => 'LETTER', // (8.5 in. by 11 in.)
- PageSetup::PAPERSIZE_TABLOID => [792.00, 1224.00], // (11 in. by 17 in.)
- PageSetup::PAPERSIZE_LEDGER => [1224.00, 792.00], // (17 in. by 11 in.)
- PageSetup::PAPERSIZE_LEGAL => 'LEGAL', // (8.5 in. by 14 in.)
- PageSetup::PAPERSIZE_STATEMENT => [396.00, 612.00], // (5.5 in. by 8.5 in.)
- PageSetup::PAPERSIZE_EXECUTIVE => 'EXECUTIVE', // (7.25 in. by 10.5 in.)
- PageSetup::PAPERSIZE_A3 => 'A3', // (297 mm by 420 mm)
- PageSetup::PAPERSIZE_A4 => 'A4', // (210 mm by 297 mm)
- PageSetup::PAPERSIZE_A4_SMALL => 'A4', // (210 mm by 297 mm)
- PageSetup::PAPERSIZE_A5 => 'A5', // (148 mm by 210 mm)
- PageSetup::PAPERSIZE_B4 => 'B4', // (250 mm by 353 mm)
- PageSetup::PAPERSIZE_B5 => 'B5', // (176 mm by 250 mm)
- PageSetup::PAPERSIZE_FOLIO => 'FOLIO', // (8.5 in. by 13 in.)
- PageSetup::PAPERSIZE_QUARTO => [609.45, 779.53], // (215 mm by 275 mm)
- PageSetup::PAPERSIZE_STANDARD_1 => [720.00, 1008.00], // (10 in. by 14 in.)
- PageSetup::PAPERSIZE_STANDARD_2 => [792.00, 1224.00], // (11 in. by 17 in.)
- PageSetup::PAPERSIZE_NOTE => 'LETTER', // (8.5 in. by 11 in.)
- PageSetup::PAPERSIZE_NO9_ENVELOPE => [279.00, 639.00], // (3.875 in. by 8.875 in.)
- PageSetup::PAPERSIZE_NO10_ENVELOPE => [297.00, 684.00], // (4.125 in. by 9.5 in.)
- PageSetup::PAPERSIZE_NO11_ENVELOPE => [324.00, 747.00], // (4.5 in. by 10.375 in.)
- PageSetup::PAPERSIZE_NO12_ENVELOPE => [342.00, 792.00], // (4.75 in. by 11 in.)
- PageSetup::PAPERSIZE_NO14_ENVELOPE => [360.00, 828.00], // (5 in. by 11.5 in.)
- PageSetup::PAPERSIZE_C => [1224.00, 1584.00], // (17 in. by 22 in.)
- PageSetup::PAPERSIZE_D => [1584.00, 2448.00], // (22 in. by 34 in.)
- PageSetup::PAPERSIZE_E => [2448.00, 3168.00], // (34 in. by 44 in.)
- PageSetup::PAPERSIZE_DL_ENVELOPE => [311.81, 623.62], // (110 mm by 220 mm)
- PageSetup::PAPERSIZE_C5_ENVELOPE => 'C5', // (162 mm by 229 mm)
- PageSetup::PAPERSIZE_C3_ENVELOPE => 'C3', // (324 mm by 458 mm)
- PageSetup::PAPERSIZE_C4_ENVELOPE => 'C4', // (229 mm by 324 mm)
- PageSetup::PAPERSIZE_C6_ENVELOPE => 'C6', // (114 mm by 162 mm)
- PageSetup::PAPERSIZE_C65_ENVELOPE => [323.15, 649.13], // (114 mm by 229 mm)
- PageSetup::PAPERSIZE_B4_ENVELOPE => 'B4', // (250 mm by 353 mm)
- PageSetup::PAPERSIZE_B5_ENVELOPE => 'B5', // (176 mm by 250 mm)
- PageSetup::PAPERSIZE_B6_ENVELOPE => [498.90, 354.33], // (176 mm by 125 mm)
- PageSetup::PAPERSIZE_ITALY_ENVELOPE => [311.81, 651.97], // (110 mm by 230 mm)
- PageSetup::PAPERSIZE_MONARCH_ENVELOPE => [279.00, 540.00], // (3.875 in. by 7.5 in.)
- PageSetup::PAPERSIZE_6_3_4_ENVELOPE => [261.00, 468.00], // (3.625 in. by 6.5 in.)
- PageSetup::PAPERSIZE_US_STANDARD_FANFOLD => [1071.00, 792.00], // (14.875 in. by 11 in.)
- PageSetup::PAPERSIZE_GERMAN_STANDARD_FANFOLD => [612.00, 864.00], // (8.5 in. by 12 in.)
- PageSetup::PAPERSIZE_GERMAN_LEGAL_FANFOLD => 'FOLIO', // (8.5 in. by 13 in.)
- PageSetup::PAPERSIZE_ISO_B4 => 'B4', // (250 mm by 353 mm)
- PageSetup::PAPERSIZE_JAPANESE_DOUBLE_POSTCARD => [566.93, 419.53], // (200 mm by 148 mm)
- PageSetup::PAPERSIZE_STANDARD_PAPER_1 => [648.00, 792.00], // (9 in. by 11 in.)
- PageSetup::PAPERSIZE_STANDARD_PAPER_2 => [720.00, 792.00], // (10 in. by 11 in.)
- PageSetup::PAPERSIZE_STANDARD_PAPER_3 => [1080.00, 792.00], // (15 in. by 11 in.)
- PageSetup::PAPERSIZE_INVITE_ENVELOPE => [623.62, 623.62], // (220 mm by 220 mm)
- PageSetup::PAPERSIZE_LETTER_EXTRA_PAPER => [667.80, 864.00], // (9.275 in. by 12 in.)
- PageSetup::PAPERSIZE_LEGAL_EXTRA_PAPER => [667.80, 1080.00], // (9.275 in. by 15 in.)
- PageSetup::PAPERSIZE_TABLOID_EXTRA_PAPER => [841.68, 1296.00], // (11.69 in. by 18 in.)
- PageSetup::PAPERSIZE_A4_EXTRA_PAPER => [668.98, 912.76], // (236 mm by 322 mm)
- PageSetup::PAPERSIZE_LETTER_TRANSVERSE_PAPER => [595.80, 792.00], // (8.275 in. by 11 in.)
- PageSetup::PAPERSIZE_A4_TRANSVERSE_PAPER => 'A4', // (210 mm by 297 mm)
- PageSetup::PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER => [667.80, 864.00], // (9.275 in. by 12 in.)
- PageSetup::PAPERSIZE_SUPERA_SUPERA_A4_PAPER => [643.46, 1009.13], // (227 mm by 356 mm)
- PageSetup::PAPERSIZE_SUPERB_SUPERB_A3_PAPER => [864.57, 1380.47], // (305 mm by 487 mm)
- PageSetup::PAPERSIZE_LETTER_PLUS_PAPER => [612.00, 913.68], // (8.5 in. by 12.69 in.)
- PageSetup::PAPERSIZE_A4_PLUS_PAPER => [595.28, 935.43], // (210 mm by 330 mm)
- PageSetup::PAPERSIZE_A5_TRANSVERSE_PAPER => 'A5', // (148 mm by 210 mm)
- PageSetup::PAPERSIZE_JIS_B5_TRANSVERSE_PAPER => [515.91, 728.50], // (182 mm by 257 mm)
- PageSetup::PAPERSIZE_A3_EXTRA_PAPER => [912.76, 1261.42], // (322 mm by 445 mm)
- PageSetup::PAPERSIZE_A5_EXTRA_PAPER => [493.23, 666.14], // (174 mm by 235 mm)
- PageSetup::PAPERSIZE_ISO_B5_EXTRA_PAPER => [569.76, 782.36], // (201 mm by 276 mm)
- PageSetup::PAPERSIZE_A2_PAPER => 'A2', // (420 mm by 594 mm)
- PageSetup::PAPERSIZE_A3_TRANSVERSE_PAPER => 'A3', // (297 mm by 420 mm)
- PageSetup::PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER => [912.76, 1261.42], // (322 mm by 445 mm)
- ];
-
- /**
- * Create a new PDF Writer instance.
- *
- * @param Spreadsheet $spreadsheet Spreadsheet object
- */
- public function __construct(Spreadsheet $spreadsheet)
- {
- parent::__construct($spreadsheet);
- //$this->setUseInlineCss(true);
- $this->tempDir = File::sysGetTempDir() . '/phpsppdf';
- $this->isPdf = true;
- }
-
- /**
- * Get Font.
- *
- * @return string
- */
- public function getFont()
- {
- return $this->font;
- }
-
- /**
- * Set font. Examples:
- * 'arialunicid0-chinese-simplified'
- * 'arialunicid0-chinese-traditional'
- * 'arialunicid0-korean'
- * 'arialunicid0-japanese'.
- *
- * @param string $fontName
- *
- * @return $this
- */
- public function setFont($fontName)
- {
- $this->font = $fontName;
-
- return $this;
- }
-
- /**
- * Get Paper Size.
- *
- * @return int
- */
- public function getPaperSize()
- {
- return $this->paperSize;
- }
-
- /**
- * Set Paper Size.
- *
- * @param string $pValue Paper size see PageSetup::PAPERSIZE_*
- *
- * @return self
- */
- public function setPaperSize($pValue)
- {
- $this->paperSize = $pValue;
-
- return $this;
- }
-
- /**
- * Get Orientation.
- *
- * @return string
- */
- public function getOrientation()
- {
- return $this->orientation;
- }
-
- /**
- * Set Orientation.
- *
- * @param string $pValue Page orientation see PageSetup::ORIENTATION_*
- *
- * @return self
- */
- public function setOrientation($pValue)
- {
- $this->orientation = $pValue;
-
- return $this;
- }
-
- /**
- * Get temporary storage directory.
- *
- * @return string
- */
- public function getTempDir()
- {
- return $this->tempDir;
- }
-
- /**
- * Set temporary storage directory.
- *
- * @param string $pValue Temporary storage directory
- *
- * @return self
- */
- public function setTempDir($pValue)
- {
- if (is_dir($pValue)) {
- $this->tempDir = $pValue;
- } else {
- throw new WriterException("Directory does not exist: $pValue");
- }
-
- return $this;
- }
-
- /**
- * Save Spreadsheet to PDF file, pre-save.
- *
- * @param string $pFilename Name of the file to save as
- *
- * @return resource
- */
- protected function prepareForSave($pFilename)
- {
- // Open file
- $this->openFileHandle($pFilename);
-
- return $this->fileHandle;
- }
-
- /**
- * Save PhpSpreadsheet to PDF file, post-save.
- */
- protected function restoreStateAfterSave(): void
- {
- $this->maybeCloseFileHandle();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Pdf/Dompdf.php b/vendor/PhpSpreadsheet/Writer/Pdf/Dompdf.php
deleted file mode 100644
index 9ae2cce..0000000
--- a/vendor/PhpSpreadsheet/Writer/Pdf/Dompdf.php
+++ /dev/null
@@ -1,72 +0,0 @@
-getSheetIndex() === null) {
- $orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
- } else {
- $orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
- }
-
- $orientation = ($orientation == 'L') ? 'landscape' : 'portrait';
-
- // Override Page Orientation
- if ($this->getOrientation() !== null) {
- $orientation = ($this->getOrientation() == PageSetup::ORIENTATION_DEFAULT)
- ? PageSetup::ORIENTATION_PORTRAIT
- : $this->getOrientation();
- }
- // Override Paper Size
- if ($this->getPaperSize() !== null) {
- $printPaperSize = $this->getPaperSize();
- }
-
- if (isset(self::$paperSizes[$printPaperSize])) {
- $paperSize = self::$paperSizes[$printPaperSize];
- }
-
- // Create PDF
- $pdf = $this->createExternalWriterInstance();
- $pdf->setPaper(strtolower($paperSize), $orientation);
-
- $pdf->loadHtml($this->generateHTMLAll());
- $pdf->render();
-
- // Write to file
- fwrite($fileHandle, $pdf->output());
-
- parent::restoreStateAfterSave();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Pdf/Mpdf.php b/vendor/PhpSpreadsheet/Writer/Pdf/Mpdf.php
deleted file mode 100644
index 75e0010..0000000
--- a/vendor/PhpSpreadsheet/Writer/Pdf/Mpdf.php
+++ /dev/null
@@ -1,106 +0,0 @@
-getSheetIndex()) {
- $orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
- } else {
- $orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
- }
- $this->setOrientation($orientation);
-
- // Override Page Orientation
- if (null !== $this->getOrientation()) {
- $orientation = ($this->getOrientation() == PageSetup::ORIENTATION_DEFAULT)
- ? PageSetup::ORIENTATION_PORTRAIT
- : $this->getOrientation();
- }
- $orientation = strtoupper($orientation);
-
- // Override Paper Size
- if (null !== $this->getPaperSize()) {
- $printPaperSize = $this->getPaperSize();
- }
-
- if (isset(self::$paperSizes[$printPaperSize])) {
- $paperSize = self::$paperSizes[$printPaperSize];
- }
-
- // Create PDF
- $config = ['tempDir' => $this->tempDir . '/mpdf'];
- $pdf = $this->createExternalWriterInstance($config);
- $ortmp = $orientation;
- $pdf->_setPageSize(strtoupper($paperSize), $ortmp);
- $pdf->DefOrientation = $orientation;
- $pdf->AddPageByArray([
- 'orientation' => $orientation,
- 'margin-left' => $this->inchesToMm($this->spreadsheet->getActiveSheet()->getPageMargins()->getLeft()),
- 'margin-right' => $this->inchesToMm($this->spreadsheet->getActiveSheet()->getPageMargins()->getRight()),
- 'margin-top' => $this->inchesToMm($this->spreadsheet->getActiveSheet()->getPageMargins()->getTop()),
- 'margin-bottom' => $this->inchesToMm($this->spreadsheet->getActiveSheet()->getPageMargins()->getBottom()),
- ]);
-
- // Document info
- $pdf->SetTitle($this->spreadsheet->getProperties()->getTitle());
- $pdf->SetAuthor($this->spreadsheet->getProperties()->getCreator());
- $pdf->SetSubject($this->spreadsheet->getProperties()->getSubject());
- $pdf->SetKeywords($this->spreadsheet->getProperties()->getKeywords());
- $pdf->SetCreator($this->spreadsheet->getProperties()->getCreator());
-
- $html = $this->generateHTMLAll();
- foreach (\array_chunk(\explode(PHP_EOL, $html), 1000) as $lines) {
- $pdf->WriteHTML(\implode(PHP_EOL, $lines));
- }
-
- // Write to file
- fwrite($fileHandle, $pdf->Output('', 'S'));
-
- parent::restoreStateAfterSave();
- }
-
- /**
- * Convert inches to mm.
- *
- * @param float $inches
- *
- * @return float
- */
- private function inchesToMm($inches)
- {
- return $inches * 25.4;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Pdf/Tcpdf.php b/vendor/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
deleted file mode 100644
index 7530b1e..0000000
--- a/vendor/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
+++ /dev/null
@@ -1,104 +0,0 @@
-setUseInlineCss(true);
- }
-
- /**
- * Gets the implementation of external PDF library that should be used.
- *
- * @param string $orientation Page orientation
- * @param string $unit Unit measure
- * @param string $paperSize Paper size
- *
- * @return \TCPDF implementation
- */
- protected function createExternalWriterInstance($orientation, $unit, $paperSize)
- {
- return new \TCPDF($orientation, $unit, $paperSize);
- }
-
- /**
- * Save Spreadsheet to file.
- *
- * @param string $pFilename Name of the file to save as
- */
- public function save($pFilename): void
- {
- $fileHandle = parent::prepareForSave($pFilename);
-
- // Default PDF paper size
- $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.)
-
- // Check for paper size and page orientation
- if ($this->getSheetIndex() === null) {
- $orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
- $printMargins = $this->spreadsheet->getSheet(0)->getPageMargins();
- } else {
- $orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
- == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
- $printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
- $printMargins = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageMargins();
- }
-
- // Override Page Orientation
- if ($this->getOrientation() !== null) {
- $orientation = ($this->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE)
- ? 'L'
- : 'P';
- }
- // Override Paper Size
- if ($this->getPaperSize() !== null) {
- $printPaperSize = $this->getPaperSize();
- }
-
- if (isset(self::$paperSizes[$printPaperSize])) {
- $paperSize = self::$paperSizes[$printPaperSize];
- }
-
- // Create PDF
- $pdf = $this->createExternalWriterInstance($orientation, 'pt', $paperSize);
- $pdf->setFontSubsetting(false);
- // Set margins, converting inches to points (using 72 dpi)
- $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72);
- $pdf->SetAutoPageBreak(true, $printMargins->getBottom() * 72);
-
- $pdf->setPrintHeader(false);
- $pdf->setPrintFooter(false);
-
- $pdf->AddPage();
-
- // Set the appropriate font
- $pdf->SetFont($this->getFont());
- $pdf->writeHTML($this->generateHTMLAll());
-
- // Document info
- $pdf->SetTitle($this->spreadsheet->getProperties()->getTitle());
- $pdf->SetAuthor($this->spreadsheet->getProperties()->getCreator());
- $pdf->SetSubject($this->spreadsheet->getProperties()->getSubject());
- $pdf->SetKeywords($this->spreadsheet->getProperties()->getKeywords());
- $pdf->SetCreator($this->spreadsheet->getProperties()->getCreator());
-
- // Write to file
- fwrite($fileHandle, $pdf->output($pFilename, 'S'));
-
- parent::restoreStateAfterSave();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls.php b/vendor/PhpSpreadsheet/Writer/Xls.php
deleted file mode 100644
index c7c2e7d..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls.php
+++ /dev/null
@@ -1,901 +0,0 @@
-spreadsheet = $spreadsheet;
-
- $this->parser = new Xls\Parser($spreadsheet);
- }
-
- /**
- * Save Spreadsheet to file.
- *
- * @param resource|string $pFilename
- */
- public function save($pFilename): void
- {
- // garbage collect
- $this->spreadsheet->garbageCollect();
-
- $saveDebugLog = Calculation::getInstance($this->spreadsheet)->getDebugLog()->getWriteDebugLog();
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog(false);
- $saveDateReturnType = Functions::getReturnDateType();
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
-
- // initialize colors array
- $this->colors = [];
-
- // Initialise workbook writer
- $this->writerWorkbook = new Xls\Workbook($this->spreadsheet, $this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser);
-
- // Initialise worksheet writers
- $countSheets = $this->spreadsheet->getSheetCount();
- for ($i = 0; $i < $countSheets; ++$i) {
- $this->writerWorksheets[$i] = new Xls\Worksheet($this->strTotal, $this->strUnique, $this->strTable, $this->colors, $this->parser, $this->preCalculateFormulas, $this->spreadsheet->getSheet($i));
- }
-
- // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.
- $this->buildWorksheetEschers();
- $this->buildWorkbookEscher();
-
- // add 15 identical cell style Xfs
- // for now, we use the first cellXf instead of cellStyleXf
- $cellXfCollection = $this->spreadsheet->getCellXfCollection();
- for ($i = 0; $i < 15; ++$i) {
- $this->writerWorkbook->addXfWriter($cellXfCollection[0], true);
- }
-
- // add all the cell Xfs
- foreach ($this->spreadsheet->getCellXfCollection() as $style) {
- $this->writerWorkbook->addXfWriter($style, false);
- }
-
- // add fonts from rich text eleemnts
- for ($i = 0; $i < $countSheets; ++$i) {
- foreach ($this->writerWorksheets[$i]->phpSheet->getCoordinates() as $coordinate) {
- $cell = $this->writerWorksheets[$i]->phpSheet->getCell($coordinate);
- $cVal = $cell->getValue();
- if ($cVal instanceof RichText) {
- $elements = $cVal->getRichTextElements();
- foreach ($elements as $element) {
- if ($element instanceof Run) {
- $font = $element->getFont();
- $this->writerWorksheets[$i]->fontHashIndex[$font->getHashCode()] = $this->writerWorkbook->addFont($font);
- }
- }
- }
- }
- }
-
- // initialize OLE file
- $workbookStreamName = 'Workbook';
- $OLE = new File(OLE::ascToUcs($workbookStreamName));
-
- // Write the worksheet streams before the global workbook stream,
- // because the byte sizes of these are needed in the global workbook stream
- $worksheetSizes = [];
- for ($i = 0; $i < $countSheets; ++$i) {
- $this->writerWorksheets[$i]->close();
- $worksheetSizes[] = $this->writerWorksheets[$i]->_datasize;
- }
-
- // add binary data for global workbook stream
- $OLE->append($this->writerWorkbook->writeWorkbook($worksheetSizes));
-
- // add binary data for sheet streams
- for ($i = 0; $i < $countSheets; ++$i) {
- $OLE->append($this->writerWorksheets[$i]->getData());
- }
-
- $this->documentSummaryInformation = $this->writeDocumentSummaryInformation();
- // initialize OLE Document Summary Information
- if (isset($this->documentSummaryInformation) && !empty($this->documentSummaryInformation)) {
- $OLE_DocumentSummaryInformation = new File(OLE::ascToUcs(chr(5) . 'DocumentSummaryInformation'));
- $OLE_DocumentSummaryInformation->append($this->documentSummaryInformation);
- }
-
- $this->summaryInformation = $this->writeSummaryInformation();
- // initialize OLE Summary Information
- if (isset($this->summaryInformation) && !empty($this->summaryInformation)) {
- $OLE_SummaryInformation = new File(OLE::ascToUcs(chr(5) . 'SummaryInformation'));
- $OLE_SummaryInformation->append($this->summaryInformation);
- }
-
- // define OLE Parts
- $arrRootData = [$OLE];
- // initialize OLE Properties file
- if (isset($OLE_SummaryInformation)) {
- $arrRootData[] = $OLE_SummaryInformation;
- }
- // initialize OLE Extended Properties file
- if (isset($OLE_DocumentSummaryInformation)) {
- $arrRootData[] = $OLE_DocumentSummaryInformation;
- }
-
- $root = new Root(time(), time(), $arrRootData);
- // save the OLE file
- $this->openFileHandle($pFilename);
- $root->save($this->fileHandle);
- $this->maybeCloseFileHandle();
-
- Functions::setReturnDateType($saveDateReturnType);
- Calculation::getInstance($this->spreadsheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
- }
-
- /**
- * Build the Worksheet Escher objects.
- */
- private function buildWorksheetEschers(): void
- {
- // 1-based index to BstoreContainer
- $blipIndex = 0;
- $lastReducedSpId = 0;
- $lastSpId = 0;
-
- foreach ($this->spreadsheet->getAllsheets() as $sheet) {
- // sheet index
- $sheetIndex = $sheet->getParent()->getIndex($sheet);
-
- $escher = null;
-
- // check if there are any shapes for this sheet
- $filterRange = $sheet->getAutoFilter()->getRange();
- if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {
- continue;
- }
-
- // create intermediate Escher object
- $escher = new Escher();
-
- // dgContainer
- $dgContainer = new DgContainer();
-
- // set the drawing index (we use sheet index + 1)
- $dgId = $sheet->getParent()->getIndex($sheet) + 1;
- $dgContainer->setDgId($dgId);
- $escher->setDgContainer($dgContainer);
-
- // spgrContainer
- $spgrContainer = new SpgrContainer();
- $dgContainer->setSpgrContainer($spgrContainer);
-
- // add one shape which is the group shape
- $spContainer = new SpContainer();
- $spContainer->setSpgr(true);
- $spContainer->setSpType(0);
- $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);
- $spgrContainer->addChild($spContainer);
-
- // add the shapes
-
- $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet
-
- foreach ($sheet->getDrawingCollection() as $drawing) {
- ++$blipIndex;
-
- ++$countShapes[$sheetIndex];
-
- // add the shape
- $spContainer = new SpContainer();
-
- // set the shape type
- $spContainer->setSpType(0x004B);
- // set the shape flag
- $spContainer->setSpFlag(0x02);
-
- // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
- $reducedSpId = $countShapes[$sheetIndex];
- $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
- $spContainer->setSpId($spId);
-
- // keep track of last reducedSpId
- $lastReducedSpId = $reducedSpId;
-
- // keep track of last spId
- $lastSpId = $spId;
-
- // set the BLIP index
- $spContainer->setOPT(0x4104, $blipIndex);
-
- // set coordinates and offsets, client anchor
- $coordinates = $drawing->getCoordinates();
- $offsetX = $drawing->getOffsetX();
- $offsetY = $drawing->getOffsetY();
- $width = $drawing->getWidth();
- $height = $drawing->getHeight();
-
- $twoAnchor = \PhpOffice\PhpSpreadsheet\Shared\Xls::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height);
-
- $spContainer->setStartCoordinates($twoAnchor['startCoordinates']);
- $spContainer->setStartOffsetX($twoAnchor['startOffsetX']);
- $spContainer->setStartOffsetY($twoAnchor['startOffsetY']);
- $spContainer->setEndCoordinates($twoAnchor['endCoordinates']);
- $spContainer->setEndOffsetX($twoAnchor['endOffsetX']);
- $spContainer->setEndOffsetY($twoAnchor['endOffsetY']);
-
- $spgrContainer->addChild($spContainer);
- }
-
- // AutoFilters
- if (!empty($filterRange)) {
- $rangeBounds = Coordinate::rangeBoundaries($filterRange);
- $iNumColStart = $rangeBounds[0][0];
- $iNumColEnd = $rangeBounds[1][0];
-
- $iInc = $iNumColStart;
- while ($iInc <= $iNumColEnd) {
- ++$countShapes[$sheetIndex];
-
- // create an Drawing Object for the dropdown
- $oDrawing = new BaseDrawing();
- // get the coordinates of drawing
- $cDrawing = Coordinate::stringFromColumnIndex($iInc) . $rangeBounds[0][1];
- $oDrawing->setCoordinates($cDrawing);
- $oDrawing->setWorksheet($sheet);
-
- // add the shape
- $spContainer = new SpContainer();
- // set the shape type
- $spContainer->setSpType(0x00C9);
- // set the shape flag
- $spContainer->setSpFlag(0x01);
-
- // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)
- $reducedSpId = $countShapes[$sheetIndex];
- $spId = $reducedSpId | ($sheet->getParent()->getIndex($sheet) + 1) << 10;
- $spContainer->setSpId($spId);
-
- // keep track of last reducedSpId
- $lastReducedSpId = $reducedSpId;
-
- // keep track of last spId
- $lastSpId = $spId;
-
- $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping
- $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape
- $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest
- $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash
- $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint
-
- // set coordinates and offsets, client anchor
- $endCoordinates = Coordinate::stringFromColumnIndex($iInc);
- $endCoordinates .= $rangeBounds[0][1] + 1;
-
- $spContainer->setStartCoordinates($cDrawing);
- $spContainer->setStartOffsetX(0);
- $spContainer->setStartOffsetY(0);
- $spContainer->setEndCoordinates($endCoordinates);
- $spContainer->setEndOffsetX(0);
- $spContainer->setEndOffsetY(0);
-
- $spgrContainer->addChild($spContainer);
- ++$iInc;
- }
- }
-
- // identifier clusters, used for workbook Escher object
- $this->IDCLs[$dgId] = $lastReducedSpId;
-
- // set last shape index
- $dgContainer->setLastSpId($lastSpId);
-
- // set the Escher object
- $this->writerWorksheets[$sheetIndex]->setEscher($escher);
- }
- }
-
- private function processMemoryDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing, string $renderingFunctionx): void
- {
- switch ($renderingFunctionx) {
- case MemoryDrawing::RENDERING_JPEG:
- $blipType = BSE::BLIPTYPE_JPEG;
- $renderingFunction = 'imagejpeg';
-
- break;
- default:
- $blipType = BSE::BLIPTYPE_PNG;
- $renderingFunction = 'imagepng';
-
- break;
- }
-
- ob_start();
- call_user_func($renderingFunction, $drawing->getImageResource());
- $blipData = ob_get_contents();
- ob_end_clean();
-
- $blip = new Blip();
- $blip->setData($blipData);
-
- $BSE = new BSE();
- $BSE->setBlipType($blipType);
- $BSE->setBlip($blip);
-
- $bstoreContainer->addBSE($BSE);
- }
-
- private function processDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing): void
- {
- $blipData = '';
- $filename = $drawing->getPath();
-
- [$imagesx, $imagesy, $imageFormat] = getimagesize($filename);
-
- switch ($imageFormat) {
- case 1: // GIF, not supported by BIFF8, we convert to PNG
- $blipType = BSE::BLIPTYPE_PNG;
- ob_start();
- imagepng(imagecreatefromgif($filename));
- $blipData = ob_get_contents();
- ob_end_clean();
-
- break;
- case 2: // JPEG
- $blipType = BSE::BLIPTYPE_JPEG;
- $blipData = file_get_contents($filename);
-
- break;
- case 3: // PNG
- $blipType = BSE::BLIPTYPE_PNG;
- $blipData = file_get_contents($filename);
-
- break;
- case 6: // Windows DIB (BMP), we convert to PNG
- $blipType = BSE::BLIPTYPE_PNG;
- ob_start();
- imagepng(SharedDrawing::imagecreatefrombmp($filename));
- $blipData = ob_get_contents();
- ob_end_clean();
-
- break;
- }
- if ($blipData) {
- $blip = new Blip();
- $blip->setData($blipData);
-
- $BSE = new BSE();
- $BSE->setBlipType($blipType);
- $BSE->setBlip($blip);
-
- $bstoreContainer->addBSE($BSE);
- }
- }
-
- private function processBaseDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing): void
- {
- if ($drawing instanceof Drawing) {
- $this->processDrawing($bstoreContainer, $drawing);
- } elseif ($drawing instanceof MemoryDrawing) {
- $this->processMemoryDrawing($bstoreContainer, $drawing, $drawing->getRenderingFunction());
- }
- }
-
- private function checkForDrawings(): bool
- {
- // any drawings in this workbook?
- $found = false;
- foreach ($this->spreadsheet->getAllSheets() as $sheet) {
- if (count($sheet->getDrawingCollection()) > 0) {
- $found = true;
-
- break;
- }
- }
-
- return $found;
- }
-
- /**
- * Build the Escher object corresponding to the MSODRAWINGGROUP record.
- */
- private function buildWorkbookEscher(): void
- {
- // nothing to do if there are no drawings
- if (!$this->checkForDrawings()) {
- return;
- }
-
- // if we reach here, then there are drawings in the workbook
- $escher = new Escher();
-
- // dggContainer
- $dggContainer = new DggContainer();
- $escher->setDggContainer($dggContainer);
-
- // set IDCLs (identifier clusters)
- $dggContainer->setIDCLs($this->IDCLs);
-
- // this loop is for determining maximum shape identifier of all drawing
- $spIdMax = 0;
- $totalCountShapes = 0;
- $countDrawings = 0;
-
- foreach ($this->spreadsheet->getAllsheets() as $sheet) {
- $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet
-
- $addCount = 0;
- foreach ($sheet->getDrawingCollection() as $drawing) {
- $addCount = 1;
- ++$sheetCountShapes;
- ++$totalCountShapes;
-
- $spId = $sheetCountShapes | ($this->spreadsheet->getIndex($sheet) + 1) << 10;
- $spIdMax = max($spId, $spIdMax);
- }
- $countDrawings += $addCount;
- }
-
- $dggContainer->setSpIdMax($spIdMax + 1);
- $dggContainer->setCDgSaved($countDrawings);
- $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing
-
- // bstoreContainer
- $bstoreContainer = new BstoreContainer();
- $dggContainer->setBstoreContainer($bstoreContainer);
-
- // the BSE's (all the images)
- foreach ($this->spreadsheet->getAllsheets() as $sheet) {
- foreach ($sheet->getDrawingCollection() as $drawing) {
- $this->processBaseDrawing($bstoreContainer, $drawing);
- }
- }
-
- // Set the Escher object
- $this->writerWorkbook->setEscher($escher);
- }
-
- /**
- * Build the OLE Part for DocumentSummary Information.
- *
- * @return string
- */
- private function writeDocumentSummaryInformation()
- {
- // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
- $data = pack('v', 0xFFFE);
- // offset: 2; size: 2;
- $data .= pack('v', 0x0000);
- // offset: 4; size: 2; OS version
- $data .= pack('v', 0x0106);
- // offset: 6; size: 2; OS indicator
- $data .= pack('v', 0x0002);
- // offset: 8; size: 16
- $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
- // offset: 24; size: 4; section count
- $data .= pack('V', 0x0001);
-
- // 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
- $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);
- // offset: 44; size: 4; offset of the start
- $data .= pack('V', 0x30);
-
- // SECTION
- $dataSection = [];
- $dataSection_NumProps = 0;
- $dataSection_Summary = '';
- $dataSection_Content = '';
-
- // GKPIDDSI_CODEPAGE: CodePage
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x01],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x02], // 2 byte signed integer
- 'data' => ['data' => 1252],
- ];
- ++$dataSection_NumProps;
-
- // GKPIDDSI_CATEGORY : Category
- $dataProp = $this->spreadsheet->getProperties()->getCategory();
- if ($dataProp) {
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x02],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x1E],
- 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
- ];
- ++$dataSection_NumProps;
- }
- // GKPIDDSI_VERSION :Version of the application that wrote the property storage
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x17],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x03],
- 'data' => ['pack' => 'V', 'data' => 0x000C0000],
- ];
- ++$dataSection_NumProps;
- // GKPIDDSI_SCALE : FALSE
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x0B],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x0B],
- 'data' => ['data' => false],
- ];
- ++$dataSection_NumProps;
- // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x10],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x0B],
- 'data' => ['data' => false],
- ];
- ++$dataSection_NumProps;
- // GKPIDDSI_SHAREDOC : FALSE
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x13],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x0B],
- 'data' => ['data' => false],
- ];
- ++$dataSection_NumProps;
- // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x16],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x0B],
- 'data' => ['data' => false],
- ];
- ++$dataSection_NumProps;
-
- // GKPIDDSI_DOCSPARTS
- // MS-OSHARED p75 (2.3.3.2.2.1)
- // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)
- // cElements
- $dataProp = pack('v', 0x0001);
- $dataProp .= pack('v', 0x0000);
- // array of UnalignedLpstr
- // cch
- $dataProp .= pack('v', 0x000A);
- $dataProp .= pack('v', 0x0000);
- // value
- $dataProp .= 'Worksheet' . chr(0);
-
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x0D],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x101E],
- 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
- ];
- ++$dataSection_NumProps;
-
- // GKPIDDSI_HEADINGPAIR
- // VtVecHeadingPairValue
- // cElements
- $dataProp = pack('v', 0x0002);
- $dataProp .= pack('v', 0x0000);
- // Array of vtHeadingPair
- // vtUnalignedString - headingString
- // stringType
- $dataProp .= pack('v', 0x001E);
- // padding
- $dataProp .= pack('v', 0x0000);
- // UnalignedLpstr
- // cch
- $dataProp .= pack('v', 0x0013);
- $dataProp .= pack('v', 0x0000);
- // value
- $dataProp .= 'Feuilles de calcul';
- // vtUnalignedString - headingParts
- // wType : 0x0003 = 32 bit signed integer
- $dataProp .= pack('v', 0x0300);
- // padding
- $dataProp .= pack('v', 0x0000);
- // value
- $dataProp .= pack('v', 0x0100);
- $dataProp .= pack('v', 0x0000);
- $dataProp .= pack('v', 0x0000);
- $dataProp .= pack('v', 0x0000);
-
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x0C],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x100C],
- 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
- ];
- ++$dataSection_NumProps;
-
- // 4 Section Length
- // 4 Property count
- // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
- $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
- foreach ($dataSection as $dataProp) {
- // Summary
- $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
- // Offset
- $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
- // DataType
- $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
- // Data
- if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
- $dataSection_Content .= pack('V', $dataProp['data']['data']);
-
- $dataSection_Content_Offset += 4 + 4;
- } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
- $dataSection_Content .= pack('V', $dataProp['data']['data']);
-
- $dataSection_Content_Offset += 4 + 4;
- } elseif ($dataProp['type']['data'] == 0x0B) { // Boolean
- $dataSection_Content .= pack('V', (int) $dataProp['data']['data']);
- $dataSection_Content_Offset += 4 + 4;
- } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
- // Null-terminated string
- $dataProp['data']['data'] .= chr(0);
- ++$dataProp['data']['length'];
- // Complete the string with null string for being a %4
- $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4));
- $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
-
- $dataSection_Content .= pack('V', $dataProp['data']['length']);
- $dataSection_Content .= $dataProp['data']['data'];
-
- $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
- // Condition below can never be true
- //} elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
- // $dataSection_Content .= $dataProp['data']['data'];
-
- // $dataSection_Content_Offset += 4 + 8;
- } else {
- $dataSection_Content .= $dataProp['data']['data'];
-
- $dataSection_Content_Offset += 4 + $dataProp['data']['length'];
- }
- }
- // Now $dataSection_Content_Offset contains the size of the content
-
- // section header
- // offset: $secOffset; size: 4; section length
- // + x Size of the content (summary + content)
- $data .= pack('V', $dataSection_Content_Offset);
- // offset: $secOffset+4; size: 4; property count
- $data .= pack('V', $dataSection_NumProps);
- // Section Summary
- $data .= $dataSection_Summary;
- // Section Content
- $data .= $dataSection_Content;
-
- return $data;
- }
-
- private function writeSummaryPropOle(int $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata): void
- {
- if ($dataProp) {
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => $sumdata],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => $typdata], // null-terminated string prepended by dword string length
- 'data' => ['data' => OLE::localDateToOLE($dataProp)],
- ];
- ++$dataSection_NumProps;
- }
- }
-
- private function writeSummaryProp(string $dataProp, int &$dataSection_NumProps, array &$dataSection, int $sumdata, int $typdata): void
- {
- if ($dataProp) {
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => $sumdata],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => $typdata], // null-terminated string prepended by dword string length
- 'data' => ['data' => $dataProp, 'length' => strlen($dataProp)],
- ];
- ++$dataSection_NumProps;
- }
- }
-
- /**
- * Build the OLE Part for Summary Information.
- *
- * @return string
- */
- private function writeSummaryInformation()
- {
- // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)
- $data = pack('v', 0xFFFE);
- // offset: 2; size: 2;
- $data .= pack('v', 0x0000);
- // offset: 4; size: 2; OS version
- $data .= pack('v', 0x0106);
- // offset: 6; size: 2; OS indicator
- $data .= pack('v', 0x0002);
- // offset: 8; size: 16
- $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);
- // offset: 24; size: 4; section count
- $data .= pack('V', 0x0001);
-
- // 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
- $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3);
- // offset: 44; size: 4; offset of the start
- $data .= pack('V', 0x30);
-
- // SECTION
- $dataSection = [];
- $dataSection_NumProps = 0;
- $dataSection_Summary = '';
- $dataSection_Content = '';
-
- // CodePage : CP-1252
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x01],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x02], // 2 byte signed integer
- 'data' => ['data' => 1252],
- ];
- ++$dataSection_NumProps;
-
- $props = $this->spreadsheet->getProperties();
- $this->writeSummaryProp($props->getTitle(), $dataSection_NumProps, $dataSection, 0x02, 0x1e);
- $this->writeSummaryProp($props->getSubject(), $dataSection_NumProps, $dataSection, 0x03, 0x1e);
- $this->writeSummaryProp($props->getCreator(), $dataSection_NumProps, $dataSection, 0x04, 0x1e);
- $this->writeSummaryProp($props->getKeywords(), $dataSection_NumProps, $dataSection, 0x05, 0x1e);
- $this->writeSummaryProp($props->getDescription(), $dataSection_NumProps, $dataSection, 0x06, 0x1e);
- $this->writeSummaryProp($props->getLastModifiedBy(), $dataSection_NumProps, $dataSection, 0x08, 0x1e);
- $this->writeSummaryPropOle($props->getCreated(), $dataSection_NumProps, $dataSection, 0x0c, 0x40);
- $this->writeSummaryPropOle($props->getModified(), $dataSection_NumProps, $dataSection, 0x0d, 0x40);
-
- // Security
- $dataSection[] = [
- 'summary' => ['pack' => 'V', 'data' => 0x13],
- 'offset' => ['pack' => 'V'],
- 'type' => ['pack' => 'V', 'data' => 0x03], // 4 byte signed integer
- 'data' => ['data' => 0x00],
- ];
- ++$dataSection_NumProps;
-
- // 4 Section Length
- // 4 Property count
- // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4))
- $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;
- foreach ($dataSection as $dataProp) {
- // Summary
- $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);
- // Offset
- $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);
- // DataType
- $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);
- // Data
- if ($dataProp['type']['data'] == 0x02) { // 2 byte signed integer
- $dataSection_Content .= pack('V', $dataProp['data']['data']);
-
- $dataSection_Content_Offset += 4 + 4;
- } elseif ($dataProp['type']['data'] == 0x03) { // 4 byte signed integer
- $dataSection_Content .= pack('V', $dataProp['data']['data']);
-
- $dataSection_Content_Offset += 4 + 4;
- } elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
- // Null-terminated string
- $dataProp['data']['data'] .= chr(0);
- ++$dataProp['data']['length'];
- // Complete the string with null string for being a %4
- $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4));
- $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);
-
- $dataSection_Content .= pack('V', $dataProp['data']['length']);
- $dataSection_Content .= $dataProp['data']['data'];
-
- $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);
- } elseif ($dataProp['type']['data'] == 0x40) { // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)
- $dataSection_Content .= $dataProp['data']['data'];
-
- $dataSection_Content_Offset += 4 + 8;
- }
- // Data Type Not Used at the moment
- }
- // Now $dataSection_Content_Offset contains the size of the content
-
- // section header
- // offset: $secOffset; size: 4; section length
- // + x Size of the content (summary + content)
- $data .= pack('V', $dataSection_Content_Offset);
- // offset: $secOffset+4; size: 4; property count
- $data .= pack('V', $dataSection_NumProps);
- // Section Summary
- $data .= $dataSection_Summary;
- // Section Content
- $data .= $dataSection_Content;
-
- return $data;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/BIFFwriter.php b/vendor/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
deleted file mode 100644
index 84e27d0..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
+++ /dev/null
@@ -1,224 +0,0 @@
-
-// *
-// * The majority of this is _NOT_ my code. I simply ported it from the
-// * PERL Spreadsheet::WriteExcel module.
-// *
-// * The author of the Spreadsheet::WriteExcel module is John McNamara
-// *
-// *
-// * I _DO_ maintain this code, and John McNamara has nothing to do with the
-// * porting of this code to PHP. Any questions directly related to this
-// * class library should be directed to me.
-// *
-// * License Information:
-// *
-// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
-// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com
-// *
-// * This library is free software; you can redistribute it and/or
-// * modify it under the terms of the GNU Lesser General Public
-// * License as published by the Free Software Foundation; either
-// * version 2.1 of the License, or (at your option) any later version.
-// *
-// * This library is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// * Lesser General Public License for more details.
-// *
-// * You should have received a copy of the GNU Lesser General Public
-// * License along with this library; if not, write to the Free Software
-// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-// */
-class BIFFwriter
-{
- /**
- * The byte order of this architecture. 0 => little endian, 1 => big endian.
- *
- * @var int
- */
- private static $byteOrder;
-
- /**
- * The string containing the data of the BIFF stream.
- *
- * @var string
- */
- public $_data;
-
- /**
- * The size of the data in bytes. Should be the same as strlen($this->_data).
- *
- * @var int
- */
- public $_datasize;
-
- /**
- * The maximum length for a BIFF record (excluding record header and length field). See addContinue().
- *
- * @var int
- *
- * @see addContinue()
- */
- private $limit = 8224;
-
- /**
- * Constructor.
- */
- public function __construct()
- {
- $this->_data = '';
- $this->_datasize = 0;
- }
-
- /**
- * Determine the byte order and store it as class data to avoid
- * recalculating it for each call to new().
- *
- * @return int
- */
- public static function getByteOrder()
- {
- if (!isset(self::$byteOrder)) {
- // Check if "pack" gives the required IEEE 64bit float
- $teststr = pack('d', 1.2345);
- $number = pack('C8', 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);
- if ($number == $teststr) {
- $byte_order = 0; // Little Endian
- } elseif ($number == strrev($teststr)) {
- $byte_order = 1; // Big Endian
- } else {
- // Give up. I'll fix this in a later version.
- throw new WriterException('Required floating point format not supported on this platform.');
- }
- self::$byteOrder = $byte_order;
- }
-
- return self::$byteOrder;
- }
-
- /**
- * General storage function.
- *
- * @param string $data binary data to append
- */
- protected function append($data): void
- {
- if (strlen($data) - 4 > $this->limit) {
- $data = $this->addContinue($data);
- }
- $this->_data .= $data;
- $this->_datasize += strlen($data);
- }
-
- /**
- * General storage function like append, but returns string instead of modifying $this->_data.
- *
- * @param string $data binary data to write
- *
- * @return string
- */
- public function writeData($data)
- {
- if (strlen($data) - 4 > $this->limit) {
- $data = $this->addContinue($data);
- }
- $this->_datasize += strlen($data);
-
- return $data;
- }
-
- /**
- * Writes Excel BOF record to indicate the beginning of a stream or
- * sub-stream in the BIFF file.
- *
- * @param int $type type of BIFF file to write: 0x0005 Workbook,
- * 0x0010 Worksheet
- */
- protected function storeBof($type): void
- {
- $record = 0x0809; // Record identifier (BIFF5-BIFF8)
- $length = 0x0010;
-
- // by inspection of real files, MS Office Excel 2007 writes the following
- $unknown = pack('VV', 0x000100D1, 0x00000406);
-
- $build = 0x0DBB; // Excel 97
- $year = 0x07CC; // Excel 97
-
- $version = 0x0600; // BIFF8
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvv', $version, $type, $build, $year);
- $this->append($header . $data . $unknown);
- }
-
- /**
- * Writes Excel EOF record to indicate the end of a BIFF stream.
- */
- protected function storeEof(): void
- {
- $record = 0x000A; // Record identifier
- $length = 0x0000; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $this->append($header);
- }
-
- /**
- * Writes Excel EOF record to indicate the end of a BIFF stream.
- */
- public function writeEof()
- {
- $record = 0x000A; // Record identifier
- $length = 0x0000; // Number of bytes to follow
- $header = pack('vv', $record, $length);
-
- return $this->writeData($header);
- }
-
- /**
- * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In
- * Excel 97 the limit is 8228 bytes. Records that are longer than these limits
- * must be split up into CONTINUE blocks.
- *
- * This function takes a long BIFF record and inserts CONTINUE records as
- * necessary.
- *
- * @param string $data The original binary data to be written
- *
- * @return string A very convenient string of continue blocks
- */
- private function addContinue($data)
- {
- $limit = $this->limit;
- $record = 0x003C; // Record identifier
-
- // The first 2080/8224 bytes remain intact. However, we have to change
- // the length field of the record.
- $tmp = substr($data, 0, 2) . pack('v', $limit) . substr($data, 4, $limit);
-
- $header = pack('vv', $record, $limit); // Headers for continue records
-
- // Retrieve chunks of 2080/8224 bytes +4 for the header.
- $data_length = strlen($data);
- for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) {
- $tmp .= $header;
- $tmp .= substr($data, $i, $limit);
- }
-
- // Retrieve the last chunk of data
- $header = pack('vv', $record, strlen($data) - $i);
- $tmp .= $header;
- $tmp .= substr($data, $i);
-
- return $tmp;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Escher.php b/vendor/PhpSpreadsheet/Writer/Xls/Escher.php
deleted file mode 100644
index 1ee2e90..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Escher.php
+++ /dev/null
@@ -1,510 +0,0 @@
-object = $object;
- }
-
- /**
- * Process the object to be written.
- *
- * @return string
- */
- public function close()
- {
- // initialize
- $this->data = '';
-
- switch (get_class($this->object)) {
- case \PhpOffice\PhpSpreadsheet\Shared\Escher::class:
- if ($dggContainer = $this->object->getDggContainer()) {
- $writer = new self($dggContainer);
- $this->data = $writer->close();
- } elseif ($dgContainer = $this->object->getDgContainer()) {
- $writer = new self($dgContainer);
- $this->data = $writer->close();
- $this->spOffsets = $writer->getSpOffsets();
- $this->spTypes = $writer->getSpTypes();
- }
-
- break;
- case DggContainer::class:
- // this is a container record
-
- // initialize
- $innerData = '';
-
- // write the dgg
- $recVer = 0x0;
- $recInstance = 0x0000;
- $recType = 0xF006;
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- // dgg data
- $dggData =
- pack(
- 'VVVV',
- $this->object->getSpIdMax(), // maximum shape identifier increased by one
- $this->object->getCDgSaved() + 1, // number of file identifier clusters increased by one
- $this->object->getCSpSaved(),
- $this->object->getCDgSaved() // count total number of drawings saved
- );
-
- // add file identifier clusters (one per drawing)
- $IDCLs = $this->object->getIDCLs();
-
- foreach ($IDCLs as $dgId => $maxReducedSpId) {
- $dggData .= pack('VV', $dgId, $maxReducedSpId + 1);
- }
-
- $header = pack('vvV', $recVerInstance, $recType, strlen($dggData));
- $innerData .= $header . $dggData;
-
- // write the bstoreContainer
- if ($bstoreContainer = $this->object->getBstoreContainer()) {
- $writer = new self($bstoreContainer);
- $innerData .= $writer->close();
- }
-
- // write the record
- $recVer = 0xF;
- $recInstance = 0x0000;
- $recType = 0xF000;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header . $innerData;
-
- break;
- case BstoreContainer::class:
- // this is a container record
-
- // initialize
- $innerData = '';
-
- // treat the inner data
- if ($BSECollection = $this->object->getBSECollection()) {
- foreach ($BSECollection as $BSE) {
- $writer = new self($BSE);
- $innerData .= $writer->close();
- }
- }
-
- // write the record
- $recVer = 0xF;
- $recInstance = count($this->object->getBSECollection());
- $recType = 0xF001;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header . $innerData;
-
- break;
- case BSE::class:
- // this is a semi-container record
-
- // initialize
- $innerData = '';
-
- // here we treat the inner data
- if ($blip = $this->object->getBlip()) {
- $writer = new self($blip);
- $innerData .= $writer->close();
- }
-
- // initialize
- $data = '';
-
- $btWin32 = $this->object->getBlipType();
- $btMacOS = $this->object->getBlipType();
- $data .= pack('CC', $btWin32, $btMacOS);
-
- $rgbUid = pack('VVVV', 0, 0, 0, 0); // todo
- $data .= $rgbUid;
-
- $tag = 0;
- $size = strlen($innerData);
- $cRef = 1;
- $foDelay = 0; //todo
- $unused1 = 0x0;
- $cbName = 0x0;
- $unused2 = 0x0;
- $unused3 = 0x0;
- $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);
-
- $data .= $innerData;
-
- // write the record
- $recVer = 0x2;
- $recInstance = $this->object->getBlipType();
- $recType = 0xF007;
- $length = strlen($data);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header;
-
- $this->data .= $data;
-
- break;
- case Blip::class:
- // this is an atom record
-
- // write the record
- switch ($this->object->getParent()->getBlipType()) {
- case BSE::BLIPTYPE_JPEG:
- // initialize
- $innerData = '';
-
- $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo
- $innerData .= $rgbUid1;
-
- $tag = 0xFF; // todo
- $innerData .= pack('C', $tag);
-
- $innerData .= $this->object->getData();
-
- $recVer = 0x0;
- $recInstance = 0x46A;
- $recType = 0xF01D;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header;
-
- $this->data .= $innerData;
-
- break;
- case BSE::BLIPTYPE_PNG:
- // initialize
- $innerData = '';
-
- $rgbUid1 = pack('VVVV', 0, 0, 0, 0); // todo
- $innerData .= $rgbUid1;
-
- $tag = 0xFF; // todo
- $innerData .= pack('C', $tag);
-
- $innerData .= $this->object->getData();
-
- $recVer = 0x0;
- $recInstance = 0x6E0;
- $recType = 0xF01E;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header;
-
- $this->data .= $innerData;
-
- break;
- }
-
- break;
- case DgContainer::class:
- // this is a container record
-
- // initialize
- $innerData = '';
-
- // write the dg
- $recVer = 0x0;
- $recInstance = $this->object->getDgId();
- $recType = 0xF008;
- $length = 8;
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- // number of shapes in this drawing (including group shape)
- $countShapes = count($this->object->getSpgrContainer()->getChildren());
- $innerData .= $header . pack('VV', $countShapes, $this->object->getLastSpId());
-
- // write the spgrContainer
- if ($spgrContainer = $this->object->getSpgrContainer()) {
- $writer = new self($spgrContainer);
- $innerData .= $writer->close();
-
- // get the shape offsets relative to the spgrContainer record
- $spOffsets = $writer->getSpOffsets();
- $spTypes = $writer->getSpTypes();
-
- // save the shape offsets relative to dgContainer
- foreach ($spOffsets as &$spOffset) {
- $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)
- }
-
- $this->spOffsets = $spOffsets;
- $this->spTypes = $spTypes;
- }
-
- // write the record
- $recVer = 0xF;
- $recInstance = 0x0000;
- $recType = 0xF002;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header . $innerData;
-
- break;
- case SpgrContainer::class:
- // this is a container record
-
- // initialize
- $innerData = '';
-
- // initialize spape offsets
- $totalSize = 8;
- $spOffsets = [];
- $spTypes = [];
-
- // treat the inner data
- foreach ($this->object->getChildren() as $spContainer) {
- $writer = new self($spContainer);
- $spData = $writer->close();
- $innerData .= $spData;
-
- // save the shape offsets (where new shape records begin)
- $totalSize += strlen($spData);
- $spOffsets[] = $totalSize;
-
- $spTypes = array_merge($spTypes, $writer->getSpTypes());
- }
-
- // write the record
- $recVer = 0xF;
- $recInstance = 0x0000;
- $recType = 0xF003;
- $length = strlen($innerData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header . $innerData;
- $this->spOffsets = $spOffsets;
- $this->spTypes = $spTypes;
-
- break;
- case SpContainer::class:
- // initialize
- $data = '';
-
- // build the data
-
- // write group shape record, if necessary?
- if ($this->object->getSpgr()) {
- $recVer = 0x1;
- $recInstance = 0x0000;
- $recType = 0xF009;
- $length = 0x00000010;
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $data .= $header . pack('VVVV', 0, 0, 0, 0);
- }
- $this->spTypes[] = ($this->object->getSpType());
-
- // write the shape record
- $recVer = 0x2;
- $recInstance = $this->object->getSpType(); // shape type
- $recType = 0xF00A;
- $length = 0x00000008;
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $data .= $header . pack('VV', $this->object->getSpId(), $this->object->getSpgr() ? 0x0005 : 0x0A00);
-
- // the options
- if ($this->object->getOPTCollection()) {
- $optData = '';
-
- $recVer = 0x3;
- $recInstance = count($this->object->getOPTCollection());
- $recType = 0xF00B;
- foreach ($this->object->getOPTCollection() as $property => $value) {
- $optData .= pack('vV', $property, $value);
- }
- $length = strlen($optData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
- $data .= $header . $optData;
- }
-
- // the client anchor
- if ($this->object->getStartCoordinates()) {
- $clientAnchorData = '';
-
- $recVer = 0x0;
- $recInstance = 0x0;
- $recType = 0xF010;
-
- // start coordinates
- [$column, $row] = Coordinate::coordinateFromString($this->object->getStartCoordinates());
- $c1 = Coordinate::columnIndexFromString($column) - 1;
- $r1 = $row - 1;
-
- // start offsetX
- $startOffsetX = $this->object->getStartOffsetX();
-
- // start offsetY
- $startOffsetY = $this->object->getStartOffsetY();
-
- // end coordinates
- [$column, $row] = Coordinate::coordinateFromString($this->object->getEndCoordinates());
- $c2 = Coordinate::columnIndexFromString($column) - 1;
- $r2 = $row - 1;
-
- // end offsetX
- $endOffsetX = $this->object->getEndOffsetX();
-
- // end offsetY
- $endOffsetY = $this->object->getEndOffsetY();
-
- $clientAnchorData = pack('vvvvvvvvv', $this->object->getSpFlag(), $c1, $startOffsetX, $r1, $startOffsetY, $c2, $endOffsetX, $r2, $endOffsetY);
-
- $length = strlen($clientAnchorData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
- $data .= $header . $clientAnchorData;
- }
-
- // the client data, just empty for now
- if (!$this->object->getSpgr()) {
- $clientDataData = '';
-
- $recVer = 0x0;
- $recInstance = 0x0;
- $recType = 0xF011;
-
- $length = strlen($clientDataData);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
- $data .= $header . $clientDataData;
- }
-
- // write the record
- $recVer = 0xF;
- $recInstance = 0x0000;
- $recType = 0xF004;
- $length = strlen($data);
-
- $recVerInstance = $recVer;
- $recVerInstance |= $recInstance << 4;
-
- $header = pack('vvV', $recVerInstance, $recType, $length);
-
- $this->data = $header . $data;
-
- break;
- }
-
- return $this->data;
- }
-
- /**
- * Gets the shape offsets.
- *
- * @return array
- */
- public function getSpOffsets()
- {
- return $this->spOffsets;
- }
-
- /**
- * Gets the shape types.
- *
- * @return array
- */
- public function getSpTypes()
- {
- return $this->spTypes;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Font.php b/vendor/PhpSpreadsheet/Writer/Xls/Font.php
deleted file mode 100644
index 9cb31ea..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Font.php
+++ /dev/null
@@ -1,147 +0,0 @@
-colorIndex = 0x7FFF;
- $this->font = $font;
- }
-
- /**
- * Set the color index.
- *
- * @param int $colorIndex
- */
- public function setColorIndex($colorIndex): void
- {
- $this->colorIndex = $colorIndex;
- }
-
- /**
- * Get font record data.
- *
- * @return string
- */
- public function writeFont()
- {
- $font_outline = 0;
- $font_shadow = 0;
-
- $icv = $this->colorIndex; // Index to color palette
- if ($this->font->getSuperscript()) {
- $sss = 1;
- } elseif ($this->font->getSubscript()) {
- $sss = 2;
- } else {
- $sss = 0;
- }
- $bFamily = 0; // Font family
- $bCharSet = \PhpOffice\PhpSpreadsheet\Shared\Font::getCharsetFromFontName($this->font->getName()); // Character set
-
- $record = 0x31; // Record identifier
- $reserved = 0x00; // Reserved
- $grbit = 0x00; // Font attributes
- if ($this->font->getItalic()) {
- $grbit |= 0x02;
- }
- if ($this->font->getStrikethrough()) {
- $grbit |= 0x08;
- }
- if ($font_outline) {
- $grbit |= 0x10;
- }
- if ($font_shadow) {
- $grbit |= 0x20;
- }
-
- $data = pack(
- 'vvvvvCCCC',
- // Fontsize (in twips)
- $this->font->getSize() * 20,
- $grbit,
- // Colour
- $icv,
- // Font weight
- self::mapBold($this->font->getBold()),
- // Superscript/Subscript
- $sss,
- self::mapUnderline($this->font->getUnderline()),
- $bFamily,
- $bCharSet,
- $reserved
- );
- $data .= StringHelper::UTF8toBIFF8UnicodeShort($this->font->getName());
-
- $length = strlen($data);
- $header = pack('vv', $record, $length);
-
- return $header . $data;
- }
-
- /**
- * Map to BIFF5-BIFF8 codes for bold.
- *
- * @param bool $bold
- *
- * @return int
- */
- private static function mapBold($bold)
- {
- if ($bold) {
- return 0x2BC; // 700 = Bold font weight
- }
-
- return 0x190; // 400 = Normal font weight
- }
-
- /**
- * Map of BIFF2-BIFF8 codes for underline styles.
- *
- * @var array of int
- */
- private static $mapUnderline = [
- \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_NONE => 0x00,
- \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE => 0x01,
- \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE => 0x02,
- \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLEACCOUNTING => 0x21,
- \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLEACCOUNTING => 0x22,
- ];
-
- /**
- * Map underline.
- *
- * @param string $underline
- *
- * @return int
- */
- private static function mapUnderline($underline)
- {
- if (isset(self::$mapUnderline[$underline])) {
- return self::$mapUnderline[$underline];
- }
-
- return 0x00;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Parser.php b/vendor/PhpSpreadsheet/Writer/Xls/Parser.php
deleted file mode 100644
index f89957a..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Parser.php
+++ /dev/null
@@ -1,1483 +0,0 @@
-=,;#()"{}
- const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+';
-
- // Sheet title in quoted form (without surrounding quotes)
- // Invalid sheet title characters cannot occur in the sheet title:
- // *:/\?[] (usual invalid sheet title characters)
- // Single quote is represented as a pair ''
- const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+';
-
- /**
- * The index of the character we are currently looking at.
- *
- * @var int
- */
- public $currentCharacter;
-
- /**
- * The token we are working on.
- *
- * @var string
- */
- public $currentToken;
-
- /**
- * The formula to parse.
- *
- * @var string
- */
- private $formula;
-
- /**
- * The character ahead of the current char.
- *
- * @var string
- */
- public $lookAhead;
-
- /**
- * The parse tree to be generated.
- *
- * @var string
- */
- public $parseTree;
-
- /**
- * Array of external sheets.
- *
- * @var array
- */
- private $externalSheets;
-
- /**
- * Array of sheet references in the form of REF structures.
- *
- * @var array
- */
- public $references;
-
- /**
- * The Excel ptg indices.
- *
- * @var array
- */
- private $ptg = [
- 'ptgExp' => 0x01,
- 'ptgTbl' => 0x02,
- 'ptgAdd' => 0x03,
- 'ptgSub' => 0x04,
- 'ptgMul' => 0x05,
- 'ptgDiv' => 0x06,
- 'ptgPower' => 0x07,
- 'ptgConcat' => 0x08,
- 'ptgLT' => 0x09,
- 'ptgLE' => 0x0A,
- 'ptgEQ' => 0x0B,
- 'ptgGE' => 0x0C,
- 'ptgGT' => 0x0D,
- 'ptgNE' => 0x0E,
- 'ptgIsect' => 0x0F,
- 'ptgUnion' => 0x10,
- 'ptgRange' => 0x11,
- 'ptgUplus' => 0x12,
- 'ptgUminus' => 0x13,
- 'ptgPercent' => 0x14,
- 'ptgParen' => 0x15,
- 'ptgMissArg' => 0x16,
- 'ptgStr' => 0x17,
- 'ptgAttr' => 0x19,
- 'ptgSheet' => 0x1A,
- 'ptgEndSheet' => 0x1B,
- 'ptgErr' => 0x1C,
- 'ptgBool' => 0x1D,
- 'ptgInt' => 0x1E,
- 'ptgNum' => 0x1F,
- 'ptgArray' => 0x20,
- 'ptgFunc' => 0x21,
- 'ptgFuncVar' => 0x22,
- 'ptgName' => 0x23,
- 'ptgRef' => 0x24,
- 'ptgArea' => 0x25,
- 'ptgMemArea' => 0x26,
- 'ptgMemErr' => 0x27,
- 'ptgMemNoMem' => 0x28,
- 'ptgMemFunc' => 0x29,
- 'ptgRefErr' => 0x2A,
- 'ptgAreaErr' => 0x2B,
- 'ptgRefN' => 0x2C,
- 'ptgAreaN' => 0x2D,
- 'ptgMemAreaN' => 0x2E,
- 'ptgMemNoMemN' => 0x2F,
- 'ptgNameX' => 0x39,
- 'ptgRef3d' => 0x3A,
- 'ptgArea3d' => 0x3B,
- 'ptgRefErr3d' => 0x3C,
- 'ptgAreaErr3d' => 0x3D,
- 'ptgArrayV' => 0x40,
- 'ptgFuncV' => 0x41,
- 'ptgFuncVarV' => 0x42,
- 'ptgNameV' => 0x43,
- 'ptgRefV' => 0x44,
- 'ptgAreaV' => 0x45,
- 'ptgMemAreaV' => 0x46,
- 'ptgMemErrV' => 0x47,
- 'ptgMemNoMemV' => 0x48,
- 'ptgMemFuncV' => 0x49,
- 'ptgRefErrV' => 0x4A,
- 'ptgAreaErrV' => 0x4B,
- 'ptgRefNV' => 0x4C,
- 'ptgAreaNV' => 0x4D,
- 'ptgMemAreaNV' => 0x4E,
- 'ptgMemNoMemNV' => 0x4F,
- 'ptgFuncCEV' => 0x58,
- 'ptgNameXV' => 0x59,
- 'ptgRef3dV' => 0x5A,
- 'ptgArea3dV' => 0x5B,
- 'ptgRefErr3dV' => 0x5C,
- 'ptgAreaErr3dV' => 0x5D,
- 'ptgArrayA' => 0x60,
- 'ptgFuncA' => 0x61,
- 'ptgFuncVarA' => 0x62,
- 'ptgNameA' => 0x63,
- 'ptgRefA' => 0x64,
- 'ptgAreaA' => 0x65,
- 'ptgMemAreaA' => 0x66,
- 'ptgMemErrA' => 0x67,
- 'ptgMemNoMemA' => 0x68,
- 'ptgMemFuncA' => 0x69,
- 'ptgRefErrA' => 0x6A,
- 'ptgAreaErrA' => 0x6B,
- 'ptgRefNA' => 0x6C,
- 'ptgAreaNA' => 0x6D,
- 'ptgMemAreaNA' => 0x6E,
- 'ptgMemNoMemNA' => 0x6F,
- 'ptgFuncCEA' => 0x78,
- 'ptgNameXA' => 0x79,
- 'ptgRef3dA' => 0x7A,
- 'ptgArea3dA' => 0x7B,
- 'ptgRefErr3dA' => 0x7C,
- 'ptgAreaErr3dA' => 0x7D,
- ];
-
- /**
- * Thanks to Michael Meeks and Gnumeric for the initial arg values.
- *
- * The following hash was generated by "function_locale.pl" in the distro.
- * Refer to function_locale.pl for non-English function names.
- *
- * The array elements are as follow:
- * ptg: The Excel function ptg code.
- * args: The number of arguments that the function takes:
- * >=0 is a fixed number of arguments.
- * -1 is a variable number of arguments.
- * class: The reference, value or array class of the function args.
- * vol: The function is volatile.
- *
- * @var array
- */
- private $functions = [
- // function ptg args class vol
- 'COUNT' => [0, -1, 0, 0],
- 'IF' => [1, -1, 1, 0],
- 'ISNA' => [2, 1, 1, 0],
- 'ISERROR' => [3, 1, 1, 0],
- 'SUM' => [4, -1, 0, 0],
- 'AVERAGE' => [5, -1, 0, 0],
- 'MIN' => [6, -1, 0, 0],
- 'MAX' => [7, -1, 0, 0],
- 'ROW' => [8, -1, 0, 0],
- 'COLUMN' => [9, -1, 0, 0],
- 'NA' => [10, 0, 0, 0],
- 'NPV' => [11, -1, 1, 0],
- 'STDEV' => [12, -1, 0, 0],
- 'DOLLAR' => [13, -1, 1, 0],
- 'FIXED' => [14, -1, 1, 0],
- 'SIN' => [15, 1, 1, 0],
- 'COS' => [16, 1, 1, 0],
- 'TAN' => [17, 1, 1, 0],
- 'ATAN' => [18, 1, 1, 0],
- 'PI' => [19, 0, 1, 0],
- 'SQRT' => [20, 1, 1, 0],
- 'EXP' => [21, 1, 1, 0],
- 'LN' => [22, 1, 1, 0],
- 'LOG10' => [23, 1, 1, 0],
- 'ABS' => [24, 1, 1, 0],
- 'INT' => [25, 1, 1, 0],
- 'SIGN' => [26, 1, 1, 0],
- 'ROUND' => [27, 2, 1, 0],
- 'LOOKUP' => [28, -1, 0, 0],
- 'INDEX' => [29, -1, 0, 1],
- 'REPT' => [30, 2, 1, 0],
- 'MID' => [31, 3, 1, 0],
- 'LEN' => [32, 1, 1, 0],
- 'VALUE' => [33, 1, 1, 0],
- 'TRUE' => [34, 0, 1, 0],
- 'FALSE' => [35, 0, 1, 0],
- 'AND' => [36, -1, 0, 0],
- 'OR' => [37, -1, 0, 0],
- 'NOT' => [38, 1, 1, 0],
- 'MOD' => [39, 2, 1, 0],
- 'DCOUNT' => [40, 3, 0, 0],
- 'DSUM' => [41, 3, 0, 0],
- 'DAVERAGE' => [42, 3, 0, 0],
- 'DMIN' => [43, 3, 0, 0],
- 'DMAX' => [44, 3, 0, 0],
- 'DSTDEV' => [45, 3, 0, 0],
- 'VAR' => [46, -1, 0, 0],
- 'DVAR' => [47, 3, 0, 0],
- 'TEXT' => [48, 2, 1, 0],
- 'LINEST' => [49, -1, 0, 0],
- 'TREND' => [50, -1, 0, 0],
- 'LOGEST' => [51, -1, 0, 0],
- 'GROWTH' => [52, -1, 0, 0],
- 'PV' => [56, -1, 1, 0],
- 'FV' => [57, -1, 1, 0],
- 'NPER' => [58, -1, 1, 0],
- 'PMT' => [59, -1, 1, 0],
- 'RATE' => [60, -1, 1, 0],
- 'MIRR' => [61, 3, 0, 0],
- 'IRR' => [62, -1, 0, 0],
- 'RAND' => [63, 0, 1, 1],
- 'MATCH' => [64, -1, 0, 0],
- 'DATE' => [65, 3, 1, 0],
- 'TIME' => [66, 3, 1, 0],
- 'DAY' => [67, 1, 1, 0],
- 'MONTH' => [68, 1, 1, 0],
- 'YEAR' => [69, 1, 1, 0],
- 'WEEKDAY' => [70, -1, 1, 0],
- 'HOUR' => [71, 1, 1, 0],
- 'MINUTE' => [72, 1, 1, 0],
- 'SECOND' => [73, 1, 1, 0],
- 'NOW' => [74, 0, 1, 1],
- 'AREAS' => [75, 1, 0, 1],
- 'ROWS' => [76, 1, 0, 1],
- 'COLUMNS' => [77, 1, 0, 1],
- 'OFFSET' => [78, -1, 0, 1],
- 'SEARCH' => [82, -1, 1, 0],
- 'TRANSPOSE' => [83, 1, 1, 0],
- 'TYPE' => [86, 1, 1, 0],
- 'ATAN2' => [97, 2, 1, 0],
- 'ASIN' => [98, 1, 1, 0],
- 'ACOS' => [99, 1, 1, 0],
- 'CHOOSE' => [100, -1, 1, 0],
- 'HLOOKUP' => [101, -1, 0, 0],
- 'VLOOKUP' => [102, -1, 0, 0],
- 'ISREF' => [105, 1, 0, 0],
- 'LOG' => [109, -1, 1, 0],
- 'CHAR' => [111, 1, 1, 0],
- 'LOWER' => [112, 1, 1, 0],
- 'UPPER' => [113, 1, 1, 0],
- 'PROPER' => [114, 1, 1, 0],
- 'LEFT' => [115, -1, 1, 0],
- 'RIGHT' => [116, -1, 1, 0],
- 'EXACT' => [117, 2, 1, 0],
- 'TRIM' => [118, 1, 1, 0],
- 'REPLACE' => [119, 4, 1, 0],
- 'SUBSTITUTE' => [120, -1, 1, 0],
- 'CODE' => [121, 1, 1, 0],
- 'FIND' => [124, -1, 1, 0],
- 'CELL' => [125, -1, 0, 1],
- 'ISERR' => [126, 1, 1, 0],
- 'ISTEXT' => [127, 1, 1, 0],
- 'ISNUMBER' => [128, 1, 1, 0],
- 'ISBLANK' => [129, 1, 1, 0],
- 'T' => [130, 1, 0, 0],
- 'N' => [131, 1, 0, 0],
- 'DATEVALUE' => [140, 1, 1, 0],
- 'TIMEVALUE' => [141, 1, 1, 0],
- 'SLN' => [142, 3, 1, 0],
- 'SYD' => [143, 4, 1, 0],
- 'DDB' => [144, -1, 1, 0],
- 'INDIRECT' => [148, -1, 1, 1],
- 'CALL' => [150, -1, 1, 0],
- 'CLEAN' => [162, 1, 1, 0],
- 'MDETERM' => [163, 1, 2, 0],
- 'MINVERSE' => [164, 1, 2, 0],
- 'MMULT' => [165, 2, 2, 0],
- 'IPMT' => [167, -1, 1, 0],
- 'PPMT' => [168, -1, 1, 0],
- 'COUNTA' => [169, -1, 0, 0],
- 'PRODUCT' => [183, -1, 0, 0],
- 'FACT' => [184, 1, 1, 0],
- 'DPRODUCT' => [189, 3, 0, 0],
- 'ISNONTEXT' => [190, 1, 1, 0],
- 'STDEVP' => [193, -1, 0, 0],
- 'VARP' => [194, -1, 0, 0],
- 'DSTDEVP' => [195, 3, 0, 0],
- 'DVARP' => [196, 3, 0, 0],
- 'TRUNC' => [197, -1, 1, 0],
- 'ISLOGICAL' => [198, 1, 1, 0],
- 'DCOUNTA' => [199, 3, 0, 0],
- 'USDOLLAR' => [204, -1, 1, 0],
- 'FINDB' => [205, -1, 1, 0],
- 'SEARCHB' => [206, -1, 1, 0],
- 'REPLACEB' => [207, 4, 1, 0],
- 'LEFTB' => [208, -1, 1, 0],
- 'RIGHTB' => [209, -1, 1, 0],
- 'MIDB' => [210, 3, 1, 0],
- 'LENB' => [211, 1, 1, 0],
- 'ROUNDUP' => [212, 2, 1, 0],
- 'ROUNDDOWN' => [213, 2, 1, 0],
- 'ASC' => [214, 1, 1, 0],
- 'DBCS' => [215, 1, 1, 0],
- 'RANK' => [216, -1, 0, 0],
- 'ADDRESS' => [219, -1, 1, 0],
- 'DAYS360' => [220, -1, 1, 0],
- 'TODAY' => [221, 0, 1, 1],
- 'VDB' => [222, -1, 1, 0],
- 'MEDIAN' => [227, -1, 0, 0],
- 'SUMPRODUCT' => [228, -1, 2, 0],
- 'SINH' => [229, 1, 1, 0],
- 'COSH' => [230, 1, 1, 0],
- 'TANH' => [231, 1, 1, 0],
- 'ASINH' => [232, 1, 1, 0],
- 'ACOSH' => [233, 1, 1, 0],
- 'ATANH' => [234, 1, 1, 0],
- 'DGET' => [235, 3, 0, 0],
- 'INFO' => [244, 1, 1, 1],
- 'DB' => [247, -1, 1, 0],
- 'FREQUENCY' => [252, 2, 0, 0],
- 'ERROR.TYPE' => [261, 1, 1, 0],
- 'REGISTER.ID' => [267, -1, 1, 0],
- 'AVEDEV' => [269, -1, 0, 0],
- 'BETADIST' => [270, -1, 1, 0],
- 'GAMMALN' => [271, 1, 1, 0],
- 'BETAINV' => [272, -1, 1, 0],
- 'BINOMDIST' => [273, 4, 1, 0],
- 'CHIDIST' => [274, 2, 1, 0],
- 'CHIINV' => [275, 2, 1, 0],
- 'COMBIN' => [276, 2, 1, 0],
- 'CONFIDENCE' => [277, 3, 1, 0],
- 'CRITBINOM' => [278, 3, 1, 0],
- 'EVEN' => [279, 1, 1, 0],
- 'EXPONDIST' => [280, 3, 1, 0],
- 'FDIST' => [281, 3, 1, 0],
- 'FINV' => [282, 3, 1, 0],
- 'FISHER' => [283, 1, 1, 0],
- 'FISHERINV' => [284, 1, 1, 0],
- 'FLOOR' => [285, 2, 1, 0],
- 'GAMMADIST' => [286, 4, 1, 0],
- 'GAMMAINV' => [287, 3, 1, 0],
- 'CEILING' => [288, 2, 1, 0],
- 'HYPGEOMDIST' => [289, 4, 1, 0],
- 'LOGNORMDIST' => [290, 3, 1, 0],
- 'LOGINV' => [291, 3, 1, 0],
- 'NEGBINOMDIST' => [292, 3, 1, 0],
- 'NORMDIST' => [293, 4, 1, 0],
- 'NORMSDIST' => [294, 1, 1, 0],
- 'NORMINV' => [295, 3, 1, 0],
- 'NORMSINV' => [296, 1, 1, 0],
- 'STANDARDIZE' => [297, 3, 1, 0],
- 'ODD' => [298, 1, 1, 0],
- 'PERMUT' => [299, 2, 1, 0],
- 'POISSON' => [300, 3, 1, 0],
- 'TDIST' => [301, 3, 1, 0],
- 'WEIBULL' => [302, 4, 1, 0],
- 'SUMXMY2' => [303, 2, 2, 0],
- 'SUMX2MY2' => [304, 2, 2, 0],
- 'SUMX2PY2' => [305, 2, 2, 0],
- 'CHITEST' => [306, 2, 2, 0],
- 'CORREL' => [307, 2, 2, 0],
- 'COVAR' => [308, 2, 2, 0],
- 'FORECAST' => [309, 3, 2, 0],
- 'FTEST' => [310, 2, 2, 0],
- 'INTERCEPT' => [311, 2, 2, 0],
- 'PEARSON' => [312, 2, 2, 0],
- 'RSQ' => [313, 2, 2, 0],
- 'STEYX' => [314, 2, 2, 0],
- 'SLOPE' => [315, 2, 2, 0],
- 'TTEST' => [316, 4, 2, 0],
- 'PROB' => [317, -1, 2, 0],
- 'DEVSQ' => [318, -1, 0, 0],
- 'GEOMEAN' => [319, -1, 0, 0],
- 'HARMEAN' => [320, -1, 0, 0],
- 'SUMSQ' => [321, -1, 0, 0],
- 'KURT' => [322, -1, 0, 0],
- 'SKEW' => [323, -1, 0, 0],
- 'ZTEST' => [324, -1, 0, 0],
- 'LARGE' => [325, 2, 0, 0],
- 'SMALL' => [326, 2, 0, 0],
- 'QUARTILE' => [327, 2, 0, 0],
- 'PERCENTILE' => [328, 2, 0, 0],
- 'PERCENTRANK' => [329, -1, 0, 0],
- 'MODE' => [330, -1, 2, 0],
- 'TRIMMEAN' => [331, 2, 0, 0],
- 'TINV' => [332, 2, 1, 0],
- 'CONCATENATE' => [336, -1, 1, 0],
- 'POWER' => [337, 2, 1, 0],
- 'RADIANS' => [342, 1, 1, 0],
- 'DEGREES' => [343, 1, 1, 0],
- 'SUBTOTAL' => [344, -1, 0, 0],
- 'SUMIF' => [345, -1, 0, 0],
- 'COUNTIF' => [346, 2, 0, 0],
- 'COUNTBLANK' => [347, 1, 0, 0],
- 'ISPMT' => [350, 4, 1, 0],
- 'DATEDIF' => [351, 3, 1, 0],
- 'DATESTRING' => [352, 1, 1, 0],
- 'NUMBERSTRING' => [353, 2, 1, 0],
- 'ROMAN' => [354, -1, 1, 0],
- 'GETPIVOTDATA' => [358, -1, 0, 0],
- 'HYPERLINK' => [359, -1, 1, 0],
- 'PHONETIC' => [360, 1, 0, 0],
- 'AVERAGEA' => [361, -1, 0, 0],
- 'MAXA' => [362, -1, 0, 0],
- 'MINA' => [363, -1, 0, 0],
- 'STDEVPA' => [364, -1, 0, 0],
- 'VARPA' => [365, -1, 0, 0],
- 'STDEVA' => [366, -1, 0, 0],
- 'VARA' => [367, -1, 0, 0],
- 'BAHTTEXT' => [368, 1, 0, 0],
- ];
-
- private $spreadsheet;
-
- /**
- * The class constructor.
- */
- public function __construct(Spreadsheet $spreadsheet)
- {
- $this->spreadsheet = $spreadsheet;
-
- $this->currentCharacter = 0;
- $this->currentToken = ''; // The token we are working on.
- $this->formula = ''; // The formula to parse.
- $this->lookAhead = ''; // The character ahead of the current char.
- $this->parseTree = ''; // The parse tree to be generated.
- $this->externalSheets = [];
- $this->references = [];
- }
-
- /**
- * Convert a token to the proper ptg value.
- *
- * @param mixed $token the token to convert
- *
- * @return mixed the converted token on success
- */
- private function convert($token)
- {
- if (preg_match('/"([^"]|""){0,255}"/', $token)) {
- return $this->convertString($token);
- } elseif (is_numeric($token)) {
- return $this->convertNumber($token);
- // match references like A1 or $A$1
- } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/', $token)) {
- return $this->convertRef2d($token);
- // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?[A-Ia-i]?[A-Za-z]\$?(\\d+)$/u', $token)) {
- return $this->convertRef3d($token);
- // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\\d+)$/u", $token)) {
- return $this->convertRef3d($token);
- // match ranges like A1:B2 or $A$1:$B$2
- } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) {
- return $this->convertRange2d($token);
- // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?([A-Ia-i]?[A-Za-z])?\$?(\\d+)\\:\$?([A-Ia-i]?[A-Za-z])?\$?(\\d+)$/u', $token)) {
- return $this->convertRange3d($token);
- // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\\d+)\\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\\d+)$/u", $token)) {
- return $this->convertRange3d($token);
- // operators (including parentheses)
- } elseif (isset($this->ptg[$token])) {
- return pack('C', $this->ptg[$token]);
- // match error codes
- } elseif (preg_match('/^#[A-Z0\\/]{3,5}[!?]{1}$/', $token) || $token == '#N/A') {
- return $this->convertError($token);
- } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/mui', $token) && $this->spreadsheet->getDefinedName($token) !== null) {
- return $this->convertDefinedName($token);
- // commented so argument number can be processed correctly. See toReversePolish().
- /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token))
- {
- return($this->convertFunction($token, $this->_func_args));
- }*/
- // if it's an argument, ignore the token (the argument remains)
- } elseif ($token == 'arg') {
- return '';
- }
-
- // TODO: use real error codes
- throw new WriterException("Unknown token $token");
- }
-
- /**
- * Convert a number token to ptgInt or ptgNum.
- *
- * @param mixed $num an integer or double for conversion to its ptg value
- *
- * @return string
- */
- private function convertNumber($num)
- {
- // Integer in the range 0..2**16-1
- if ((preg_match('/^\\d+$/', $num)) && ($num <= 65535)) {
- return pack('Cv', $this->ptg['ptgInt'], $num);
- }
-
- // A float
- if (BIFFwriter::getByteOrder()) { // if it's Big Endian
- $num = strrev($num);
- }
-
- return pack('Cd', $this->ptg['ptgNum'], $num);
- }
-
- /**
- * Convert a string token to ptgStr.
- *
- * @param string $string a string for conversion to its ptg value
- *
- * @return mixed the converted token on success
- */
- private function convertString($string)
- {
- // chop away beggining and ending quotes
- $string = substr($string, 1, -1);
- if (strlen($string) > 255) {
- throw new WriterException('String is too long');
- }
-
- return pack('C', $this->ptg['ptgStr']) . StringHelper::UTF8toBIFF8UnicodeShort($string);
- }
-
- /**
- * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of
- * args that it takes.
- *
- * @param string $token the name of the function for convertion to ptg value
- * @param int $num_args the number of arguments the function receives
- *
- * @return string The packed ptg for the function
- */
- private function convertFunction($token, $num_args)
- {
- $args = $this->functions[$token][1];
-
- // Fixed number of args eg. TIME($i, $j, $k).
- if ($args >= 0) {
- return pack('Cv', $this->ptg['ptgFuncV'], $this->functions[$token][0]);
- }
- // Variable number of args eg. SUM($i, $j, $k, ..).
- if ($args == -1) {
- return pack('CCv', $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]);
- }
- }
-
- /**
- * Convert an Excel range such as A1:D4 to a ptgRefV.
- *
- * @param string $range An Excel range in the A1:A2
- * @param int $class
- *
- * @return string
- */
- private function convertRange2d($range, $class = 0)
- {
- // TODO: possible class value 0,1,2 check Formula.pm
- // Split the range into 2 cell refs
- if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) {
- [$cell1, $cell2] = explode(':', $range);
- } else {
- // TODO: use real error codes
- throw new WriterException('Unknown range separator');
- }
-
- // Convert the cell references
- [$row1, $col1] = $this->cellToPackedRowcol($cell1);
- [$row2, $col2] = $this->cellToPackedRowcol($cell2);
-
- // The ptg value depends on the class of the ptg.
- if ($class == 0) {
- $ptgArea = pack('C', $this->ptg['ptgArea']);
- } elseif ($class == 1) {
- $ptgArea = pack('C', $this->ptg['ptgAreaV']);
- } elseif ($class == 2) {
- $ptgArea = pack('C', $this->ptg['ptgAreaA']);
- } else {
- // TODO: use real error codes
- throw new WriterException("Unknown class $class");
- }
-
- return $ptgArea . $row1 . $row2 . $col1 . $col2;
- }
-
- /**
- * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to
- * a ptgArea3d.
- *
- * @param string $token an Excel range in the Sheet1!A1:A2 format
- *
- * @return mixed the packed ptgArea3d token on success
- */
- private function convertRange3d($token)
- {
- // Split the ref at the ! symbol
- [$ext_ref, $range] = PhpspreadsheetWorksheet::extractSheetTitle($token, true);
-
- // Convert the external reference part (different for BIFF8)
- $ext_ref = $this->getRefIndex($ext_ref);
-
- // Split the range into 2 cell refs
- [$cell1, $cell2] = explode(':', $range);
-
- // Convert the cell references
- if (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\\d+)$/', $cell1)) {
- [$row1, $col1] = $this->cellToPackedRowcol($cell1);
- [$row2, $col2] = $this->cellToPackedRowcol($cell2);
- } else { // It's a rows range (like 26:27)
- [$row1, $col1, $row2, $col2] = $this->rangeToPackedRange($cell1 . ':' . $cell2);
- }
-
- // The ptg value depends on the class of the ptg.
- $ptgArea = pack('C', $this->ptg['ptgArea3d']);
-
- return $ptgArea . $ext_ref . $row1 . $row2 . $col1 . $col2;
- }
-
- /**
- * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV.
- *
- * @param string $cell An Excel cell reference
- *
- * @return string The cell in packed() format with the corresponding ptg
- */
- private function convertRef2d($cell)
- {
- // Convert the cell reference
- $cell_array = $this->cellToPackedRowcol($cell);
- [$row, $col] = $cell_array;
-
- // The ptg value depends on the class of the ptg.
- $ptgRef = pack('C', $this->ptg['ptgRefA']);
-
- return $ptgRef . $row . $col;
- }
-
- /**
- * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a
- * ptgRef3d.
- *
- * @param string $cell An Excel cell reference
- *
- * @return mixed the packed ptgRef3d token on success
- */
- private function convertRef3d($cell)
- {
- // Split the ref at the ! symbol
- [$ext_ref, $cell] = PhpspreadsheetWorksheet::extractSheetTitle($cell, true);
-
- // Convert the external reference part (different for BIFF8)
- $ext_ref = $this->getRefIndex($ext_ref);
-
- // Convert the cell reference part
- [$row, $col] = $this->cellToPackedRowcol($cell);
-
- // The ptg value depends on the class of the ptg.
- $ptgRef = pack('C', $this->ptg['ptgRef3dA']);
-
- return $ptgRef . $ext_ref . $row . $col;
- }
-
- /**
- * Convert an error code to a ptgErr.
- *
- * @param string $errorCode The error code for conversion to its ptg value
- *
- * @return string The error code ptgErr
- */
- private function convertError($errorCode)
- {
- switch ($errorCode) {
- case '#NULL!':
- return pack('C', 0x00);
- case '#DIV/0!':
- return pack('C', 0x07);
- case '#VALUE!':
- return pack('C', 0x0F);
- case '#REF!':
- return pack('C', 0x17);
- case '#NAME?':
- return pack('C', 0x1D);
- case '#NUM!':
- return pack('C', 0x24);
- case '#N/A':
- return pack('C', 0x2A);
- }
-
- return pack('C', 0xFF);
- }
-
- private function convertDefinedName(string $name): void
- {
- if (strlen($name) > 255) {
- throw new WriterException('Defined Name is too long');
- }
-
- $nameReference = 1;
- foreach ($this->spreadsheet->getDefinedNames() as $definedName) {
- if ($name === $definedName->getName()) {
- break;
- }
- ++$nameReference;
- }
-
- $ptgRef = pack('Cvxx', $this->ptg['ptgName'], $nameReference);
-
- throw new WriterException('Cannot yet write formulae with defined names to Xls');
-// return $ptgRef;
- }
-
- /**
- * Look up the REF index that corresponds to an external sheet name
- * (or range). If it doesn't exist yet add it to the workbook's references
- * array. It assumes all sheet names given must exist.
- *
- * @param string $ext_ref The name of the external reference
- *
- * @return mixed The reference index in packed() format on success
- */
- private function getRefIndex($ext_ref)
- {
- $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any.
- $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any.
- $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with '
-
- // Check if there is a sheet range eg., Sheet1:Sheet2.
- if (preg_match('/:/', $ext_ref)) {
- [$sheet_name1, $sheet_name2] = explode(':', $ext_ref);
-
- $sheet1 = $this->getSheetIndex($sheet_name1);
- if ($sheet1 == -1) {
- throw new WriterException("Unknown sheet name $sheet_name1 in formula");
- }
- $sheet2 = $this->getSheetIndex($sheet_name2);
- if ($sheet2 == -1) {
- throw new WriterException("Unknown sheet name $sheet_name2 in formula");
- }
-
- // Reverse max and min sheet numbers if necessary
- if ($sheet1 > $sheet2) {
- [$sheet1, $sheet2] = [$sheet2, $sheet1];
- }
- } else { // Single sheet name only.
- $sheet1 = $this->getSheetIndex($ext_ref);
- if ($sheet1 == -1) {
- throw new WriterException("Unknown sheet name $ext_ref in formula");
- }
- $sheet2 = $sheet1;
- }
-
- // assume all references belong to this document
- $supbook_index = 0x00;
- $ref = pack('vvv', $supbook_index, $sheet1, $sheet2);
- $totalreferences = count($this->references);
- $index = -1;
- for ($i = 0; $i < $totalreferences; ++$i) {
- if ($ref == $this->references[$i]) {
- $index = $i;
-
- break;
- }
- }
- // if REF was not found add it to references array
- if ($index == -1) {
- $this->references[$totalreferences] = $ref;
- $index = $totalreferences;
- }
-
- return pack('v', $index);
- }
-
- /**
- * Look up the index that corresponds to an external sheet name. The hash of
- * sheet names is updated by the addworksheet() method of the
- * \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook class.
- *
- * @param string $sheet_name Sheet name
- *
- * @return int The sheet index, -1 if the sheet was not found
- */
- private function getSheetIndex($sheet_name)
- {
- if (!isset($this->externalSheets[$sheet_name])) {
- return -1;
- }
-
- return $this->externalSheets[$sheet_name];
- }
-
- /**
- * This method is used to update the array of sheet names. It is
- * called by the addWorksheet() method of the
- * \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook class.
- *
- * @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::addWorksheet()
- *
- * @param string $name The name of the worksheet being added
- * @param int $index The index of the worksheet being added
- */
- public function setExtSheet($name, $index): void
- {
- $this->externalSheets[$name] = $index;
- }
-
- /**
- * pack() row and column into the required 3 or 4 byte format.
- *
- * @param string $cell The Excel cell reference to be packed
- *
- * @return array Array containing the row and column in packed() format
- */
- private function cellToPackedRowcol($cell)
- {
- $cell = strtoupper($cell);
- [$row, $col, $row_rel, $col_rel] = $this->cellToRowcol($cell);
- if ($col >= 256) {
- throw new WriterException("Column in: $cell greater than 255");
- }
- if ($row >= 65536) {
- throw new WriterException("Row in: $cell greater than 65536 ");
- }
-
- // Set the high bits to indicate if row or col are relative.
- $col |= $col_rel << 14;
- $col |= $row_rel << 15;
- $col = pack('v', $col);
-
- $row = pack('v', $row);
-
- return [$row, $col];
- }
-
- /**
- * pack() row range into the required 3 or 4 byte format.
- * Just using maximum col/rows, which is probably not the correct solution.
- *
- * @param string $range The Excel range to be packed
- *
- * @return array Array containing (row1,col1,row2,col2) in packed() format
- */
- private function rangeToPackedRange($range)
- {
- preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);
- // return absolute rows if there is a $ in the ref
- $row1_rel = empty($match[1]) ? 1 : 0;
- $row1 = $match[2];
- $row2_rel = empty($match[3]) ? 1 : 0;
- $row2 = $match[4];
- // Convert 1-index to zero-index
- --$row1;
- --$row2;
- // Trick poor inocent Excel
- $col1 = 0;
- $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!)
-
- // FIXME: this changes for BIFF8
- if (($row1 >= 65536) || ($row2 >= 65536)) {
- throw new WriterException("Row in: $range greater than 65536 ");
- }
-
- // Set the high bits to indicate if rows are relative.
- $col1 |= $row1_rel << 15;
- $col2 |= $row2_rel << 15;
- $col1 = pack('v', $col1);
- $col2 = pack('v', $col2);
-
- $row1 = pack('v', $row1);
- $row2 = pack('v', $row2);
-
- return [$row1, $col1, $row2, $col2];
- }
-
- /**
- * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero
- * indexed row and column number. Also returns two (0,1) values to indicate
- * whether the row or column are relative references.
- *
- * @param string $cell the Excel cell reference in A1 format
- *
- * @return array
- */
- private function cellToRowcol($cell)
- {
- preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match);
- // return absolute column if there is a $ in the ref
- $col_rel = empty($match[1]) ? 1 : 0;
- $col_ref = $match[2];
- $row_rel = empty($match[3]) ? 1 : 0;
- $row = $match[4];
-
- // Convert base26 column string to a number.
- $expn = strlen($col_ref) - 1;
- $col = 0;
- $col_ref_length = strlen($col_ref);
- for ($i = 0; $i < $col_ref_length; ++$i) {
- $col += (ord($col_ref[$i]) - 64) * 26 ** $expn;
- --$expn;
- }
-
- // Convert 1-index to zero-index
- --$row;
- --$col;
-
- return [$row, $col, $row_rel, $col_rel];
- }
-
- /**
- * Advance to the next valid token.
- */
- private function advance()
- {
- $i = $this->currentCharacter;
- $formula_length = strlen($this->formula);
- // eat up white spaces
- if ($i < $formula_length) {
- while ($this->formula[$i] == ' ') {
- ++$i;
- }
-
- if ($i < ($formula_length - 1)) {
- $this->lookAhead = $this->formula[$i + 1];
- }
- $token = '';
- }
-
- while ($i < $formula_length) {
- $token .= $this->formula[$i];
-
- if ($i < ($formula_length - 1)) {
- $this->lookAhead = $this->formula[$i + 1];
- } else {
- $this->lookAhead = '';
- }
-
- if ($this->match($token) != '') {
- $this->currentCharacter = $i + 1;
- $this->currentToken = $token;
-
- return 1;
- }
-
- if ($i < ($formula_length - 2)) {
- $this->lookAhead = $this->formula[$i + 2];
- } else { // if we run out of characters lookAhead becomes empty
- $this->lookAhead = '';
- }
- ++$i;
- }
- //die("Lexical error ".$this->currentCharacter);
- }
-
- /**
- * Checks if it's a valid token.
- *
- * @param mixed $token the token to check
- *
- * @return mixed The checked token or false on failure
- */
- private function match($token)
- {
- switch ($token) {
- case '+':
- case '-':
- case '*':
- case '/':
- case '(':
- case ')':
- case ',':
- case ';':
- case '>=':
- case '<=':
- case '=':
- case '<>':
- case '^':
- case '&':
- case '%':
- return $token;
-
- break;
- case '>':
- if ($this->lookAhead === '=') { // it's a GE token
- break;
- }
-
- return $token;
-
- break;
- case '<':
- // it's a LE or a NE token
- if (($this->lookAhead === '=') || ($this->lookAhead === '>')) {
- break;
- }
-
- return $token;
-
- break;
- default:
- // if it's a reference A1 or $A$1 or $A1 or A$1
- if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?\d+$/', $token) && !preg_match('/\d/', $this->lookAhead) && ($this->lookAhead !== ':') && ($this->lookAhead !== '.') && ($this->lookAhead !== '!')) {
- return $token;
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?[A-Ia-i]?[A-Za-z]\$?\\d+$/u', $token) && !preg_match('/\d/', $this->lookAhead) && ($this->lookAhead !== ':') && ($this->lookAhead !== '.')) {
- // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1)
- return $token;
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?[A-Ia-i]?[A-Za-z]\\$?\\d+$/u", $token) && !preg_match('/\d/', $this->lookAhead) && ($this->lookAhead !== ':') && ($this->lookAhead !== '.')) {
- // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1)
- return $token;
- } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+:(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+$/', $token) && !preg_match('/\d/', $this->lookAhead)) {
- // if it's a range A1:A2 or $A$1:$A$2
- return $token;
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?([A-Ia-i]?[A-Za-z])?\$?\\d+:\$?([A-Ia-i]?[A-Za-z])?\$?\\d+$/u', $token) && !preg_match('/\d/', $this->lookAhead)) {
- // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2
- return $token;
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?([A-Ia-i]?[A-Za-z])?\\$?\\d+:\\$?([A-Ia-i]?[A-Za-z])?\\$?\\d+$/u", $token) && !preg_match('/\d/', $this->lookAhead)) {
- // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2
- return $token;
- } elseif (is_numeric($token) && (!is_numeric($token . $this->lookAhead) || ($this->lookAhead == '')) && ($this->lookAhead !== '!') && ($this->lookAhead !== ':')) {
- // If it's a number (check that it's not a sheet name or range)
- return $token;
- } elseif (preg_match('/"([^"]|""){0,255}"/', $token) && $this->lookAhead !== '"' && (substr_count($token, '"') % 2 == 0)) {
- // If it's a string (of maximum 255 characters)
- return $token;
- } elseif (preg_match('/^#[A-Z0\\/]{3,5}[!?]{1}$/', $token) || $token === '#N/A') {
- // If it's an error code
- return $token;
- } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\\.]+$/i", $token) && ($this->lookAhead === '(')) {
- // if it's a function call
- return $token;
- } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/miu', $token) && $this->spreadsheet->getDefinedName($token) !== null) {
- return $token;
- } elseif (substr($token, -1) === ')') {
- // It's an argument of some description (e.g. a named range),
- // precise nature yet to be determined
- return $token;
- }
-
- return '';
- }
- }
-
- /**
- * The parsing method. It parses a formula.
- *
- * @param string $formula the formula to parse, without the initial equal
- * sign (=)
- *
- * @return mixed true on success
- */
- public function parse($formula)
- {
- $this->currentCharacter = 0;
- $this->formula = (string) $formula;
- $this->lookAhead = $formula[1] ?? '';
- $this->advance();
- $this->parseTree = $this->condition();
-
- return true;
- }
-
- /**
- * It parses a condition. It assumes the following rule:
- * Cond -> Expr [(">" | "<") Expr].
- *
- * @return mixed The parsed ptg'd tree on success
- */
- private function condition()
- {
- $result = $this->expression();
- if ($this->currentToken == '<') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgLT', $result, $result2);
- } elseif ($this->currentToken == '>') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgGT', $result, $result2);
- } elseif ($this->currentToken == '<=') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgLE', $result, $result2);
- } elseif ($this->currentToken == '>=') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgGE', $result, $result2);
- } elseif ($this->currentToken == '=') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgEQ', $result, $result2);
- } elseif ($this->currentToken == '<>') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgNE', $result, $result2);
- } elseif ($this->currentToken == '&') {
- $this->advance();
- $result2 = $this->expression();
- $result = $this->createTree('ptgConcat', $result, $result2);
- }
-
- return $result;
- }
-
- /**
- * It parses a expression. It assumes the following rule:
- * Expr -> Term [("+" | "-") Term]
- * -> "string"
- * -> "-" Term : Negative value
- * -> "+" Term : Positive value
- * -> Error code.
- *
- * @return mixed The parsed ptg'd tree on success
- */
- private function expression()
- {
- // If it's a string return a string node
- if (preg_match('/"([^"]|""){0,255}"/', $this->currentToken)) {
- $tmp = str_replace('""', '"', $this->currentToken);
- if (($tmp == '"') || ($tmp == '')) {
- // Trap for "" that has been used for an empty string
- $tmp = '""';
- }
- $result = $this->createTree($tmp, '', '');
- $this->advance();
-
- return $result;
- // If it's an error code
- } elseif (preg_match('/^#[A-Z0\\/]{3,5}[!?]{1}$/', $this->currentToken) || $this->currentToken == '#N/A') {
- $result = $this->createTree($this->currentToken, 'ptgErr', '');
- $this->advance();
-
- return $result;
- // If it's a negative value
- } elseif ($this->currentToken == '-') {
- // catch "-" Term
- $this->advance();
- $result2 = $this->expression();
-
- return $this->createTree('ptgUminus', $result2, '');
- // If it's a positive value
- } elseif ($this->currentToken == '+') {
- // catch "+" Term
- $this->advance();
- $result2 = $this->expression();
-
- return $this->createTree('ptgUplus', $result2, '');
- }
- $result = $this->term();
- while (
- ($this->currentToken == '+') ||
- ($this->currentToken == '-') ||
- ($this->currentToken == '^')
- ) {
- if ($this->currentToken == '+') {
- $this->advance();
- $result2 = $this->term();
- $result = $this->createTree('ptgAdd', $result, $result2);
- } elseif ($this->currentToken == '-') {
- $this->advance();
- $result2 = $this->term();
- $result = $this->createTree('ptgSub', $result, $result2);
- } else {
- $this->advance();
- $result2 = $this->term();
- $result = $this->createTree('ptgPower', $result, $result2);
- }
- }
-
- return $result;
- }
-
- /**
- * This function just introduces a ptgParen element in the tree, so that Excel
- * doesn't get confused when working with a parenthesized formula afterwards.
- *
- * @see fact()
- *
- * @return array The parsed ptg'd tree
- */
- private function parenthesizedExpression()
- {
- return $this->createTree('ptgParen', $this->expression(), '');
- }
-
- /**
- * It parses a term. It assumes the following rule:
- * Term -> Fact [("*" | "/") Fact].
- *
- * @return mixed The parsed ptg'd tree on success
- */
- private function term()
- {
- $result = $this->fact();
- while (
- ($this->currentToken == '*') ||
- ($this->currentToken == '/')
- ) {
- if ($this->currentToken == '*') {
- $this->advance();
- $result2 = $this->fact();
- $result = $this->createTree('ptgMul', $result, $result2);
- } else {
- $this->advance();
- $result2 = $this->fact();
- $result = $this->createTree('ptgDiv', $result, $result2);
- }
- }
-
- return $result;
- }
-
- /**
- * It parses a factor. It assumes the following rule:
- * Fact -> ( Expr )
- * | CellRef
- * | CellRange
- * | Number
- * | Function.
- *
- * @return mixed The parsed ptg'd tree on success
- */
- private function fact()
- {
- if ($this->currentToken === '(') {
- $this->advance(); // eat the "("
- $result = $this->parenthesizedExpression();
- if ($this->currentToken !== ')') {
- throw new WriterException("')' token expected.");
- }
- $this->advance(); // eat the ")"
-
- return $result;
- }
- // if it's a reference
- if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?\d+$/', $this->currentToken)) {
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?[A-Ia-i]?[A-Za-z]\$?\\d+$/u', $this->currentToken)) {
- // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1)
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?[A-Ia-i]?[A-Za-z]\\$?\\d+$/u", $this->currentToken)) {
- // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1)
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (
- preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+:(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+$/', $this->currentToken) ||
- preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?\d+$/', $this->currentToken)
- ) {
- // if it's a range A1:B2 or $A$1:$B$2
- // must be an error?
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (preg_match('/^' . self::REGEX_SHEET_TITLE_UNQUOTED . '(\\:' . self::REGEX_SHEET_TITLE_UNQUOTED . ')?\\!\$?([A-Ia-i]?[A-Za-z])?\$?\\d+:\$?([A-Ia-i]?[A-Za-z])?\$?\\d+$/u', $this->currentToken)) {
- // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2)
- // must be an error?
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . '(\\:' . self::REGEX_SHEET_TITLE_QUOTED . ")?'\\!\\$?([A-Ia-i]?[A-Za-z])?\\$?\\d+:\\$?([A-Ia-i]?[A-Za-z])?\\$?\\d+$/u", $this->currentToken)) {
- // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2)
- // must be an error?
- $result = $this->createTree($this->currentToken, '', '');
- $this->advance();
-
- return $result;
- } elseif (is_numeric($this->currentToken)) {
- // If it's a number or a percent
- if ($this->lookAhead === '%') {
- $result = $this->createTree('ptgPercent', $this->currentToken, '');
- $this->advance(); // Skip the percentage operator once we've pre-built that tree
- } else {
- $result = $this->createTree($this->currentToken, '', '');
- }
- $this->advance();
-
- return $result;
- } elseif (preg_match("/^[A-Z0-9\xc0-\xdc\\.]+$/i", $this->currentToken) && ($this->lookAhead === '(')) {
- // if it's a function call
- return $this->func();
- } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/miu', $this->currentToken) && $this->spreadsheet->getDefinedName($this->currentToken) !== null) {
- $result = $this->createTree('ptgName', $this->currentToken, '');
- $this->advance();
-
- return $result;
- }
-
- throw new WriterException('Syntax error: ' . $this->currentToken . ', lookahead: ' . $this->lookAhead . ', current char: ' . $this->currentCharacter);
- }
-
- /**
- * It parses a function call. It assumes the following rule:
- * Func -> ( Expr [,Expr]* ).
- *
- * @return mixed The parsed ptg'd tree on success
- */
- private function func()
- {
- $num_args = 0; // number of arguments received
- $function = strtoupper($this->currentToken);
- $result = ''; // initialize result
- $this->advance();
- $this->advance(); // eat the "("
- while ($this->currentToken !== ')') {
- if ($num_args > 0) {
- if ($this->currentToken === ',' || $this->currentToken === ';') {
- $this->advance(); // eat the "," or ";"
- } else {
- throw new WriterException("Syntax error: comma expected in function $function, arg #{$num_args}");
- }
- $result2 = $this->condition();
- $result = $this->createTree('arg', $result, $result2);
- } else { // first argument
- $result2 = $this->condition();
- $result = $this->createTree('arg', '', $result2);
- }
- ++$num_args;
- }
- if (!isset($this->functions[$function])) {
- throw new WriterException("Function $function() doesn't exist");
- }
- $args = $this->functions[$function][1];
- // If fixed number of args eg. TIME($i, $j, $k). Check that the number of args is valid.
- if (($args >= 0) && ($args != $num_args)) {
- throw new WriterException("Incorrect number of arguments in function $function() ");
- }
-
- $result = $this->createTree($function, $result, $num_args);
- $this->advance(); // eat the ")"
-
- return $result;
- }
-
- /**
- * Creates a tree. In fact an array which may have one or two arrays (sub-trees)
- * as elements.
- *
- * @param mixed $value the value of this node
- * @param mixed $left the left array (sub-tree) or a final node
- * @param mixed $right the right array (sub-tree) or a final node
- *
- * @return array A tree
- */
- private function createTree($value, $left, $right)
- {
- return ['value' => $value, 'left' => $left, 'right' => $right];
- }
-
- /**
- * Builds a string containing the tree in reverse polish notation (What you
- * would use in a HP calculator stack).
- * The following tree:.
- *
- * +
- * / \
- * 2 3
- *
- * produces: "23+"
- *
- * The following tree:
- *
- * +
- * / \
- * 3 *
- * / \
- * 6 A1
- *
- * produces: "36A1*+"
- *
- * In fact all operands, functions, references, etc... are written as ptg's
- *
- * @param array $tree the optional tree to convert
- *
- * @return string The tree in reverse polish notation
- */
- public function toReversePolish($tree = [])
- {
- $polish = ''; // the string we are going to return
- if (empty($tree)) { // If it's the first call use parseTree
- $tree = $this->parseTree;
- }
-
- if (is_array($tree['left'])) {
- $converted_tree = $this->toReversePolish($tree['left']);
- $polish .= $converted_tree;
- } elseif ($tree['left'] != '') { // It's a final node
- $converted_tree = $this->convert($tree['left']);
- $polish .= $converted_tree;
- }
- if (is_array($tree['right'])) {
- $converted_tree = $this->toReversePolish($tree['right']);
- $polish .= $converted_tree;
- } elseif ($tree['right'] != '') { // It's a final node
- $converted_tree = $this->convert($tree['right']);
- $polish .= $converted_tree;
- }
- // if it's a function convert it here (so we can set it's arguments)
- if (
- preg_match("/^[A-Z0-9\xc0-\xdc\\.]+$/", $tree['value']) &&
- !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/', $tree['value']) &&
- !preg_match('/^[A-Ia-i]?[A-Za-z](\\d+)\\.\\.[A-Ia-i]?[A-Za-z](\\d+)$/', $tree['value']) &&
- !is_numeric($tree['value']) &&
- !isset($this->ptg[$tree['value']])
- ) {
- // left subtree for a function is always an array.
- if ($tree['left'] != '') {
- $left_tree = $this->toReversePolish($tree['left']);
- } else {
- $left_tree = '';
- }
- // add it's left subtree and return.
- return $left_tree . $this->convertFunction($tree['value'], $tree['right']);
- }
- $converted_tree = $this->convert($tree['value']);
-
- return $polish . $converted_tree;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Workbook.php b/vendor/PhpSpreadsheet/Writer/Xls/Workbook.php
deleted file mode 100644
index f752bce..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Workbook.php
+++ /dev/null
@@ -1,1191 +0,0 @@
-
-// *
-// * The majority of this is _NOT_ my code. I simply ported it from the
-// * PERL Spreadsheet::WriteExcel module.
-// *
-// * The author of the Spreadsheet::WriteExcel module is John McNamara
-// *
-// *
-// * I _DO_ maintain this code, and John McNamara has nothing to do with the
-// * porting of this code to PHP. Any questions directly related to this
-// * class library should be directed to me.
-// *
-// * License Information:
-// *
-// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
-// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com
-// *
-// * This library is free software; you can redistribute it and/or
-// * modify it under the terms of the GNU Lesser General Public
-// * License as published by the Free Software Foundation; either
-// * version 2.1 of the License, or (at your option) any later version.
-// *
-// * This library is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// * Lesser General Public License for more details.
-// *
-// * You should have received a copy of the GNU Lesser General Public
-// * License along with this library; if not, write to the Free Software
-// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-// */
-class Workbook extends BIFFwriter
-{
- /**
- * Formula parser.
- *
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Parser
- */
- private $parser;
-
- /**
- * The BIFF file size for the workbook.
- *
- * @var int
- *
- * @see calcSheetOffsets()
- */
- private $biffSize;
-
- /**
- * XF Writers.
- *
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Xf[]
- */
- private $xfWriters = [];
-
- /**
- * Array containing the colour palette.
- *
- * @var array
- */
- private $palette;
-
- /**
- * The codepage indicates the text encoding used for strings.
- *
- * @var int
- */
- private $codepage;
-
- /**
- * The country code used for localization.
- *
- * @var int
- */
- private $countryCode;
-
- /**
- * Workbook.
- *
- * @var Spreadsheet
- */
- private $spreadsheet;
-
- /**
- * Fonts writers.
- *
- * @var Font[]
- */
- private $fontWriters = [];
-
- /**
- * Added fonts. Maps from font's hash => index in workbook.
- *
- * @var array
- */
- private $addedFonts = [];
-
- /**
- * Shared number formats.
- *
- * @var array
- */
- private $numberFormats = [];
-
- /**
- * Added number formats. Maps from numberFormat's hash => index in workbook.
- *
- * @var array
- */
- private $addedNumberFormats = [];
-
- /**
- * Sizes of the binary worksheet streams.
- *
- * @var array
- */
- private $worksheetSizes = [];
-
- /**
- * Offsets of the binary worksheet streams relative to the start of the global workbook stream.
- *
- * @var array
- */
- private $worksheetOffsets = [];
-
- /**
- * Total number of shared strings in workbook.
- *
- * @var int
- */
- private $stringTotal;
-
- /**
- * Number of unique shared strings in workbook.
- *
- * @var int
- */
- private $stringUnique;
-
- /**
- * Array of unique shared strings in workbook.
- *
- * @var array
- */
- private $stringTable;
-
- /**
- * Color cache.
- */
- private $colors;
-
- /**
- * Escher object corresponding to MSODRAWINGGROUP.
- *
- * @var \PhpOffice\PhpSpreadsheet\Shared\Escher
- */
- private $escher;
-
- /**
- * Class constructor.
- *
- * @param Spreadsheet $spreadsheet The Workbook
- * @param int $str_total Total number of strings
- * @param int $str_unique Total number of unique strings
- * @param array $str_table String Table
- * @param array $colors Colour Table
- * @param Parser $parser The formula parser created for the Workbook
- */
- public function __construct(Spreadsheet $spreadsheet, &$str_total, &$str_unique, &$str_table, &$colors, Parser $parser)
- {
- // It needs to call its parent's constructor explicitly
- parent::__construct();
-
- $this->parser = $parser;
- $this->biffSize = 0;
- $this->palette = [];
- $this->countryCode = -1;
-
- $this->stringTotal = &$str_total;
- $this->stringUnique = &$str_unique;
- $this->stringTable = &$str_table;
- $this->colors = &$colors;
- $this->setPaletteXl97();
-
- $this->spreadsheet = $spreadsheet;
-
- $this->codepage = 0x04B0;
-
- // Add empty sheets and Build color cache
- $countSheets = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $countSheets; ++$i) {
- $phpSheet = $spreadsheet->getSheet($i);
-
- $this->parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser
-
- $supbook_index = 0x00;
- $ref = pack('vvv', $supbook_index, $i, $i);
- $this->parser->references[] = $ref; // Register reference with parser
-
- // Sheet tab colors?
- if ($phpSheet->isTabColorSet()) {
- $this->addColor($phpSheet->getTabColor()->getRGB());
- }
- }
- }
-
- /**
- * Add a new XF writer.
- *
- * @param bool $isStyleXf Is it a style XF?
- *
- * @return int Index to XF record
- */
- public function addXfWriter(Style $style, $isStyleXf = false)
- {
- $xfWriter = new Xf($style);
- $xfWriter->setIsStyleXf($isStyleXf);
-
- // Add the font if not already added
- $fontIndex = $this->addFont($style->getFont());
-
- // Assign the font index to the xf record
- $xfWriter->setFontIndex($fontIndex);
-
- // Background colors, best to treat these after the font so black will come after white in custom palette
- $xfWriter->setFgColor($this->addColor($style->getFill()->getStartColor()->getRGB()));
- $xfWriter->setBgColor($this->addColor($style->getFill()->getEndColor()->getRGB()));
- $xfWriter->setBottomColor($this->addColor($style->getBorders()->getBottom()->getColor()->getRGB()));
- $xfWriter->setTopColor($this->addColor($style->getBorders()->getTop()->getColor()->getRGB()));
- $xfWriter->setRightColor($this->addColor($style->getBorders()->getRight()->getColor()->getRGB()));
- $xfWriter->setLeftColor($this->addColor($style->getBorders()->getLeft()->getColor()->getRGB()));
- $xfWriter->setDiagColor($this->addColor($style->getBorders()->getDiagonal()->getColor()->getRGB()));
-
- // Add the number format if it is not a built-in one and not already added
- if ($style->getNumberFormat()->getBuiltInFormatCode() === false) {
- $numberFormatHashCode = $style->getNumberFormat()->getHashCode();
-
- if (isset($this->addedNumberFormats[$numberFormatHashCode])) {
- $numberFormatIndex = $this->addedNumberFormats[$numberFormatHashCode];
- } else {
- $numberFormatIndex = 164 + count($this->numberFormats);
- $this->numberFormats[$numberFormatIndex] = $style->getNumberFormat();
- $this->addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex;
- }
- } else {
- $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode();
- }
-
- // Assign the number format index to xf record
- $xfWriter->setNumberFormatIndex($numberFormatIndex);
-
- $this->xfWriters[] = $xfWriter;
-
- return count($this->xfWriters) - 1;
- }
-
- /**
- * Add a font to added fonts.
- *
- * @return int Index to FONT record
- */
- public function addFont(\PhpOffice\PhpSpreadsheet\Style\Font $font)
- {
- $fontHashCode = $font->getHashCode();
- if (isset($this->addedFonts[$fontHashCode])) {
- $fontIndex = $this->addedFonts[$fontHashCode];
- } else {
- $countFonts = count($this->fontWriters);
- $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1;
-
- $fontWriter = new Font($font);
- $fontWriter->setColorIndex($this->addColor($font->getColor()->getRGB()));
- $this->fontWriters[] = $fontWriter;
-
- $this->addedFonts[$fontHashCode] = $fontIndex;
- }
-
- return $fontIndex;
- }
-
- /**
- * Alter color palette adding a custom color.
- *
- * @param string $rgb E.g. 'FF00AA'
- *
- * @return int Color index
- */
- private function addColor($rgb)
- {
- if (!isset($this->colors[$rgb])) {
- $color =
- [
- hexdec(substr($rgb, 0, 2)),
- hexdec(substr($rgb, 2, 2)),
- hexdec(substr($rgb, 4)),
- 0,
- ];
- $colorIndex = array_search($color, $this->palette);
- if ($colorIndex) {
- $this->colors[$rgb] = $colorIndex;
- } else {
- if (count($this->colors) === 0) {
- $lastColor = 7;
- } else {
- $lastColor = end($this->colors);
- }
- if ($lastColor < 57) {
- // then we add a custom color altering the palette
- $colorIndex = $lastColor + 1;
- $this->palette[$colorIndex] = $color;
- $this->colors[$rgb] = $colorIndex;
- } else {
- // no room for more custom colors, just map to black
- $colorIndex = 0;
- }
- }
- } else {
- // fetch already added custom color
- $colorIndex = $this->colors[$rgb];
- }
-
- return $colorIndex;
- }
-
- /**
- * Sets the colour palette to the Excel 97+ default.
- */
- private function setPaletteXl97(): void
- {
- $this->palette = [
- 0x08 => [0x00, 0x00, 0x00, 0x00],
- 0x09 => [0xff, 0xff, 0xff, 0x00],
- 0x0A => [0xff, 0x00, 0x00, 0x00],
- 0x0B => [0x00, 0xff, 0x00, 0x00],
- 0x0C => [0x00, 0x00, 0xff, 0x00],
- 0x0D => [0xff, 0xff, 0x00, 0x00],
- 0x0E => [0xff, 0x00, 0xff, 0x00],
- 0x0F => [0x00, 0xff, 0xff, 0x00],
- 0x10 => [0x80, 0x00, 0x00, 0x00],
- 0x11 => [0x00, 0x80, 0x00, 0x00],
- 0x12 => [0x00, 0x00, 0x80, 0x00],
- 0x13 => [0x80, 0x80, 0x00, 0x00],
- 0x14 => [0x80, 0x00, 0x80, 0x00],
- 0x15 => [0x00, 0x80, 0x80, 0x00],
- 0x16 => [0xc0, 0xc0, 0xc0, 0x00],
- 0x17 => [0x80, 0x80, 0x80, 0x00],
- 0x18 => [0x99, 0x99, 0xff, 0x00],
- 0x19 => [0x99, 0x33, 0x66, 0x00],
- 0x1A => [0xff, 0xff, 0xcc, 0x00],
- 0x1B => [0xcc, 0xff, 0xff, 0x00],
- 0x1C => [0x66, 0x00, 0x66, 0x00],
- 0x1D => [0xff, 0x80, 0x80, 0x00],
- 0x1E => [0x00, 0x66, 0xcc, 0x00],
- 0x1F => [0xcc, 0xcc, 0xff, 0x00],
- 0x20 => [0x00, 0x00, 0x80, 0x00],
- 0x21 => [0xff, 0x00, 0xff, 0x00],
- 0x22 => [0xff, 0xff, 0x00, 0x00],
- 0x23 => [0x00, 0xff, 0xff, 0x00],
- 0x24 => [0x80, 0x00, 0x80, 0x00],
- 0x25 => [0x80, 0x00, 0x00, 0x00],
- 0x26 => [0x00, 0x80, 0x80, 0x00],
- 0x27 => [0x00, 0x00, 0xff, 0x00],
- 0x28 => [0x00, 0xcc, 0xff, 0x00],
- 0x29 => [0xcc, 0xff, 0xff, 0x00],
- 0x2A => [0xcc, 0xff, 0xcc, 0x00],
- 0x2B => [0xff, 0xff, 0x99, 0x00],
- 0x2C => [0x99, 0xcc, 0xff, 0x00],
- 0x2D => [0xff, 0x99, 0xcc, 0x00],
- 0x2E => [0xcc, 0x99, 0xff, 0x00],
- 0x2F => [0xff, 0xcc, 0x99, 0x00],
- 0x30 => [0x33, 0x66, 0xff, 0x00],
- 0x31 => [0x33, 0xcc, 0xcc, 0x00],
- 0x32 => [0x99, 0xcc, 0x00, 0x00],
- 0x33 => [0xff, 0xcc, 0x00, 0x00],
- 0x34 => [0xff, 0x99, 0x00, 0x00],
- 0x35 => [0xff, 0x66, 0x00, 0x00],
- 0x36 => [0x66, 0x66, 0x99, 0x00],
- 0x37 => [0x96, 0x96, 0x96, 0x00],
- 0x38 => [0x00, 0x33, 0x66, 0x00],
- 0x39 => [0x33, 0x99, 0x66, 0x00],
- 0x3A => [0x00, 0x33, 0x00, 0x00],
- 0x3B => [0x33, 0x33, 0x00, 0x00],
- 0x3C => [0x99, 0x33, 0x00, 0x00],
- 0x3D => [0x99, 0x33, 0x66, 0x00],
- 0x3E => [0x33, 0x33, 0x99, 0x00],
- 0x3F => [0x33, 0x33, 0x33, 0x00],
- ];
- }
-
- /**
- * Assemble worksheets into a workbook and send the BIFF data to an OLE
- * storage.
- *
- * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams
- *
- * @return string Binary data for workbook stream
- */
- public function writeWorkbook(array $pWorksheetSizes)
- {
- $this->worksheetSizes = $pWorksheetSizes;
-
- // Calculate the number of selected worksheet tabs and call the finalization
- // methods for each worksheet
- $total_worksheets = $this->spreadsheet->getSheetCount();
-
- // Add part 1 of the Workbook globals, what goes before the SHEET records
- $this->storeBof(0x0005);
- $this->writeCodepage();
- $this->writeWindow1();
-
- $this->writeDateMode();
- $this->writeAllFonts();
- $this->writeAllNumberFormats();
- $this->writeAllXfs();
- $this->writeAllStyles();
- $this->writePalette();
-
- // Prepare part 3 of the workbook global stream, what goes after the SHEET records
- $part3 = '';
- if ($this->countryCode !== -1) {
- $part3 .= $this->writeCountry();
- }
- $part3 .= $this->writeRecalcId();
-
- $part3 .= $this->writeSupbookInternal();
- /* TODO: store external SUPBOOK records and XCT and CRN records
- in case of external references for BIFF8 */
- $part3 .= $this->writeExternalsheetBiff8();
- $part3 .= $this->writeAllDefinedNamesBiff8();
- $part3 .= $this->writeMsoDrawingGroup();
- $part3 .= $this->writeSharedStringsTable();
-
- $part3 .= $this->writeEof();
-
- // Add part 2 of the Workbook globals, the SHEET records
- $this->calcSheetOffsets();
- for ($i = 0; $i < $total_worksheets; ++$i) {
- $this->writeBoundSheet($this->spreadsheet->getSheet($i), $this->worksheetOffsets[$i]);
- }
-
- // Add part 3 of the Workbook globals
- $this->_data .= $part3;
-
- return $this->_data;
- }
-
- /**
- * Calculate offsets for Worksheet BOF records.
- */
- private function calcSheetOffsets(): void
- {
- $boundsheet_length = 10; // fixed length for a BOUNDSHEET record
-
- // size of Workbook globals part 1 + 3
- $offset = $this->_datasize;
-
- // add size of Workbook globals part 2, the length of the SHEET records
- $total_worksheets = count($this->spreadsheet->getAllSheets());
- foreach ($this->spreadsheet->getWorksheetIterator() as $sheet) {
- $offset += $boundsheet_length + strlen(StringHelper::UTF8toBIFF8UnicodeShort($sheet->getTitle()));
- }
-
- // add the sizes of each of the Sheet substreams, respectively
- for ($i = 0; $i < $total_worksheets; ++$i) {
- $this->worksheetOffsets[$i] = $offset;
- $offset += $this->worksheetSizes[$i];
- }
- $this->biffSize = $offset;
- }
-
- /**
- * Store the Excel FONT records.
- */
- private function writeAllFonts(): void
- {
- foreach ($this->fontWriters as $fontWriter) {
- $this->append($fontWriter->writeFont());
- }
- }
-
- /**
- * Store user defined numerical formats i.e. FORMAT records.
- */
- private function writeAllNumberFormats(): void
- {
- foreach ($this->numberFormats as $numberFormatIndex => $numberFormat) {
- $this->writeNumberFormat($numberFormat->getFormatCode(), $numberFormatIndex);
- }
- }
-
- /**
- * Write all XF records.
- */
- private function writeAllXfs(): void
- {
- foreach ($this->xfWriters as $xfWriter) {
- $this->append($xfWriter->writeXf());
- }
- }
-
- /**
- * Write all STYLE records.
- */
- private function writeAllStyles(): void
- {
- $this->writeStyle();
- }
-
- private function parseDefinedNameValue(DefinedName $pDefinedName): string
- {
- $definedRange = $pDefinedName->getValue();
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_CELLREF . '/mui',
- $definedRange,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
-
- $worksheets = $splitRanges[2];
- $columns = $splitRanges[6];
- $rows = $splitRanges[7];
-
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $worksheet = $worksheets[$splitCount][0];
- $column = $columns[$splitCount][0];
- $row = $rows[$splitCount][0];
-
- $newRange = '';
- if (empty($worksheet)) {
- if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
- // We need a worksheet
- $worksheet = $pDefinedName->getWorksheet()->getTitle();
- }
- } else {
- $worksheet = str_replace("''", "'", trim($worksheet, "'"));
- }
- if (!empty($worksheet)) {
- $newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
- }
-
- if (!empty($column)) {
- $newRange .= "\${$column}";
- }
- if (!empty($row)) {
- $newRange .= "\${$row}";
- }
-
- $definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
- }
-
- return $definedRange;
- }
-
- /**
- * Writes all the DEFINEDNAME records (BIFF8).
- * So far this is only used for repeating rows/columns (print titles) and print areas.
- */
- private function writeAllDefinedNamesBiff8()
- {
- $chunk = '';
-
- // Named ranges
- $definedNames = $this->spreadsheet->getDefinedNames();
- if (count($definedNames) > 0) {
- // Loop named ranges
- foreach ($definedNames as $definedName) {
- $range = $this->parseDefinedNameValue($definedName);
-
- // parse formula
- try {
- $error = $this->parser->parse($range);
- $formulaData = $this->parser->toReversePolish();
-
- // make sure tRef3d is of type tRef3dR (0x3A)
- if (isset($formulaData[0]) && ($formulaData[0] == "\x7A" || $formulaData[0] == "\x5A")) {
- $formulaData = "\x3A" . substr($formulaData, 1);
- }
-
- if ($definedName->getLocalOnly()) {
- // local scope
- $scope = $this->spreadsheet->getIndex($definedName->getScope()) + 1;
- } else {
- // global scope
- $scope = 0;
- }
- $chunk .= $this->writeData($this->writeDefinedNameBiff8($definedName->getName(), $formulaData, $scope, false));
- } catch (PhpSpreadsheetException $e) {
- // do nothing
- }
- }
- }
-
- // total number of sheets
- $total_worksheets = $this->spreadsheet->getSheetCount();
-
- // write the print titles (repeating rows, columns), if any
- for ($i = 0; $i < $total_worksheets; ++$i) {
- $sheetSetup = $this->spreadsheet->getSheet($i)->getPageSetup();
- // simultaneous repeatColumns repeatRows
- if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) {
- $repeat = $sheetSetup->getColumnsToRepeatAtLeft();
- $colmin = Coordinate::columnIndexFromString($repeat[0]) - 1;
- $colmax = Coordinate::columnIndexFromString($repeat[1]) - 1;
-
- $repeat = $sheetSetup->getRowsToRepeatAtTop();
- $rowmin = $repeat[0] - 1;
- $rowmax = $repeat[1] - 1;
-
- // construct formula data manually
- $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc
- $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d
- $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d
- $formulaData .= pack('C', 0x10); // tList
-
- // store the DEFINEDNAME record
- $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true));
-
- // (exclusive) either repeatColumns or repeatRows
- } elseif ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) {
- // Columns to repeat
- if ($sheetSetup->isColumnsToRepeatAtLeftSet()) {
- $repeat = $sheetSetup->getColumnsToRepeatAtLeft();
- $colmin = Coordinate::columnIndexFromString($repeat[0]) - 1;
- $colmax = Coordinate::columnIndexFromString($repeat[1]) - 1;
- } else {
- $colmin = 0;
- $colmax = 255;
- }
- // Rows to repeat
- if ($sheetSetup->isRowsToRepeatAtTopSet()) {
- $repeat = $sheetSetup->getRowsToRepeatAtTop();
- $rowmin = $repeat[0] - 1;
- $rowmax = $repeat[1] - 1;
- } else {
- $rowmin = 0;
- $rowmax = 65535;
- }
-
- // construct formula data manually because parser does not recognize absolute 3d cell references
- $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax);
-
- // store the DEFINEDNAME record
- $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true));
- }
- }
-
- // write the print areas, if any
- for ($i = 0; $i < $total_worksheets; ++$i) {
- $sheetSetup = $this->spreadsheet->getSheet($i)->getPageSetup();
- if ($sheetSetup->isPrintAreaSet()) {
- // Print area, e.g. A3:J6,H1:X20
- $printArea = Coordinate::splitRange($sheetSetup->getPrintArea());
- $countPrintArea = count($printArea);
-
- $formulaData = '';
- for ($j = 0; $j < $countPrintArea; ++$j) {
- $printAreaRect = $printArea[$j]; // e.g. A3:J6
- $printAreaRect[0] = Coordinate::coordinateFromString($printAreaRect[0]);
- $printAreaRect[1] = Coordinate::coordinateFromString($printAreaRect[1]);
-
- $print_rowmin = $printAreaRect[0][1] - 1;
- $print_rowmax = $printAreaRect[1][1] - 1;
- $print_colmin = Coordinate::columnIndexFromString($printAreaRect[0][0]) - 1;
- $print_colmax = Coordinate::columnIndexFromString($printAreaRect[1][0]) - 1;
-
- // construct formula data manually because parser does not recognize absolute 3d cell references
- $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax);
-
- if ($j > 0) {
- $formulaData .= pack('C', 0x10); // list operator token ','
- }
- }
-
- // store the DEFINEDNAME record
- $chunk .= $this->writeData($this->writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true));
- }
- }
-
- // write autofilters, if any
- for ($i = 0; $i < $total_worksheets; ++$i) {
- $sheetAutoFilter = $this->spreadsheet->getSheet($i)->getAutoFilter();
- $autoFilterRange = $sheetAutoFilter->getRange();
- if (!empty($autoFilterRange)) {
- $rangeBounds = Coordinate::rangeBoundaries($autoFilterRange);
-
- //Autofilter built in name
- $name = pack('C', 0x0D);
-
- $chunk .= $this->writeData($this->writeShortNameBiff8($name, $i + 1, $rangeBounds, true));
- }
- }
-
- return $chunk;
- }
-
- /**
- * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data.
- *
- * @param string $name The name in UTF-8
- * @param string $formulaData The binary formula data
- * @param int $sheetIndex 1-based sheet index the defined name applies to. 0 = global
- * @param bool $isBuiltIn Built-in name?
- *
- * @return string Complete binary record data
- */
- private function writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false)
- {
- $record = 0x0018;
-
- // option flags
- $options = $isBuiltIn ? 0x20 : 0x00;
-
- // length of the name, character count
- $nlen = StringHelper::countCharacters($name);
-
- // name with stripped length field
- $name = substr(StringHelper::UTF8toBIFF8UnicodeLong($name), 2);
-
- // size of the formula (in bytes)
- $sz = strlen($formulaData);
-
- // combine the parts
- $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0)
- . $name . $formulaData;
- $length = strlen($data);
-
- $header = pack('vv', $record, $length);
-
- return $header . $data;
- }
-
- /**
- * Write a short NAME record.
- *
- * @param string $name
- * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global
- * @param integer[][] $rangeBounds range boundaries
- * @param bool $isHidden
- *
- * @return string Complete binary record data
- * */
- private function writeShortNameBiff8($name, $sheetIndex, $rangeBounds, $isHidden = false)
- {
- $record = 0x0018;
-
- // option flags
- $options = ($isHidden ? 0x21 : 0x00);
-
- $extra = pack(
- 'Cvvvvv',
- 0x3B,
- $sheetIndex - 1,
- $rangeBounds[0][1] - 1,
- $rangeBounds[1][1] - 1,
- $rangeBounds[0][0] - 1,
- $rangeBounds[1][0] - 1
- );
-
- // size of the formula (in bytes)
- $sz = strlen($extra);
-
- // combine the parts
- $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0)
- . $name . $extra;
- $length = strlen($data);
-
- $header = pack('vv', $record, $length);
-
- return $header . $data;
- }
-
- /**
- * Stores the CODEPAGE biff record.
- */
- private function writeCodepage(): void
- {
- $record = 0x0042; // Record identifier
- $length = 0x0002; // Number of bytes to follow
- $cv = $this->codepage; // The code page
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $cv);
-
- $this->append($header . $data);
- }
-
- /**
- * Write Excel BIFF WINDOW1 record.
- */
- private function writeWindow1(): void
- {
- $record = 0x003D; // Record identifier
- $length = 0x0012; // Number of bytes to follow
-
- $xWn = 0x0000; // Horizontal position of window
- $yWn = 0x0000; // Vertical position of window
- $dxWn = 0x25BC; // Width of window
- $dyWn = 0x1572; // Height of window
-
- $grbit = 0x0038; // Option flags
-
- // not supported by PhpSpreadsheet, so there is only one selected sheet, the active
- $ctabsel = 1; // Number of workbook tabs selected
-
- $wTabRatio = 0x0258; // Tab to scrollbar ratio
-
- // not supported by PhpSpreadsheet, set to 0
- $itabFirst = 0; // 1st displayed worksheet
- $itabCur = $this->spreadsheet->getActiveSheetIndex(); // Active worksheet
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvvvvvvv', $xWn, $yWn, $dxWn, $dyWn, $grbit, $itabCur, $itabFirst, $ctabsel, $wTabRatio);
- $this->append($header . $data);
- }
-
- /**
- * Writes Excel BIFF BOUNDSHEET record.
- *
- * @param Worksheet $sheet Worksheet name
- * @param int $offset Location of worksheet BOF
- */
- private function writeBoundSheet($sheet, $offset): void
- {
- $sheetname = $sheet->getTitle();
- $record = 0x0085; // Record identifier
-
- // sheet state
- switch ($sheet->getSheetState()) {
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_VISIBLE:
- $ss = 0x00;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_HIDDEN:
- $ss = 0x01;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::SHEETSTATE_VERYHIDDEN:
- $ss = 0x02;
-
- break;
- default:
- $ss = 0x00;
-
- break;
- }
-
- // sheet type
- $st = 0x00;
-
- $grbit = 0x0000; // Visibility and sheet type
-
- $data = pack('VCC', $offset, $ss, $st);
- $data .= StringHelper::UTF8toBIFF8UnicodeShort($sheetname);
-
- $length = strlen($data);
- $header = pack('vv', $record, $length);
- $this->append($header . $data);
- }
-
- /**
- * Write Internal SUPBOOK record.
- */
- private function writeSupbookInternal()
- {
- $record = 0x01AE; // Record identifier
- $length = 0x0004; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('vv', $this->spreadsheet->getSheetCount(), 0x0401);
-
- return $this->writeData($header . $data);
- }
-
- /**
- * Writes the Excel BIFF EXTERNSHEET record. These references are used by
- * formulas.
- */
- private function writeExternalsheetBiff8()
- {
- $totalReferences = count($this->parser->references);
- $record = 0x0017; // Record identifier
- $length = 2 + 6 * $totalReferences; // Number of bytes to follow
-
- $supbook_index = 0; // FIXME: only using internal SUPBOOK record
- $header = pack('vv', $record, $length);
- $data = pack('v', $totalReferences);
- for ($i = 0; $i < $totalReferences; ++$i) {
- $data .= $this->parser->references[$i];
- }
-
- return $this->writeData($header . $data);
- }
-
- /**
- * Write Excel BIFF STYLE records.
- */
- private function writeStyle(): void
- {
- $record = 0x0293; // Record identifier
- $length = 0x0004; // Bytes to follow
-
- $ixfe = 0x8000; // Index to cell style XF
- $BuiltIn = 0x00; // Built-in style
- $iLevel = 0xff; // Outline style level
-
- $header = pack('vv', $record, $length);
- $data = pack('vCC', $ixfe, $BuiltIn, $iLevel);
- $this->append($header . $data);
- }
-
- /**
- * Writes Excel FORMAT record for non "built-in" numerical formats.
- *
- * @param string $format Custom format string
- * @param int $ifmt Format index code
- */
- private function writeNumberFormat($format, $ifmt): void
- {
- $record = 0x041E; // Record identifier
-
- $numberFormatString = StringHelper::UTF8toBIFF8UnicodeLong($format);
- $length = 2 + strlen($numberFormatString); // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $ifmt) . $numberFormatString;
- $this->append($header . $data);
- }
-
- /**
- * Write DATEMODE record to indicate the date system in use (1904 or 1900).
- */
- private function writeDateMode(): void
- {
- $record = 0x0022; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $f1904 = (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904)
- ? 1
- : 0; // Flag for 1904 date system
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $f1904);
- $this->append($header . $data);
- }
-
- /**
- * Stores the COUNTRY record for localization.
- *
- * @return string
- */
- private function writeCountry()
- {
- $record = 0x008C; // Record identifier
- $length = 4; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- // using the same country code always for simplicity
- $data = pack('vv', $this->countryCode, $this->countryCode);
-
- return $this->writeData($header . $data);
- }
-
- /**
- * Write the RECALCID record.
- *
- * @return string
- */
- private function writeRecalcId()
- {
- $record = 0x01C1; // Record identifier
- $length = 8; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
-
- // by inspection of real Excel files, MS Office Excel 2007 writes this
- $data = pack('VV', 0x000001C1, 0x00001E667);
-
- return $this->writeData($header . $data);
- }
-
- /**
- * Stores the PALETTE biff record.
- */
- private function writePalette(): void
- {
- $aref = $this->palette;
-
- $record = 0x0092; // Record identifier
- $length = 2 + 4 * count($aref); // Number of bytes to follow
- $ccv = count($aref); // Number of RGB values to follow
- $data = ''; // The RGB data
-
- // Pack the RGB data
- foreach ($aref as $color) {
- foreach ($color as $byte) {
- $data .= pack('C', $byte);
- }
- }
-
- $header = pack('vvv', $record, $length, $ccv);
- $this->append($header . $data);
- }
-
- /**
- * Handling of the SST continue blocks is complicated by the need to include an
- * additional continuation byte depending on whether the string is split between
- * blocks or whether it starts at the beginning of the block. (There are also
- * additional complications that will arise later when/if Rich Strings are
- * supported).
- *
- * The Excel documentation says that the SST record should be followed by an
- * EXTSST record. The EXTSST record is a hash table that is used to optimise
- * access to SST. However, despite the documentation it doesn't seem to be
- * required so we will ignore it.
- *
- * @return string Binary data
- */
- private function writeSharedStringsTable()
- {
- // maximum size of record data (excluding record header)
- $continue_limit = 8224;
-
- // initialize array of record data blocks
- $recordDatas = [];
-
- // start SST record data block with total number of strings, total number of unique strings
- $recordData = pack('VV', $this->stringTotal, $this->stringUnique);
-
- // loop through all (unique) strings in shared strings table
- foreach (array_keys($this->stringTable) as $string) {
- // here $string is a BIFF8 encoded string
-
- // length = character count
- $headerinfo = unpack('vlength/Cencoding', $string);
-
- // currently, this is always 1 = uncompressed
- $encoding = $headerinfo['encoding'];
-
- // initialize finished writing current $string
- $finished = false;
-
- while ($finished === false) {
- // normally, there will be only one cycle, but if string cannot immediately be written as is
- // there will be need for more than one cylcle, if string longer than one record data block, there
- // may be need for even more cycles
-
- if (strlen($recordData) + strlen($string) <= $continue_limit) {
- // then we can write the string (or remainder of string) without any problems
- $recordData .= $string;
-
- if (strlen($recordData) + strlen($string) == $continue_limit) {
- // we close the record data block, and initialize a new one
- $recordDatas[] = $recordData;
- $recordData = '';
- }
-
- // we are finished writing this string
- $finished = true;
- } else {
- // special treatment writing the string (or remainder of the string)
- // If the string is very long it may need to be written in more than one CONTINUE record.
-
- // check how many bytes more there is room for in the current record
- $space_remaining = $continue_limit - strlen($recordData);
-
- // minimum space needed
- // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character
- // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character
- $min_space_needed = ($encoding == 1) ? 5 : 4;
-
- // We have two cases
- // 1. space remaining is less than minimum space needed
- // here we must waste the space remaining and move to next record data block
- // 2. space remaining is greater than or equal to minimum space needed
- // here we write as much as we can in the current block, then move to next record data block
-
- // 1. space remaining is less than minimum space needed
- if ($space_remaining < $min_space_needed) {
- // we close the block, store the block data
- $recordDatas[] = $recordData;
-
- // and start new record data block where we start writing the string
- $recordData = '';
-
- // 2. space remaining is greater than or equal to minimum space needed
- } else {
- // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below
- $effective_space_remaining = $space_remaining;
-
- // for uncompressed strings, sometimes effective space remaining is reduced by 1
- if ($encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1) {
- --$effective_space_remaining;
- }
-
- // one block fininshed, store the block data
- $recordData .= substr($string, 0, $effective_space_remaining);
-
- $string = substr($string, $effective_space_remaining); // for next cycle in while loop
- $recordDatas[] = $recordData;
-
- // start new record data block with the repeated option flags
- $recordData = pack('C', $encoding);
- }
- }
- }
- }
-
- // Store the last record data block unless it is empty
- // if there was no need for any continue records, this will be the for SST record data block itself
- if (strlen($recordData) > 0) {
- $recordDatas[] = $recordData;
- }
-
- // combine into one chunk with all the blocks SST, CONTINUE,...
- $chunk = '';
- foreach ($recordDatas as $i => $recordData) {
- // first block should have the SST record header, remaing should have CONTINUE header
- $record = ($i == 0) ? 0x00FC : 0x003C;
-
- $header = pack('vv', $record, strlen($recordData));
- $data = $header . $recordData;
-
- $chunk .= $this->writeData($data);
- }
-
- return $chunk;
- }
-
- /**
- * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records.
- */
- private function writeMsoDrawingGroup()
- {
- // write the Escher stream if necessary
- if (isset($this->escher)) {
- $writer = new Escher($this->escher);
- $data = $writer->close();
-
- $record = 0x00EB;
- $length = strlen($data);
- $header = pack('vv', $record, $length);
-
- return $this->writeData($header . $data);
- }
-
- return '';
- }
-
- /**
- * Get Escher object.
- *
- * @return \PhpOffice\PhpSpreadsheet\Shared\Escher
- */
- public function getEscher()
- {
- return $this->escher;
- }
-
- /**
- * Set Escher object.
- *
- * @param \PhpOffice\PhpSpreadsheet\Shared\Escher $pValue
- */
- public function setEscher(?\PhpOffice\PhpSpreadsheet\Shared\Escher $pValue = null): void
- {
- $this->escher = $pValue;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Worksheet.php b/vendor/PhpSpreadsheet/Writer/Xls/Worksheet.php
deleted file mode 100644
index a1c258c..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Worksheet.php
+++ /dev/null
@@ -1,4490 +0,0 @@
-
-// *
-// * The majority of this is _NOT_ my code. I simply ported it from the
-// * PERL Spreadsheet::WriteExcel module.
-// *
-// * The author of the Spreadsheet::WriteExcel module is John McNamara
-// *
-// *
-// * I _DO_ maintain this code, and John McNamara has nothing to do with the
-// * porting of this code to PHP. Any questions directly related to this
-// * class library should be directed to me.
-// *
-// * License Information:
-// *
-// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
-// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com
-// *
-// * This library is free software; you can redistribute it and/or
-// * modify it under the terms of the GNU Lesser General Public
-// * License as published by the Free Software Foundation; either
-// * version 2.1 of the License, or (at your option) any later version.
-// *
-// * This library is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// * Lesser General Public License for more details.
-// *
-// * You should have received a copy of the GNU Lesser General Public
-// * License along with this library; if not, write to the Free Software
-// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-// */
-class Worksheet extends BIFFwriter
-{
- /**
- * Formula parser.
- *
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Parser
- */
- private $parser;
-
- /**
- * Maximum number of characters for a string (LABEL record in BIFF5).
- *
- * @var int
- */
- private $xlsStringMaxLength;
-
- /**
- * Array containing format information for columns.
- *
- * @var array
- */
- private $columnInfo;
-
- /**
- * Array containing the selected area for the worksheet.
- *
- * @var array
- */
- private $selection;
-
- /**
- * The active pane for the worksheet.
- *
- * @var int
- */
- private $activePane;
-
- /**
- * Whether to use outline.
- *
- * @var int
- */
- private $outlineOn;
-
- /**
- * Auto outline styles.
- *
- * @var bool
- */
- private $outlineStyle;
-
- /**
- * Whether to have outline summary below.
- *
- * @var bool
- */
- private $outlineBelow;
-
- /**
- * Whether to have outline summary at the right.
- *
- * @var bool
- */
- private $outlineRight;
-
- /**
- * Reference to the total number of strings in the workbook.
- *
- * @var int
- */
- private $stringTotal;
-
- /**
- * Reference to the number of unique strings in the workbook.
- *
- * @var int
- */
- private $stringUnique;
-
- /**
- * Reference to the array containing all the unique strings in the workbook.
- *
- * @var array
- */
- private $stringTable;
-
- /**
- * Color cache.
- */
- private $colors;
-
- /**
- * Index of first used row (at least 0).
- *
- * @var int
- */
- private $firstRowIndex;
-
- /**
- * Index of last used row. (no used rows means -1).
- *
- * @var int
- */
- private $lastRowIndex;
-
- /**
- * Index of first used column (at least 0).
- *
- * @var int
- */
- private $firstColumnIndex;
-
- /**
- * Index of last used column (no used columns means -1).
- *
- * @var int
- */
- private $lastColumnIndex;
-
- /**
- * Sheet object.
- *
- * @var \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
- */
- public $phpSheet;
-
- /**
- * Count cell style Xfs.
- *
- * @var int
- */
- private $countCellStyleXfs;
-
- /**
- * Escher object corresponding to MSODRAWING.
- *
- * @var \PhpOffice\PhpSpreadsheet\Shared\Escher
- */
- private $escher;
-
- /**
- * Array of font hashes associated to FONT records index.
- *
- * @var array
- */
- public $fontHashIndex;
-
- /**
- * @var bool
- */
- private $preCalculateFormulas;
-
- /**
- * @var int
- */
- private $printHeaders;
-
- /**
- * Constructor.
- *
- * @param int $str_total Total number of strings
- * @param int $str_unique Total number of unique strings
- * @param array &$str_table String Table
- * @param array &$colors Colour Table
- * @param Parser $parser The formula parser created for the Workbook
- * @param bool $preCalculateFormulas Flag indicating whether formulas should be calculated or just written
- * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet The worksheet to write
- */
- public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, Parser $parser, $preCalculateFormulas, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet)
- {
- // It needs to call its parent's constructor explicitly
- parent::__construct();
-
- $this->preCalculateFormulas = $preCalculateFormulas;
- $this->stringTotal = &$str_total;
- $this->stringUnique = &$str_unique;
- $this->stringTable = &$str_table;
- $this->colors = &$colors;
- $this->parser = $parser;
-
- $this->phpSheet = $phpSheet;
-
- $this->xlsStringMaxLength = 255;
- $this->columnInfo = [];
- $this->selection = [0, 0, 0, 0];
- $this->activePane = 3;
-
- $this->printHeaders = 0;
-
- $this->outlineStyle = 0;
- $this->outlineBelow = 1;
- $this->outlineRight = 1;
- $this->outlineOn = 1;
-
- $this->fontHashIndex = [];
-
- // calculate values for DIMENSIONS record
- $minR = 1;
- $minC = 'A';
-
- $maxR = $this->phpSheet->getHighestRow();
- $maxC = $this->phpSheet->getHighestColumn();
-
- // Determine lowest and highest column and row
- $this->lastRowIndex = ($maxR > 65535) ? 65535 : $maxR;
-
- $this->firstColumnIndex = Coordinate::columnIndexFromString($minC);
- $this->lastColumnIndex = Coordinate::columnIndexFromString($maxC);
-
-// if ($this->firstColumnIndex > 255) $this->firstColumnIndex = 255;
- if ($this->lastColumnIndex > 255) {
- $this->lastColumnIndex = 255;
- }
-
- $this->countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection());
- }
-
- /**
- * Add data to the beginning of the workbook (note the reverse order)
- * and to the end of the workbook.
- *
- * @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::storeWorkbook()
- */
- public function close(): void
- {
- $phpSheet = $this->phpSheet;
-
- // Storing selected cells and active sheet because it changes while parsing cells with formulas.
- $selectedCells = $this->phpSheet->getSelectedCells();
- $activeSheetIndex = $this->phpSheet->getParent()->getActiveSheetIndex();
-
- // Write BOF record
- $this->storeBof(0x0010);
-
- // Write PRINTHEADERS
- $this->writePrintHeaders();
-
- // Write PRINTGRIDLINES
- $this->writePrintGridlines();
-
- // Write GRIDSET
- $this->writeGridset();
-
- // Calculate column widths
- $phpSheet->calculateColumnWidths();
-
- // Column dimensions
- if (($defaultWidth = $phpSheet->getDefaultColumnDimension()->getWidth()) < 0) {
- $defaultWidth = \PhpOffice\PhpSpreadsheet\Shared\Font::getDefaultColumnWidthByFont($phpSheet->getParent()->getDefaultStyle()->getFont());
- }
-
- $columnDimensions = $phpSheet->getColumnDimensions();
- $maxCol = $this->lastColumnIndex - 1;
- for ($i = 0; $i <= $maxCol; ++$i) {
- $hidden = 0;
- $level = 0;
- $xfIndex = 15; // there are 15 cell style Xfs
-
- $width = $defaultWidth;
-
- $columnLetter = Coordinate::stringFromColumnIndex($i + 1);
- if (isset($columnDimensions[$columnLetter])) {
- $columnDimension = $columnDimensions[$columnLetter];
- if ($columnDimension->getWidth() >= 0) {
- $width = $columnDimension->getWidth();
- }
- $hidden = $columnDimension->getVisible() ? 0 : 1;
- $level = $columnDimension->getOutlineLevel();
- $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs
- }
-
- // Components of columnInfo:
- // $firstcol first column on the range
- // $lastcol last column on the range
- // $width width to set
- // $xfIndex The optional cell style Xf index to apply to the columns
- // $hidden The optional hidden atribute
- // $level The optional outline level
- $this->columnInfo[] = [$i, $i, $width, $xfIndex, $hidden, $level];
- }
-
- // Write GUTS
- $this->writeGuts();
-
- // Write DEFAULTROWHEIGHT
- $this->writeDefaultRowHeight();
- // Write WSBOOL
- $this->writeWsbool();
- // Write horizontal and vertical page breaks
- $this->writeBreaks();
- // Write page header
- $this->writeHeader();
- // Write page footer
- $this->writeFooter();
- // Write page horizontal centering
- $this->writeHcenter();
- // Write page vertical centering
- $this->writeVcenter();
- // Write left margin
- $this->writeMarginLeft();
- // Write right margin
- $this->writeMarginRight();
- // Write top margin
- $this->writeMarginTop();
- // Write bottom margin
- $this->writeMarginBottom();
- // Write page setup
- $this->writeSetup();
- // Write sheet protection
- $this->writeProtect();
- // Write SCENPROTECT
- $this->writeScenProtect();
- // Write OBJECTPROTECT
- $this->writeObjectProtect();
- // Write sheet password
- $this->writePassword();
- // Write DEFCOLWIDTH record
- $this->writeDefcol();
-
- // Write the COLINFO records if they exist
- if (!empty($this->columnInfo)) {
- $colcount = count($this->columnInfo);
- for ($i = 0; $i < $colcount; ++$i) {
- $this->writeColinfo($this->columnInfo[$i]);
- }
- }
- $autoFilterRange = $phpSheet->getAutoFilter()->getRange();
- if (!empty($autoFilterRange)) {
- // Write AUTOFILTERINFO
- $this->writeAutoFilterInfo();
- }
-
- // Write sheet dimensions
- $this->writeDimensions();
-
- // Row dimensions
- foreach ($phpSheet->getRowDimensions() as $rowDimension) {
- $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs
- $this->writeRow($rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel());
- }
-
- // Write Cells
- foreach ($phpSheet->getCoordinates() as $coordinate) {
- $cell = $phpSheet->getCell($coordinate);
- $row = $cell->getRow() - 1;
- $column = Coordinate::columnIndexFromString($cell->getColumn()) - 1;
-
- // Don't break Excel break the code!
- if ($row > 65535 || $column > 255) {
- throw new WriterException('Rows or columns overflow! Excel5 has limit to 65535 rows and 255 columns. Use XLSX instead.');
- }
-
- // Write cell value
- $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs
-
- $cVal = $cell->getValue();
- if ($cVal instanceof RichText) {
- $arrcRun = [];
- $str_len = StringHelper::countCharacters($cVal->getPlainText(), 'UTF-8');
- $str_pos = 0;
- $elements = $cVal->getRichTextElements();
- foreach ($elements as $element) {
- // FONT Index
- if ($element instanceof Run) {
- $str_fontidx = $this->fontHashIndex[$element->getFont()->getHashCode()];
- } else {
- $str_fontidx = 0;
- }
- $arrcRun[] = ['strlen' => $str_pos, 'fontidx' => $str_fontidx];
- // Position FROM
- $str_pos += StringHelper::countCharacters($element->getText(), 'UTF-8');
- }
- $this->writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun);
- } else {
- switch ($cell->getDatatype()) {
- case DataType::TYPE_STRING:
- case DataType::TYPE_NULL:
- if ($cVal === '' || $cVal === null) {
- $this->writeBlank($row, $column, $xfIndex);
- } else {
- $this->writeString($row, $column, $cVal, $xfIndex);
- }
-
- break;
- case DataType::TYPE_NUMERIC:
- $this->writeNumber($row, $column, $cVal, $xfIndex);
-
- break;
- case DataType::TYPE_FORMULA:
- $calculatedValue = $this->preCalculateFormulas ?
- $cell->getCalculatedValue() : null;
- if (self::WRITE_FORMULA_EXCEPTION == $this->writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue)) {
- if ($calculatedValue === null) {
- $calculatedValue = $cell->getCalculatedValue();
- }
- $calctype = gettype($calculatedValue);
- switch ($calctype) {
- case 'integer':
- case 'double':
- $this->writeNumber($row, $column, $calculatedValue, $xfIndex);
-
- break;
- case 'string':
- $this->writeString($row, $column, $calculatedValue, $xfIndex);
-
- break;
- case 'boolean':
- $this->writeBoolErr($row, $column, $calculatedValue, 0, $xfIndex);
-
- break;
- default:
- $this->writeString($row, $column, $cVal, $xfIndex);
- }
- }
-
- break;
- case DataType::TYPE_BOOL:
- $this->writeBoolErr($row, $column, $cVal, 0, $xfIndex);
-
- break;
- case DataType::TYPE_ERROR:
- $this->writeBoolErr($row, $column, self::mapErrorCode($cVal), 1, $xfIndex);
-
- break;
- }
- }
- }
-
- // Append
- $this->writeMsoDrawing();
-
- // Restoring active sheet.
- $this->phpSheet->getParent()->setActiveSheetIndex($activeSheetIndex);
-
- // Write WINDOW2 record
- $this->writeWindow2();
-
- // Write PLV record
- $this->writePageLayoutView();
-
- // Write ZOOM record
- $this->writeZoom();
- if ($phpSheet->getFreezePane()) {
- $this->writePanes();
- }
-
- // Restoring selected cells.
- $this->phpSheet->setSelectedCells($selectedCells);
-
- // Write SELECTION record
- $this->writeSelection();
-
- // Write MergedCellsTable Record
- $this->writeMergedCells();
-
- // Hyperlinks
- foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) {
- [$column, $row] = Coordinate::coordinateFromString($coordinate);
-
- $url = $hyperlink->getUrl();
-
- if (strpos($url, 'sheet://') !== false) {
- // internal to current workbook
- $url = str_replace('sheet://', 'internal:', $url);
- } elseif (preg_match('/^(http:|https:|ftp:|mailto:)/', $url)) {
- // URL
- } else {
- // external (local file)
- $url = 'external:' . $url;
- }
-
- $this->writeUrl($row - 1, Coordinate::columnIndexFromString($column) - 1, $url);
- }
-
- $this->writeDataValidity();
- $this->writeSheetLayout();
-
- // Write SHEETPROTECTION record
- $this->writeSheetProtection();
- $this->writeRangeProtection();
-
- $arrConditionalStyles = $phpSheet->getConditionalStylesCollection();
- if (!empty($arrConditionalStyles)) {
- $arrConditional = [];
- // @TODO CFRule & CFHeader
- // Write CFHEADER record
- $this->writeCFHeader();
- // Write ConditionalFormattingTable records
- foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) {
- foreach ($conditionalStyles as $conditional) {
- if (
- $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
- || $conditional->getConditionType() == Conditional::CONDITION_CELLIS
- ) {
- if (!isset($arrConditional[$conditional->getHashCode()])) {
- // This hash code has been handled
- $arrConditional[$conditional->getHashCode()] = true;
-
- // Write CFRULE record
- $this->writeCFRule($conditional);
- }
- }
- }
- }
- }
-
- $this->storeEof();
- }
-
- /**
- * Write a cell range address in BIFF8
- * always fixed range
- * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format.
- *
- * @param string $range E.g. 'A1' or 'A1:B6'
- *
- * @return string Binary data
- */
- private function writeBIFF8CellRangeAddressFixed($range)
- {
- $explodes = explode(':', $range);
-
- // extract first cell, e.g. 'A1'
- $firstCell = $explodes[0];
-
- // extract last cell, e.g. 'B6'
- if (count($explodes) == 1) {
- $lastCell = $firstCell;
- } else {
- $lastCell = $explodes[1];
- }
-
- $firstCellCoordinates = Coordinate::coordinateFromString($firstCell); // e.g. [0, 1]
- $lastCellCoordinates = Coordinate::coordinateFromString($lastCell); // e.g. [1, 6]
-
- return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, Coordinate::columnIndexFromString($firstCellCoordinates[0]) - 1, Coordinate::columnIndexFromString($lastCellCoordinates[0]) - 1);
- }
-
- /**
- * Retrieves data from memory in one chunk, or from disk in $buffer
- * sized chunks.
- *
- * @return string The data
- */
- public function getData()
- {
- $buffer = 4096;
-
- // Return data stored in memory
- if (isset($this->_data)) {
- $tmp = $this->_data;
- $this->_data = null;
-
- return $tmp;
- }
-
- // No data to return
- return false;
- }
-
- /**
- * Set the option to print the row and column headers on the printed page.
- *
- * @param int $print Whether to print the headers or not. Defaults to 1 (print).
- */
- public function printRowColHeaders($print = 1): void
- {
- $this->printHeaders = $print;
- }
-
- /**
- * This method sets the properties for outlining and grouping. The defaults
- * correspond to Excel's defaults.
- *
- * @param bool $visible
- * @param bool $symbols_below
- * @param bool $symbols_right
- * @param bool $auto_style
- */
- public function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false): void
- {
- $this->outlineOn = $visible;
- $this->outlineBelow = $symbols_below;
- $this->outlineRight = $symbols_right;
- $this->outlineStyle = $auto_style;
-
- // Ensure this is a boolean vale for Window2
- if ($this->outlineOn) {
- $this->outlineOn = 1;
- }
- }
-
- /**
- * Write a double to the specified row and column (zero indexed).
- * An integer can be written as a double. Excel will display an
- * integer. $format is optional.
- *
- * Returns 0 : normal termination
- * -2 : row or column out of range
- *
- * @param int $row Zero indexed row
- * @param int $col Zero indexed column
- * @param float $num The number to write
- * @param mixed $xfIndex The optional XF format
- *
- * @return int
- */
- private function writeNumber($row, $col, $num, $xfIndex)
- {
- $record = 0x0203; // Record identifier
- $length = 0x000E; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('vvv', $row, $col, $xfIndex);
- $xl_double = pack('d', $num);
- if (self::getByteOrder()) { // if it's Big Endian
- $xl_double = strrev($xl_double);
- }
-
- $this->append($header . $data . $xl_double);
-
- return 0;
- }
-
- /**
- * Write a LABELSST record or a LABEL record. Which one depends on BIFF version.
- *
- * @param int $row Row index (0-based)
- * @param int $col Column index (0-based)
- * @param string $str The string
- * @param int $xfIndex Index to XF record
- */
- private function writeString($row, $col, $str, $xfIndex): void
- {
- $this->writeLabelSst($row, $col, $str, $xfIndex);
- }
-
- /**
- * Write a LABELSST record or a LABEL record. Which one depends on BIFF version
- * It differs from writeString by the writing of rich text strings.
- *
- * @param int $row Row index (0-based)
- * @param int $col Column index (0-based)
- * @param string $str The string
- * @param int $xfIndex The XF format index for the cell
- * @param array $arrcRun Index to Font record and characters beginning
- */
- private function writeRichTextString($row, $col, $str, $xfIndex, $arrcRun): void
- {
- $record = 0x00FD; // Record identifier
- $length = 0x000A; // Bytes to follow
- $str = StringHelper::UTF8toBIFF8UnicodeShort($str, $arrcRun);
-
- // check if string is already present
- if (!isset($this->stringTable[$str])) {
- $this->stringTable[$str] = $this->stringUnique++;
- }
- ++$this->stringTotal;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]);
- $this->append($header . $data);
- }
-
- /**
- * Write a string to the specified row and column (zero indexed).
- * This is the BIFF8 version (no 255 chars limit).
- * $format is optional.
- *
- * @param int $row Zero indexed row
- * @param int $col Zero indexed column
- * @param string $str The string to write
- * @param mixed $xfIndex The XF format index for the cell
- */
- private function writeLabelSst($row, $col, $str, $xfIndex): void
- {
- $record = 0x00FD; // Record identifier
- $length = 0x000A; // Bytes to follow
-
- $str = StringHelper::UTF8toBIFF8UnicodeLong($str);
-
- // check if string is already present
- if (!isset($this->stringTable[$str])) {
- $this->stringTable[$str] = $this->stringUnique++;
- }
- ++$this->stringTotal;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvV', $row, $col, $xfIndex, $this->stringTable[$str]);
- $this->append($header . $data);
- }
-
- /**
- * Write a blank cell to the specified row and column (zero indexed).
- * A blank cell is used to specify formatting without adding a string
- * or a number.
- *
- * A blank cell without a format serves no purpose. Therefore, we don't write
- * a BLANK record unless a format is specified.
- *
- * Returns 0 : normal termination (including no format)
- * -1 : insufficient number of arguments
- * -2 : row or column out of range
- *
- * @param int $row Zero indexed row
- * @param int $col Zero indexed column
- * @param mixed $xfIndex The XF format index
- *
- * @return int
- */
- public function writeBlank($row, $col, $xfIndex)
- {
- $record = 0x0201; // Record identifier
- $length = 0x0006; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('vvv', $row, $col, $xfIndex);
- $this->append($header . $data);
-
- return 0;
- }
-
- /**
- * Write a boolean or an error type to the specified row and column (zero indexed).
- *
- * @param int $row Row index (0-based)
- * @param int $col Column index (0-based)
- * @param int $value
- * @param bool $isError Error or Boolean?
- * @param int $xfIndex
- *
- * @return int
- */
- private function writeBoolErr($row, $col, $value, $isError, $xfIndex)
- {
- $record = 0x0205;
- $length = 8;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvCC', $row, $col, $xfIndex, $value, $isError);
- $this->append($header . $data);
-
- return 0;
- }
-
- const WRITE_FORMULA_NORMAL = 0;
- const WRITE_FORMULA_ERRORS = -1;
- const WRITE_FORMULA_RANGE = -2;
- const WRITE_FORMULA_EXCEPTION = -3;
-
- /**
- * Write a formula to the specified row and column (zero indexed).
- * The textual representation of the formula is passed to the parser in
- * Parser.php which returns a packed binary string.
- *
- * Returns 0 : WRITE_FORMULA_NORMAL normal termination
- * -1 : WRITE_FORMULA_ERRORS formula errors (bad formula)
- * -2 : WRITE_FORMULA_RANGE row or column out of range
- * -3 : WRITE_FORMULA_EXCEPTION parse raised exception, probably due to definedname
- *
- * @param int $row Zero indexed row
- * @param int $col Zero indexed column
- * @param string $formula The formula text string
- * @param mixed $xfIndex The XF format index
- * @param mixed $calculatedValue Calculated value
- *
- * @return int
- */
- private function writeFormula($row, $col, $formula, $xfIndex, $calculatedValue)
- {
- $record = 0x0006; // Record identifier
- // Initialize possible additional value for STRING record that should be written after the FORMULA record?
- $stringValue = null;
-
- // calculated value
- if (isset($calculatedValue)) {
- // Since we can't yet get the data type of the calculated value,
- // we use best effort to determine data type
- if (is_bool($calculatedValue)) {
- // Boolean value
- $num = pack('CCCvCv', 0x01, 0x00, (int) $calculatedValue, 0x00, 0x00, 0xFFFF);
- } elseif (is_int($calculatedValue) || is_float($calculatedValue)) {
- // Numeric value
- $num = pack('d', $calculatedValue);
- } elseif (is_string($calculatedValue)) {
- $errorCodes = DataType::getErrorCodes();
- if (isset($errorCodes[$calculatedValue])) {
- // Error value
- $num = pack('CCCvCv', 0x02, 0x00, self::mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF);
- } elseif ($calculatedValue === '') {
- // Empty string (and BIFF8)
- $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF);
- } else {
- // Non-empty string value (or empty string BIFF5)
- $stringValue = $calculatedValue;
- $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF);
- }
- } else {
- // We are really not supposed to reach here
- $num = pack('d', 0x00);
- }
- } else {
- $num = pack('d', 0x00);
- }
-
- $grbit = 0x03; // Option flags
- $unknown = 0x0000; // Must be zero
-
- // Strip the '=' or '@' sign at the beginning of the formula string
- if ($formula[0] == '=') {
- $formula = substr($formula, 1);
- } else {
- // Error handling
- $this->writeString($row, $col, 'Unrecognised character for formula', 0);
-
- return self::WRITE_FORMULA_ERRORS;
- }
-
- // Parse the formula using the parser in Parser.php
- try {
- $error = $this->parser->parse($formula);
- $formula = $this->parser->toReversePolish();
-
- $formlen = strlen($formula); // Length of the binary string
- $length = 0x16 + $formlen; // Length of the record data
-
- $header = pack('vv', $record, $length);
-
- $data = pack('vvv', $row, $col, $xfIndex)
- . $num
- . pack('vVv', $grbit, $unknown, $formlen);
- $this->append($header . $data . $formula);
-
- // Append also a STRING record if necessary
- if ($stringValue !== null) {
- $this->writeStringRecord($stringValue);
- }
-
- return self::WRITE_FORMULA_NORMAL;
- } catch (PhpSpreadsheetException $e) {
- return self::WRITE_FORMULA_EXCEPTION;
- }
- }
-
- /**
- * Write a STRING record. This.
- *
- * @param string $stringValue
- */
- private function writeStringRecord($stringValue): void
- {
- $record = 0x0207; // Record identifier
- $data = StringHelper::UTF8toBIFF8UnicodeLong($stringValue);
-
- $length = strlen($data);
- $header = pack('vv', $record, $length);
-
- $this->append($header . $data);
- }
-
- /**
- * Write a hyperlink.
- * This is comprised of two elements: the visible label and
- * the invisible link. The visible label is the same as the link unless an
- * alternative string is specified. The label is written using the
- * writeString() method. Therefore the 255 characters string limit applies.
- * $string and $format are optional.
- *
- * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external
- * directory url.
- *
- * Returns 0 : normal termination
- * -2 : row or column out of range
- * -3 : long string truncated to 255 chars
- *
- * @param int $row Row
- * @param int $col Column
- * @param string $url URL string
- *
- * @return int
- */
- private function writeUrl($row, $col, $url)
- {
- // Add start row and col to arg list
- return $this->writeUrlRange($row, $col, $row, $col, $url);
- }
-
- /**
- * This is the more general form of writeUrl(). It allows a hyperlink to be
- * written to a range of cells. This function also decides the type of hyperlink
- * to be written. These are either, Web (http, ftp, mailto), Internal
- * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1').
- *
- * @param int $row1 Start row
- * @param int $col1 Start column
- * @param int $row2 End row
- * @param int $col2 End column
- * @param string $url URL string
- *
- * @return int
- *
- * @see writeUrl()
- */
- public function writeUrlRange($row1, $col1, $row2, $col2, $url)
- {
- // Check for internal/external sheet links or default to web link
- if (preg_match('[^internal:]', $url)) {
- return $this->writeUrlInternal($row1, $col1, $row2, $col2, $url);
- }
- if (preg_match('[^external:]', $url)) {
- return $this->writeUrlExternal($row1, $col1, $row2, $col2, $url);
- }
-
- return $this->writeUrlWeb($row1, $col1, $row2, $col2, $url);
- }
-
- /**
- * Used to write http, ftp and mailto hyperlinks.
- * The link type ($options) is 0x03 is the same as absolute dir ref without
- * sheet. However it is differentiated by the $unknown2 data stream.
- *
- * @param int $row1 Start row
- * @param int $col1 Start column
- * @param int $row2 End row
- * @param int $col2 End column
- * @param string $url URL string
- *
- * @return int
- *
- * @see writeUrl()
- */
- public function writeUrlWeb($row1, $col1, $row2, $col2, $url)
- {
- $record = 0x01B8; // Record identifier
- $length = 0x00000; // Bytes to follow
-
- // Pack the undocumented parts of the hyperlink stream
- $unknown1 = pack('H*', 'D0C9EA79F9BACE118C8200AA004BA90B02000000');
- $unknown2 = pack('H*', 'E0C9EA79F9BACE118C8200AA004BA90B');
-
- // Pack the option flags
- $options = pack('V', 0x03);
-
- // Convert URL to a null terminated wchar string
- $url = implode("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY));
- $url = $url . "\0\0\0";
-
- // Pack the length of the URL
- $url_len = pack('V', strlen($url));
-
- // Calculate the data length
- $length = 0x34 + strlen($url);
-
- // Pack the header data
- $header = pack('vv', $record, $length);
- $data = pack('vvvv', $row1, $row2, $col1, $col2);
-
- // Write the packed data
- $this->append($header . $data . $unknown1 . $options . $unknown2 . $url_len . $url);
-
- return 0;
- }
-
- /**
- * Used to write internal reference hyperlinks such as "Sheet1!A1".
- *
- * @param int $row1 Start row
- * @param int $col1 Start column
- * @param int $row2 End row
- * @param int $col2 End column
- * @param string $url URL string
- *
- * @return int
- *
- * @see writeUrl()
- */
- public function writeUrlInternal($row1, $col1, $row2, $col2, $url)
- {
- $record = 0x01B8; // Record identifier
- $length = 0x00000; // Bytes to follow
-
- // Strip URL type
- $url = preg_replace('/^internal:/', '', $url);
-
- // Pack the undocumented parts of the hyperlink stream
- $unknown1 = pack('H*', 'D0C9EA79F9BACE118C8200AA004BA90B02000000');
-
- // Pack the option flags
- $options = pack('V', 0x08);
-
- // Convert the URL type and to a null terminated wchar string
- $url .= "\0";
-
- // character count
- $url_len = StringHelper::countCharacters($url);
- $url_len = pack('V', $url_len);
-
- $url = StringHelper::convertEncoding($url, 'UTF-16LE', 'UTF-8');
-
- // Calculate the data length
- $length = 0x24 + strlen($url);
-
- // Pack the header data
- $header = pack('vv', $record, $length);
- $data = pack('vvvv', $row1, $row2, $col1, $col2);
-
- // Write the packed data
- $this->append($header . $data . $unknown1 . $options . $url_len . $url);
-
- return 0;
- }
-
- /**
- * Write links to external directory names such as 'c:\foo.xls',
- * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'.
- *
- * Note: Excel writes some relative links with the $dir_long string. We ignore
- * these cases for the sake of simpler code.
- *
- * @param int $row1 Start row
- * @param int $col1 Start column
- * @param int $row2 End row
- * @param int $col2 End column
- * @param string $url URL string
- *
- * @return int
- *
- * @see writeUrl()
- */
- public function writeUrlExternal($row1, $col1, $row2, $col2, $url)
- {
- // Network drives are different. We will handle them separately
- // MS/Novell network drives and shares start with \\
- if (preg_match('[^external:\\\\]', $url)) {
- return; //($this->writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format));
- }
-
- $record = 0x01B8; // Record identifier
- $length = 0x00000; // Bytes to follow
-
- // Strip URL type and change Unix dir separator to Dos style (if needed)
- //
- $url = preg_replace('/^external:/', '', $url);
- $url = preg_replace('/\//', '\\', $url);
-
- // Determine if the link is relative or absolute:
- // relative if link contains no dir separator, "somefile.xls"
- // relative if link starts with up-dir, "..\..\somefile.xls"
- // otherwise, absolute
-
- $absolute = 0x00; // relative path
- if (preg_match('/^[A-Z]:/', $url)) {
- $absolute = 0x02; // absolute path on Windows, e.g. C:\...
- }
- $link_type = 0x01 | $absolute;
-
- // Determine if the link contains a sheet reference and change some of the
- // parameters accordingly.
- // Split the dir name and sheet name (if it exists)
- $dir_long = $url;
- if (preg_match('/\\#/', $url)) {
- $link_type |= 0x08;
- }
-
- // Pack the link type
- $link_type = pack('V', $link_type);
-
- // Calculate the up-level dir count e.g.. (..\..\..\ == 3)
- $up_count = preg_match_all('/\\.\\.\\\\/', $dir_long, $useless);
- $up_count = pack('v', $up_count);
-
- // Store the short dos dir name (null terminated)
- $dir_short = preg_replace('/\\.\\.\\\\/', '', $dir_long) . "\0";
-
- // Store the long dir name as a wchar string (non-null terminated)
- $dir_long = $dir_long . "\0";
-
- // Pack the lengths of the dir strings
- $dir_short_len = pack('V', strlen($dir_short));
- $dir_long_len = pack('V', strlen($dir_long));
- $stream_len = pack('V', 0); //strlen($dir_long) + 0x06);
-
- // Pack the undocumented parts of the hyperlink stream
- $unknown1 = pack('H*', 'D0C9EA79F9BACE118C8200AA004BA90B02000000');
- $unknown2 = pack('H*', '0303000000000000C000000000000046');
- $unknown3 = pack('H*', 'FFFFADDE000000000000000000000000000000000000000');
- $unknown4 = pack('v', 0x03);
-
- // Pack the main data stream
- $data = pack('vvvv', $row1, $row2, $col1, $col2) .
- $unknown1 .
- $link_type .
- $unknown2 .
- $up_count .
- $dir_short_len .
- $dir_short .
- $unknown3 .
- $stream_len; /*.
- $dir_long_len .
- $unknown4 .
- $dir_long .
- $sheet_len .
- $sheet ;*/
-
- // Pack the header data
- $length = strlen($data);
- $header = pack('vv', $record, $length);
-
- // Write the packed data
- $this->append($header . $data);
-
- return 0;
- }
-
- /**
- * This method is used to set the height and format for a row.
- *
- * @param int $row The row to set
- * @param int $height Height we are giving to the row.
- * Use null to set XF without setting height
- * @param int $xfIndex The optional cell style Xf index to apply to the columns
- * @param bool $hidden The optional hidden attribute
- * @param int $level The optional outline level for row, in range [0,7]
- */
- private function writeRow($row, $height, $xfIndex, $hidden = false, $level = 0): void
- {
- $record = 0x0208; // Record identifier
- $length = 0x0010; // Number of bytes to follow
-
- $colMic = 0x0000; // First defined column
- $colMac = 0x0000; // Last defined column
- $irwMac = 0x0000; // Used by Excel to optimise loading
- $reserved = 0x0000; // Reserved
- $grbit = 0x0000; // Option flags
- $ixfe = $xfIndex;
-
- if ($height < 0) {
- $height = null;
- }
-
- // Use writeRow($row, null, $XF) to set XF format without setting height
- if ($height != null) {
- $miyRw = $height * 20; // row height
- } else {
- $miyRw = 0xff; // default row height is 256
- }
-
- // Set the options flags. fUnsynced is used to show that the font and row
- // heights are not compatible. This is usually the case for WriteExcel.
- // The collapsed flag 0x10 doesn't seem to be used to indicate that a row
- // is collapsed. Instead it is used to indicate that the previous row is
- // collapsed. The zero height flag, 0x20, is used to collapse a row.
-
- $grbit |= $level;
- if ($hidden) {
- $grbit |= 0x0030;
- }
- if ($height !== null) {
- $grbit |= 0x0040; // fUnsynced
- }
- if ($xfIndex !== 0xF) {
- $grbit |= 0x0080;
- }
- $grbit |= 0x0100;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvvvvvv', $row, $colMic, $colMac, $miyRw, $irwMac, $reserved, $grbit, $ixfe);
- $this->append($header . $data);
- }
-
- /**
- * Writes Excel DIMENSIONS to define the area in which there is data.
- */
- private function writeDimensions(): void
- {
- $record = 0x0200; // Record identifier
-
- $length = 0x000E;
- $data = pack('VVvvv', $this->firstRowIndex, $this->lastRowIndex + 1, $this->firstColumnIndex, $this->lastColumnIndex + 1, 0x0000); // reserved
-
- $header = pack('vv', $record, $length);
- $this->append($header . $data);
- }
-
- /**
- * Write BIFF record Window2.
- */
- private function writeWindow2(): void
- {
- $record = 0x023E; // Record identifier
- $length = 0x0012;
-
- $grbit = 0x00B6; // Option flags
- $rwTop = 0x0000; // Top row visible in window
- $colLeft = 0x0000; // Leftmost column visible in window
-
- // The options flags that comprise $grbit
- $fDspFmla = 0; // 0 - bit
- $fDspGrid = $this->phpSheet->getShowGridlines() ? 1 : 0; // 1
- $fDspRwCol = $this->phpSheet->getShowRowColHeaders() ? 1 : 0; // 2
- $fFrozen = $this->phpSheet->getFreezePane() ? 1 : 0; // 3
- $fDspZeros = 1; // 4
- $fDefaultHdr = 1; // 5
- $fArabic = $this->phpSheet->getRightToLeft() ? 1 : 0; // 6
- $fDspGuts = $this->outlineOn; // 7
- $fFrozenNoSplit = 0; // 0 - bit
- // no support in PhpSpreadsheet for selected sheet, therefore sheet is only selected if it is the active sheet
- $fSelected = ($this->phpSheet === $this->phpSheet->getParent()->getActiveSheet()) ? 1 : 0;
- $fPageBreakPreview = $this->phpSheet->getSheetView()->getView() === SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW;
-
- $grbit = $fDspFmla;
- $grbit |= $fDspGrid << 1;
- $grbit |= $fDspRwCol << 2;
- $grbit |= $fFrozen << 3;
- $grbit |= $fDspZeros << 4;
- $grbit |= $fDefaultHdr << 5;
- $grbit |= $fArabic << 6;
- $grbit |= $fDspGuts << 7;
- $grbit |= $fFrozenNoSplit << 8;
- $grbit |= $fSelected << 9; // Selected sheets.
- $grbit |= $fSelected << 10; // Active sheet.
- $grbit |= $fPageBreakPreview << 11;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvv', $grbit, $rwTop, $colLeft);
-
- // FIXME !!!
- $rgbHdr = 0x0040; // Row/column heading and gridline color index
- $zoom_factor_page_break = ($fPageBreakPreview ? $this->phpSheet->getSheetView()->getZoomScale() : 0x0000);
- $zoom_factor_normal = $this->phpSheet->getSheetView()->getZoomScaleNormal();
-
- $data .= pack('vvvvV', $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);
-
- $this->append($header . $data);
- }
-
- /**
- * Write BIFF record DEFAULTROWHEIGHT.
- */
- private function writeDefaultRowHeight(): void
- {
- $defaultRowHeight = $this->phpSheet->getDefaultRowDimension()->getRowHeight();
-
- if ($defaultRowHeight < 0) {
- return;
- }
-
- // convert to twips
- $defaultRowHeight = (int) 20 * $defaultRowHeight;
-
- $record = 0x0225; // Record identifier
- $length = 0x0004; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('vv', 1, $defaultRowHeight);
- $this->append($header . $data);
- }
-
- /**
- * Write BIFF record DEFCOLWIDTH if COLINFO records are in use.
- */
- private function writeDefcol(): void
- {
- $defaultColWidth = 8;
-
- $record = 0x0055; // Record identifier
- $length = 0x0002; // Number of bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $defaultColWidth);
- $this->append($header . $data);
- }
-
- /**
- * Write BIFF record COLINFO to define column widths.
- *
- * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C
- * length record.
- *
- * @param array $col_array This is the only parameter received and is composed of the following:
- * 0 => First formatted column,
- * 1 => Last formatted column,
- * 2 => Col width (8.43 is Excel default),
- * 3 => The optional XF format of the column,
- * 4 => Option flags.
- * 5 => Optional outline level
- */
- private function writeColinfo($col_array): void
- {
- if (isset($col_array[0])) {
- $colFirst = $col_array[0];
- }
- if (isset($col_array[1])) {
- $colLast = $col_array[1];
- }
- if (isset($col_array[2])) {
- $coldx = $col_array[2];
- } else {
- $coldx = 8.43;
- }
- if (isset($col_array[3])) {
- $xfIndex = $col_array[3];
- } else {
- $xfIndex = 15;
- }
- if (isset($col_array[4])) {
- $grbit = $col_array[4];
- } else {
- $grbit = 0;
- }
- if (isset($col_array[5])) {
- $level = $col_array[5];
- } else {
- $level = 0;
- }
- $record = 0x007D; // Record identifier
- $length = 0x000C; // Number of bytes to follow
-
- $coldx *= 256; // Convert to units of 1/256 of a char
-
- $ixfe = $xfIndex;
- $reserved = 0x0000; // Reserved
-
- $level = max(0, min($level, 7));
- $grbit |= $level << 8;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvvvv', $colFirst, $colLast, $coldx, $ixfe, $grbit, $reserved);
- $this->append($header . $data);
- }
-
- /**
- * Write BIFF record SELECTION.
- */
- private function writeSelection(): void
- {
- // look up the selected cell range
- $selectedCells = Coordinate::splitRange($this->phpSheet->getSelectedCells());
- $selectedCells = $selectedCells[0];
- if (count($selectedCells) == 2) {
- [$first, $last] = $selectedCells;
- } else {
- $first = $selectedCells[0];
- $last = $selectedCells[0];
- }
-
- [$colFirst, $rwFirst] = Coordinate::coordinateFromString($first);
- $colFirst = Coordinate::columnIndexFromString($colFirst) - 1; // base 0 column index
- --$rwFirst; // base 0 row index
-
- [$colLast, $rwLast] = Coordinate::coordinateFromString($last);
- $colLast = Coordinate::columnIndexFromString($colLast) - 1; // base 0 column index
- --$rwLast; // base 0 row index
-
- // make sure we are not out of bounds
- $colFirst = min($colFirst, 255);
- $colLast = min($colLast, 255);
-
- $rwFirst = min($rwFirst, 65535);
- $rwLast = min($rwLast, 65535);
-
- $record = 0x001D; // Record identifier
- $length = 0x000F; // Number of bytes to follow
-
- $pnn = $this->activePane; // Pane position
- $rwAct = $rwFirst; // Active row
- $colAct = $colFirst; // Active column
- $irefAct = 0; // Active cell ref
- $cref = 1; // Number of refs
-
- if (!isset($rwLast)) {
- $rwLast = $rwFirst; // Last row in reference
- }
- if (!isset($colLast)) {
- $colLast = $colFirst; // Last col in reference
- }
-
- // Swap last row/col for first row/col as necessary
- if ($rwFirst > $rwLast) {
- [$rwFirst, $rwLast] = [$rwLast, $rwFirst];
- }
-
- if ($colFirst > $colLast) {
- [$colFirst, $colLast] = [$colLast, $colFirst];
- }
-
- $header = pack('vv', $record, $length);
- $data = pack('CvvvvvvCC', $pnn, $rwAct, $colAct, $irefAct, $cref, $rwFirst, $rwLast, $colFirst, $colLast);
- $this->append($header . $data);
- }
-
- /**
- * Store the MERGEDCELLS records for all ranges of merged cells.
- */
- private function writeMergedCells(): void
- {
- $mergeCells = $this->phpSheet->getMergeCells();
- $countMergeCells = count($mergeCells);
-
- if ($countMergeCells == 0) {
- return;
- }
-
- // maximum allowed number of merged cells per record
- $maxCountMergeCellsPerRecord = 1027;
-
- // record identifier
- $record = 0x00E5;
-
- // counter for total number of merged cells treated so far by the writer
- $i = 0;
-
- // counter for number of merged cells written in record currently being written
- $j = 0;
-
- // initialize record data
- $recordData = '';
-
- // loop through the merged cells
- foreach ($mergeCells as $mergeCell) {
- ++$i;
- ++$j;
-
- // extract the row and column indexes
- $range = Coordinate::splitRange($mergeCell);
- [$first, $last] = $range[0];
- [$firstColumn, $firstRow] = Coordinate::coordinateFromString($first);
- [$lastColumn, $lastRow] = Coordinate::coordinateFromString($last);
-
- $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, Coordinate::columnIndexFromString($firstColumn) - 1, Coordinate::columnIndexFromString($lastColumn) - 1);
-
- // flush record if we have reached limit for number of merged cells, or reached final merged cell
- if ($j == $maxCountMergeCellsPerRecord || $i == $countMergeCells) {
- $recordData = pack('v', $j) . $recordData;
- $length = strlen($recordData);
- $header = pack('vv', $record, $length);
- $this->append($header . $recordData);
-
- // initialize for next record, if any
- $recordData = '';
- $j = 0;
- }
- }
- }
-
- /**
- * Write SHEETLAYOUT record.
- */
- private function writeSheetLayout(): void
- {
- if (!$this->phpSheet->isTabColorSet()) {
- return;
- }
-
- $recordData = pack(
- 'vvVVVvv',
- 0x0862,
- 0x0000, // unused
- 0x00000000, // unused
- 0x00000000, // unused
- 0x00000014, // size of record data
- $this->colors[$this->phpSheet->getTabColor()->getRGB()], // color index
- 0x0000 // unused
- );
-
- $length = strlen($recordData);
-
- $record = 0x0862; // Record identifier
- $header = pack('vv', $record, $length);
- $this->append($header . $recordData);
- }
-
- /**
- * Write SHEETPROTECTION.
- */
- private function writeSheetProtection(): void
- {
- // record identifier
- $record = 0x0867;
-
- // prepare options
- $options = (int) !$this->phpSheet->getProtection()->getObjects()
- | (int) !$this->phpSheet->getProtection()->getScenarios() << 1
- | (int) !$this->phpSheet->getProtection()->getFormatCells() << 2
- | (int) !$this->phpSheet->getProtection()->getFormatColumns() << 3
- | (int) !$this->phpSheet->getProtection()->getFormatRows() << 4
- | (int) !$this->phpSheet->getProtection()->getInsertColumns() << 5
- | (int) !$this->phpSheet->getProtection()->getInsertRows() << 6
- | (int) !$this->phpSheet->getProtection()->getInsertHyperlinks() << 7
- | (int) !$this->phpSheet->getProtection()->getDeleteColumns() << 8
- | (int) !$this->phpSheet->getProtection()->getDeleteRows() << 9
- | (int) !$this->phpSheet->getProtection()->getSelectLockedCells() << 10
- | (int) !$this->phpSheet->getProtection()->getSort() << 11
- | (int) !$this->phpSheet->getProtection()->getAutoFilter() << 12
- | (int) !$this->phpSheet->getProtection()->getPivotTables() << 13
- | (int) !$this->phpSheet->getProtection()->getSelectUnlockedCells() << 14;
-
- // record data
- $recordData = pack(
- 'vVVCVVvv',
- 0x0867, // repeated record identifier
- 0x0000, // not used
- 0x0000, // not used
- 0x00, // not used
- 0x01000200, // unknown data
- 0xFFFFFFFF, // unknown data
- $options, // options
- 0x0000 // not used
- );
-
- $length = strlen($recordData);
- $header = pack('vv', $record, $length);
-
- $this->append($header . $recordData);
- }
-
- /**
- * Write BIFF record RANGEPROTECTION.
- *
- * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records
- * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records
- */
- private function writeRangeProtection(): void
- {
- foreach ($this->phpSheet->getProtectedCells() as $range => $password) {
- // number of ranges, e.g. 'A1:B3 C20:D25'
- $cellRanges = explode(' ', $range);
- $cref = count($cellRanges);
-
- $recordData = pack(
- 'vvVVvCVvVv',
- 0x0868,
- 0x00,
- 0x0000,
- 0x0000,
- 0x02,
- 0x0,
- 0x0000,
- $cref,
- 0x0000,
- 0x00
- );
-
- foreach ($cellRanges as $cellRange) {
- $recordData .= $this->writeBIFF8CellRangeAddressFixed($cellRange);
- }
-
- // the rgbFeat structure
- $recordData .= pack(
- 'VV',
- 0x0000,
- hexdec($password)
- );
-
- $recordData .= StringHelper::UTF8toBIFF8UnicodeLong('p' . md5($recordData));
-
- $length = strlen($recordData);
-
- $record = 0x0868; // Record identifier
- $header = pack('vv', $record, $length);
- $this->append($header . $recordData);
- }
- }
-
- /**
- * Writes the Excel BIFF PANE record.
- * The panes can either be frozen or thawed (unfrozen).
- * Frozen panes are specified in terms of an integer number of rows and columns.
- * Thawed panes are specified in terms of Excel's units for rows and columns.
- */
- private function writePanes(): void
- {
- $panes = [];
- if ($this->phpSheet->getFreezePane()) {
- [$column, $row] = Coordinate::coordinateFromString($this->phpSheet->getFreezePane());
- $panes[0] = Coordinate::columnIndexFromString($column) - 1;
- $panes[1] = $row - 1;
-
- [$leftMostColumn, $topRow] = Coordinate::coordinateFromString($this->phpSheet->getTopLeftCell());
- //Coordinates are zero-based in xls files
- $panes[2] = $topRow - 1;
- $panes[3] = Coordinate::columnIndexFromString($leftMostColumn) - 1;
- } else {
- // thaw panes
- return;
- }
-
- $x = $panes[0] ?? null;
- $y = $panes[1] ?? null;
- $rwTop = $panes[2] ?? null;
- $colLeft = $panes[3] ?? null;
- if (count($panes) > 4) { // if Active pane was received
- $pnnAct = $panes[4];
- } else {
- $pnnAct = null;
- }
- $record = 0x0041; // Record identifier
- $length = 0x000A; // Number of bytes to follow
-
- // Code specific to frozen or thawed panes.
- if ($this->phpSheet->getFreezePane()) {
- // Set default values for $rwTop and $colLeft
- if (!isset($rwTop)) {
- $rwTop = $y;
- }
- if (!isset($colLeft)) {
- $colLeft = $x;
- }
- } else {
- // Set default values for $rwTop and $colLeft
- if (!isset($rwTop)) {
- $rwTop = 0;
- }
- if (!isset($colLeft)) {
- $colLeft = 0;
- }
-
- // Convert Excel's row and column units to the internal units.
- // The default row height is 12.75
- // The default column width is 8.43
- // The following slope and intersection values were interpolated.
- //
- $y = 20 * $y + 255;
- $x = 113.879 * $x + 390;
- }
-
- // Determine which pane should be active. There is also the undocumented
- // option to override this should it be necessary: may be removed later.
- //
- if (!isset($pnnAct)) {
- if ($x != 0 && $y != 0) {
- $pnnAct = 0; // Bottom right
- }
- if ($x != 0 && $y == 0) {
- $pnnAct = 1; // Top right
- }
- if ($x == 0 && $y != 0) {
- $pnnAct = 2; // Bottom left
- }
- if ($x == 0 && $y == 0) {
- $pnnAct = 3; // Top left
- }
- }
-
- $this->activePane = $pnnAct; // Used in writeSelection
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvvv', $x, $y, $rwTop, $colLeft, $pnnAct);
- $this->append($header . $data);
- }
-
- /**
- * Store the page setup SETUP BIFF record.
- */
- private function writeSetup(): void
- {
- $record = 0x00A1; // Record identifier
- $length = 0x0022; // Number of bytes to follow
-
- $iPaperSize = $this->phpSheet->getPageSetup()->getPaperSize(); // Paper size
-
- $iScale = $this->phpSheet->getPageSetup()->getScale() ?
- $this->phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor
-
- $iPageStart = 0x01; // Starting page number
- $iFitWidth = (int) $this->phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide
- $iFitHeight = (int) $this->phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high
- $grbit = 0x00; // Option flags
- $iRes = 0x0258; // Print resolution
- $iVRes = 0x0258; // Vertical print resolution
-
- $numHdr = $this->phpSheet->getPageMargins()->getHeader(); // Header Margin
-
- $numFtr = $this->phpSheet->getPageMargins()->getFooter(); // Footer Margin
- $iCopies = 0x01; // Number of copies
-
- // Order of printing pages
- $fLeftToRight = $this->phpSheet->getPageSetup()->getPageOrder() === PageSetup::PAGEORDER_DOWN_THEN_OVER
- ? 0x1 : 0x0;
- // Page orientation
- $fLandscape = ($this->phpSheet->getPageSetup()->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE)
- ? 0x0 : 0x1;
-
- $fNoPls = 0x0; // Setup not read from printer
- $fNoColor = 0x0; // Print black and white
- $fDraft = 0x0; // Print draft quality
- $fNotes = 0x0; // Print notes
- $fNoOrient = 0x0; // Orientation not set
- $fUsePage = 0x0; // Use custom starting page
-
- $grbit = $fLeftToRight;
- $grbit |= $fLandscape << 1;
- $grbit |= $fNoPls << 2;
- $grbit |= $fNoColor << 3;
- $grbit |= $fDraft << 4;
- $grbit |= $fNotes << 5;
- $grbit |= $fNoOrient << 6;
- $grbit |= $fUsePage << 7;
-
- $numHdr = pack('d', $numHdr);
- $numFtr = pack('d', $numFtr);
- if (self::getByteOrder()) { // if it's Big Endian
- $numHdr = strrev($numHdr);
- $numFtr = strrev($numFtr);
- }
-
- $header = pack('vv', $record, $length);
- $data1 = pack('vvvvvvvv', $iPaperSize, $iScale, $iPageStart, $iFitWidth, $iFitHeight, $grbit, $iRes, $iVRes);
- $data2 = $numHdr . $numFtr;
- $data3 = pack('v', $iCopies);
- $this->append($header . $data1 . $data2 . $data3);
- }
-
- /**
- * Store the header caption BIFF record.
- */
- private function writeHeader(): void
- {
- $record = 0x0014; // Record identifier
-
- /* removing for now
- // need to fix character count (multibyte!)
- if (strlen($this->phpSheet->getHeaderFooter()->getOddHeader()) <= 255) {
- $str = $this->phpSheet->getHeaderFooter()->getOddHeader(); // header string
- } else {
- $str = '';
- }
- */
-
- $recordData = StringHelper::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddHeader());
- $length = strlen($recordData);
-
- $header = pack('vv', $record, $length);
-
- $this->append($header . $recordData);
- }
-
- /**
- * Store the footer caption BIFF record.
- */
- private function writeFooter(): void
- {
- $record = 0x0015; // Record identifier
-
- /* removing for now
- // need to fix character count (multibyte!)
- if (strlen($this->phpSheet->getHeaderFooter()->getOddFooter()) <= 255) {
- $str = $this->phpSheet->getHeaderFooter()->getOddFooter();
- } else {
- $str = '';
- }
- */
-
- $recordData = StringHelper::UTF8toBIFF8UnicodeLong($this->phpSheet->getHeaderFooter()->getOddFooter());
- $length = strlen($recordData);
-
- $header = pack('vv', $record, $length);
-
- $this->append($header . $recordData);
- }
-
- /**
- * Store the horizontal centering HCENTER BIFF record.
- */
- private function writeHcenter(): void
- {
- $record = 0x0083; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fHCenter = $this->phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fHCenter);
-
- $this->append($header . $data);
- }
-
- /**
- * Store the vertical centering VCENTER BIFF record.
- */
- private function writeVcenter(): void
- {
- $record = 0x0084; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fVCenter = $this->phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fVCenter);
- $this->append($header . $data);
- }
-
- /**
- * Store the LEFTMARGIN BIFF record.
- */
- private function writeMarginLeft(): void
- {
- $record = 0x0026; // Record identifier
- $length = 0x0008; // Bytes to follow
-
- $margin = $this->phpSheet->getPageMargins()->getLeft(); // Margin in inches
-
- $header = pack('vv', $record, $length);
- $data = pack('d', $margin);
- if (self::getByteOrder()) { // if it's Big Endian
- $data = strrev($data);
- }
-
- $this->append($header . $data);
- }
-
- /**
- * Store the RIGHTMARGIN BIFF record.
- */
- private function writeMarginRight(): void
- {
- $record = 0x0027; // Record identifier
- $length = 0x0008; // Bytes to follow
-
- $margin = $this->phpSheet->getPageMargins()->getRight(); // Margin in inches
-
- $header = pack('vv', $record, $length);
- $data = pack('d', $margin);
- if (self::getByteOrder()) { // if it's Big Endian
- $data = strrev($data);
- }
-
- $this->append($header . $data);
- }
-
- /**
- * Store the TOPMARGIN BIFF record.
- */
- private function writeMarginTop(): void
- {
- $record = 0x0028; // Record identifier
- $length = 0x0008; // Bytes to follow
-
- $margin = $this->phpSheet->getPageMargins()->getTop(); // Margin in inches
-
- $header = pack('vv', $record, $length);
- $data = pack('d', $margin);
- if (self::getByteOrder()) { // if it's Big Endian
- $data = strrev($data);
- }
-
- $this->append($header . $data);
- }
-
- /**
- * Store the BOTTOMMARGIN BIFF record.
- */
- private function writeMarginBottom(): void
- {
- $record = 0x0029; // Record identifier
- $length = 0x0008; // Bytes to follow
-
- $margin = $this->phpSheet->getPageMargins()->getBottom(); // Margin in inches
-
- $header = pack('vv', $record, $length);
- $data = pack('d', $margin);
- if (self::getByteOrder()) { // if it's Big Endian
- $data = strrev($data);
- }
-
- $this->append($header . $data);
- }
-
- /**
- * Write the PRINTHEADERS BIFF record.
- */
- private function writePrintHeaders(): void
- {
- $record = 0x002a; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fPrintRwCol = $this->printHeaders; // Boolean flag
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fPrintRwCol);
- $this->append($header . $data);
- }
-
- /**
- * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the
- * GRIDSET record.
- */
- private function writePrintGridlines(): void
- {
- $record = 0x002b; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fPrintGrid = $this->phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fPrintGrid);
- $this->append($header . $data);
- }
-
- /**
- * Write the GRIDSET BIFF record. Must be used in conjunction with the
- * PRINTGRIDLINES record.
- */
- private function writeGridset(): void
- {
- $record = 0x0082; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fGridSet = !$this->phpSheet->getPrintGridlines(); // Boolean flag
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fGridSet);
- $this->append($header . $data);
- }
-
- /**
- * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet.
- */
- private function writeAutoFilterInfo(): void
- {
- $record = 0x009D; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $rangeBounds = Coordinate::rangeBoundaries($this->phpSheet->getAutoFilter()->getRange());
- $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0];
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $iNumFilters);
- $this->append($header . $data);
- }
-
- /**
- * Write the GUTS BIFF record. This is used to configure the gutter margins
- * where Excel outline symbols are displayed. The visibility of the gutters is
- * controlled by a flag in WSBOOL.
- *
- * @see writeWsbool()
- */
- private function writeGuts(): void
- {
- $record = 0x0080; // Record identifier
- $length = 0x0008; // Bytes to follow
-
- $dxRwGut = 0x0000; // Size of row gutter
- $dxColGut = 0x0000; // Size of col gutter
-
- // determine maximum row outline level
- $maxRowOutlineLevel = 0;
- foreach ($this->phpSheet->getRowDimensions() as $rowDimension) {
- $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel());
- }
-
- $col_level = 0;
-
- // Calculate the maximum column outline level. The equivalent calculation
- // for the row outline level is carried out in writeRow().
- $colcount = count($this->columnInfo);
- for ($i = 0; $i < $colcount; ++$i) {
- $col_level = max($this->columnInfo[$i][5], $col_level);
- }
-
- // Set the limits for the outline levels (0 <= x <= 7).
- $col_level = max(0, min($col_level, 7));
-
- // The displayed level is one greater than the max outline levels
- if ($maxRowOutlineLevel) {
- ++$maxRowOutlineLevel;
- }
- if ($col_level) {
- ++$col_level;
- }
-
- $header = pack('vv', $record, $length);
- $data = pack('vvvv', $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level);
-
- $this->append($header . $data);
- }
-
- /**
- * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction
- * with the SETUP record.
- */
- private function writeWsbool(): void
- {
- $record = 0x0081; // Record identifier
- $length = 0x0002; // Bytes to follow
- $grbit = 0x0000;
-
- // The only option that is of interest is the flag for fit to page. So we
- // set all the options in one go.
- //
- // Set the option flags
- $grbit |= 0x0001; // Auto page breaks visible
- if ($this->outlineStyle) {
- $grbit |= 0x0020; // Auto outline styles
- }
- if ($this->phpSheet->getShowSummaryBelow()) {
- $grbit |= 0x0040; // Outline summary below
- }
- if ($this->phpSheet->getShowSummaryRight()) {
- $grbit |= 0x0080; // Outline summary right
- }
- if ($this->phpSheet->getPageSetup()->getFitToPage()) {
- $grbit |= 0x0100; // Page setup fit to page
- }
- if ($this->outlineOn) {
- $grbit |= 0x0400; // Outline symbols displayed
- }
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $grbit);
- $this->append($header . $data);
- }
-
- /**
- * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records.
- */
- private function writeBreaks(): void
- {
- // initialize
- $vbreaks = [];
- $hbreaks = [];
-
- foreach ($this->phpSheet->getBreaks() as $cell => $breakType) {
- // Fetch coordinates
- $coordinates = Coordinate::coordinateFromString($cell);
-
- // Decide what to do by the type of break
- switch ($breakType) {
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_COLUMN:
- // Add to list of vertical breaks
- $vbreaks[] = Coordinate::columnIndexFromString($coordinates[0]) - 1;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_ROW:
- // Add to list of horizontal breaks
- $hbreaks[] = $coordinates[1];
-
- break;
- case \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::BREAK_NONE:
- default:
- // Nothing to do
- break;
- }
- }
-
- //horizontal page breaks
- if (!empty($hbreaks)) {
- // Sort and filter array of page breaks
- sort($hbreaks, SORT_NUMERIC);
- if ($hbreaks[0] == 0) { // don't use first break if it's 0
- array_shift($hbreaks);
- }
-
- $record = 0x001b; // Record identifier
- $cbrk = count($hbreaks); // Number of page breaks
- $length = 2 + 6 * $cbrk; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $cbrk);
-
- // Append each page break
- foreach ($hbreaks as $hbreak) {
- $data .= pack('vvv', $hbreak, 0x0000, 0x00ff);
- }
-
- $this->append($header . $data);
- }
-
- // vertical page breaks
- if (!empty($vbreaks)) {
- // 1000 vertical pagebreaks appears to be an internal Excel 5 limit.
- // It is slightly higher in Excel 97/200, approx. 1026
- $vbreaks = array_slice($vbreaks, 0, 1000);
-
- // Sort and filter array of page breaks
- sort($vbreaks, SORT_NUMERIC);
- if ($vbreaks[0] == 0) { // don't use first break if it's 0
- array_shift($vbreaks);
- }
-
- $record = 0x001a; // Record identifier
- $cbrk = count($vbreaks); // Number of page breaks
- $length = 2 + 6 * $cbrk; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $cbrk);
-
- // Append each page break
- foreach ($vbreaks as $vbreak) {
- $data .= pack('vvv', $vbreak, 0x0000, 0xffff);
- }
-
- $this->append($header . $data);
- }
- }
-
- /**
- * Set the Biff PROTECT record to indicate that the worksheet is protected.
- */
- private function writeProtect(): void
- {
- // Exit unless sheet protection has been specified
- if (!$this->phpSheet->getProtection()->getSheet()) {
- return;
- }
-
- $record = 0x0012; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $fLock = 1; // Worksheet is protected
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $fLock);
-
- $this->append($header . $data);
- }
-
- /**
- * Write SCENPROTECT.
- */
- private function writeScenProtect(): void
- {
- // Exit if sheet protection is not active
- if (!$this->phpSheet->getProtection()->getSheet()) {
- return;
- }
-
- // Exit if scenarios are not protected
- if (!$this->phpSheet->getProtection()->getScenarios()) {
- return;
- }
-
- $record = 0x00DD; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', 1);
-
- $this->append($header . $data);
- }
-
- /**
- * Write OBJECTPROTECT.
- */
- private function writeObjectProtect(): void
- {
- // Exit if sheet protection is not active
- if (!$this->phpSheet->getProtection()->getSheet()) {
- return;
- }
-
- // Exit if objects are not protected
- if (!$this->phpSheet->getProtection()->getObjects()) {
- return;
- }
-
- $record = 0x0063; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('v', 1);
-
- $this->append($header . $data);
- }
-
- /**
- * Write the worksheet PASSWORD record.
- */
- private function writePassword(): void
- {
- // Exit unless sheet protection and password have been specified
- if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword()) {
- return;
- }
-
- $record = 0x0013; // Record identifier
- $length = 0x0002; // Bytes to follow
-
- $wPassword = hexdec($this->phpSheet->getProtection()->getPassword()); // Encoded password
-
- $header = pack('vv', $record, $length);
- $data = pack('v', $wPassword);
-
- $this->append($header . $data);
- }
-
- /**
- * Insert a 24bit bitmap image in a worksheet.
- *
- * @param int $row The row we are going to insert the bitmap into
- * @param int $col The column we are going to insert the bitmap into
- * @param mixed $bitmap The bitmap filename or GD-image resource
- * @param int $x the horizontal position (offset) of the image inside the cell
- * @param int $y the vertical position (offset) of the image inside the cell
- * @param float $scale_x The horizontal scale
- * @param float $scale_y The vertical scale
- */
- public function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1): void
- {
- $bitmap_array = (is_resource($bitmap) ? $this->processBitmapGd($bitmap) : $this->processBitmap($bitmap));
- [$width, $height, $size, $data] = $bitmap_array;
-
- // Scale the frame of the image.
- $width *= $scale_x;
- $height *= $scale_y;
-
- // Calculate the vertices of the image and write the OBJ record
- $this->positionImage($col, $row, $x, $y, $width, $height);
-
- // Write the IMDATA record to store the bitmap data
- $record = 0x007f;
- $length = 8 + $size;
- $cf = 0x09;
- $env = 0x01;
- $lcb = $size;
-
- $header = pack('vvvvV', $record, $length, $cf, $env, $lcb);
- $this->append($header . $data);
- }
-
- /**
- * Calculate the vertices that define the position of the image as required by
- * the OBJ record.
- *
- * +------------+------------+
- * | A | B |
- * +-----+------------+------------+
- * | |(x1,y1) | |
- * | 1 |(A1)._______|______ |
- * | | | | |
- * | | | | |
- * +-----+----| BITMAP |-----+
- * | | | | |
- * | 2 | |______________. |
- * | | | (B2)|
- * | | | (x2,y2)|
- * +---- +------------+------------+
- *
- * Example of a bitmap that covers some of the area from cell A1 to cell B2.
- *
- * Based on the width and height of the bitmap we need to calculate 8 vars:
- * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.
- * The width and height of the cells are also variable and have to be taken into
- * account.
- * The values of $col_start and $row_start are passed in from the calling
- * function. The values of $col_end and $row_end are calculated by subtracting
- * the width and height of the bitmap from the width and height of the
- * underlying cells.
- * The vertices are expressed as a percentage of the underlying cell width as
- * follows (rhs values are in pixels):
- *
- * x1 = X / W *1024
- * y1 = Y / H *256
- * x2 = (X-1) / W *1024
- * y2 = (Y-1) / H *256
- *
- * Where: X is distance from the left side of the underlying cell
- * Y is distance from the top of the underlying cell
- * W is the width of the cell
- * H is the height of the cell
- * The SDK incorrectly states that the height should be expressed as a
- * percentage of 1024.
- *
- * @param int $col_start Col containing upper left corner of object
- * @param int $row_start Row containing top left corner of object
- * @param int $x1 Distance to left side of object
- * @param int $y1 Distance to top of object
- * @param int $width Width of image frame
- * @param int $height Height of image frame
- */
- public function positionImage($col_start, $row_start, $x1, $y1, $width, $height): void
- {
- // Initialise end cell to the same as the start cell
- $col_end = $col_start; // Col containing lower right corner of object
- $row_end = $row_start; // Row containing bottom right corner of object
-
- // Zero the specified offset if greater than the cell dimensions
- if ($x1 >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1))) {
- $x1 = 0;
- }
- if ($y1 >= Xls::sizeRow($this->phpSheet, $row_start + 1)) {
- $y1 = 0;
- }
-
- $width = $width + $x1 - 1;
- $height = $height + $y1 - 1;
-
- // Subtract the underlying cell widths to find the end cell of the image
- while ($width >= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1))) {
- $width -= Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1));
- ++$col_end;
- }
-
- // Subtract the underlying cell heights to find the end cell of the image
- while ($height >= Xls::sizeRow($this->phpSheet, $row_end + 1)) {
- $height -= Xls::sizeRow($this->phpSheet, $row_end + 1);
- ++$row_end;
- }
-
- // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
- // with zero eight or width.
- //
- if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1)) == 0) {
- return;
- }
- if (Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1)) == 0) {
- return;
- }
- if (Xls::sizeRow($this->phpSheet, $row_start + 1) == 0) {
- return;
- }
- if (Xls::sizeRow($this->phpSheet, $row_end + 1) == 0) {
- return;
- }
-
- // Convert the pixel values to the percentage value expected by Excel
- $x1 = $x1 / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_start + 1)) * 1024;
- $y1 = $y1 / Xls::sizeRow($this->phpSheet, $row_start + 1) * 256;
- $x2 = $width / Xls::sizeCol($this->phpSheet, Coordinate::stringFromColumnIndex($col_end + 1)) * 1024; // Distance to right side of object
- $y2 = $height / Xls::sizeRow($this->phpSheet, $row_end + 1) * 256; // Distance to bottom of object
-
- $this->writeObjPicture($col_start, $x1, $row_start, $y1, $col_end, $x2, $row_end, $y2);
- }
-
- /**
- * Store the OBJ record that precedes an IMDATA record. This could be generalise
- * to support other Excel objects.
- *
- * @param int $colL Column containing upper left corner of object
- * @param int $dxL Distance from left side of cell
- * @param int $rwT Row containing top left corner of object
- * @param int $dyT Distance from top of cell
- * @param int $colR Column containing lower right corner of object
- * @param int $dxR Distance from right of cell
- * @param int $rwB Row containing bottom right corner of object
- * @param int $dyB Distance from bottom of cell
- */
- private function writeObjPicture($colL, $dxL, $rwT, $dyT, $colR, $dxR, $rwB, $dyB): void
- {
- $record = 0x005d; // Record identifier
- $length = 0x003c; // Bytes to follow
-
- $cObj = 0x0001; // Count of objects in file (set to 1)
- $OT = 0x0008; // Object type. 8 = Picture
- $id = 0x0001; // Object ID
- $grbit = 0x0614; // Option flags
-
- $cbMacro = 0x0000; // Length of FMLA structure
- $Reserved1 = 0x0000; // Reserved
- $Reserved2 = 0x0000; // Reserved
-
- $icvBack = 0x09; // Background colour
- $icvFore = 0x09; // Foreground colour
- $fls = 0x00; // Fill pattern
- $fAuto = 0x00; // Automatic fill
- $icv = 0x08; // Line colour
- $lns = 0xff; // Line style
- $lnw = 0x01; // Line weight
- $fAutoB = 0x00; // Automatic border
- $frs = 0x0000; // Frame style
- $cf = 0x0009; // Image format, 9 = bitmap
- $Reserved3 = 0x0000; // Reserved
- $cbPictFmla = 0x0000; // Length of FMLA structure
- $Reserved4 = 0x0000; // Reserved
- $grbit2 = 0x0001; // Option flags
- $Reserved5 = 0x0000; // Reserved
-
- $header = pack('vv', $record, $length);
- $data = pack('V', $cObj);
- $data .= pack('v', $OT);
- $data .= pack('v', $id);
- $data .= pack('v', $grbit);
- $data .= pack('v', $colL);
- $data .= pack('v', $dxL);
- $data .= pack('v', $rwT);
- $data .= pack('v', $dyT);
- $data .= pack('v', $colR);
- $data .= pack('v', $dxR);
- $data .= pack('v', $rwB);
- $data .= pack('v', $dyB);
- $data .= pack('v', $cbMacro);
- $data .= pack('V', $Reserved1);
- $data .= pack('v', $Reserved2);
- $data .= pack('C', $icvBack);
- $data .= pack('C', $icvFore);
- $data .= pack('C', $fls);
- $data .= pack('C', $fAuto);
- $data .= pack('C', $icv);
- $data .= pack('C', $lns);
- $data .= pack('C', $lnw);
- $data .= pack('C', $fAutoB);
- $data .= pack('v', $frs);
- $data .= pack('V', $cf);
- $data .= pack('v', $Reserved3);
- $data .= pack('v', $cbPictFmla);
- $data .= pack('v', $Reserved4);
- $data .= pack('v', $grbit2);
- $data .= pack('V', $Reserved5);
-
- $this->append($header . $data);
- }
-
- /**
- * Convert a GD-image into the internal format.
- *
- * @param resource $image The image to process
- *
- * @return array Array with data and properties of the bitmap
- */
- public function processBitmapGd($image)
- {
- $width = imagesx($image);
- $height = imagesy($image);
-
- $data = pack('Vvvvv', 0x000c, $width, $height, 0x01, 0x18);
- for ($j = $height; --$j;) {
- for ($i = 0; $i < $width; ++$i) {
- $color = imagecolorsforindex($image, imagecolorat($image, $i, $j));
- foreach (['red', 'green', 'blue'] as $key) {
- $color[$key] = $color[$key] + round((255 - $color[$key]) * $color['alpha'] / 127);
- }
- $data .= chr($color['blue']) . chr($color['green']) . chr($color['red']);
- }
- if (3 * $width % 4) {
- $data .= str_repeat("\x00", 4 - 3 * $width % 4);
- }
- }
-
- return [$width, $height, strlen($data), $data];
- }
-
- /**
- * Convert a 24 bit bitmap into the modified internal format used by Windows.
- * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the
- * MSDN library.
- *
- * @param string $bitmap The bitmap to process
- *
- * @return array Array with data and properties of the bitmap
- */
- public function processBitmap($bitmap)
- {
- // Open file.
- $bmp_fd = @fopen($bitmap, 'rb');
- if (!$bmp_fd) {
- throw new WriterException("Couldn't import $bitmap");
- }
-
- // Slurp the file into a string.
- $data = fread($bmp_fd, filesize($bitmap));
-
- // Check that the file is big enough to be a bitmap.
- if (strlen($data) <= 0x36) {
- throw new WriterException("$bitmap doesn't contain enough data.\n");
- }
-
- // The first 2 bytes are used to identify the bitmap.
- $identity = unpack('A2ident', $data);
- if ($identity['ident'] != 'BM') {
- throw new WriterException("$bitmap doesn't appear to be a valid bitmap image.\n");
- }
-
- // Remove bitmap data: ID.
- $data = substr($data, 2);
-
- // Read and remove the bitmap size. This is more reliable than reading
- // the data size at offset 0x22.
- //
- $size_array = unpack('Vsa', substr($data, 0, 4));
- $size = $size_array['sa'];
- $data = substr($data, 4);
- $size -= 0x36; // Subtract size of bitmap header.
- $size += 0x0C; // Add size of BIFF header.
-
- // Remove bitmap data: reserved, offset, header length.
- $data = substr($data, 12);
-
- // Read and remove the bitmap width and height. Verify the sizes.
- $width_and_height = unpack('V2', substr($data, 0, 8));
- $width = $width_and_height[1];
- $height = $width_and_height[2];
- $data = substr($data, 8);
- if ($width > 0xFFFF) {
- throw new WriterException("$bitmap: largest image width supported is 65k.\n");
- }
- if ($height > 0xFFFF) {
- throw new WriterException("$bitmap: largest image height supported is 65k.\n");
- }
-
- // Read and remove the bitmap planes and bpp data. Verify them.
- $planes_and_bitcount = unpack('v2', substr($data, 0, 4));
- $data = substr($data, 4);
- if ($planes_and_bitcount[2] != 24) { // Bitcount
- throw new WriterException("$bitmap isn't a 24bit true color bitmap.\n");
- }
- if ($planes_and_bitcount[1] != 1) {
- throw new WriterException("$bitmap: only 1 plane supported in bitmap image.\n");
- }
-
- // Read and remove the bitmap compression. Verify compression.
- $compression = unpack('Vcomp', substr($data, 0, 4));
- $data = substr($data, 4);
-
- if ($compression['comp'] != 0) {
- throw new WriterException("$bitmap: compression not supported in bitmap image.\n");
- }
-
- // Remove bitmap data: data size, hres, vres, colours, imp. colours.
- $data = substr($data, 20);
-
- // Add the BITMAPCOREHEADER data
- $header = pack('Vvvvv', 0x000c, $width, $height, 0x01, 0x18);
- $data = $header . $data;
-
- return [$width, $height, $size, $data];
- }
-
- /**
- * Store the window zoom factor. This should be a reduced fraction but for
- * simplicity we will store all fractions with a numerator of 100.
- */
- private function writeZoom(): void
- {
- // If scale is 100 we don't need to write a record
- if ($this->phpSheet->getSheetView()->getZoomScale() == 100) {
- return;
- }
-
- $record = 0x00A0; // Record identifier
- $length = 0x0004; // Bytes to follow
-
- $header = pack('vv', $record, $length);
- $data = pack('vv', $this->phpSheet->getSheetView()->getZoomScale(), 100);
- $this->append($header . $data);
- }
-
- /**
- * Get Escher object.
- *
- * @return \PhpOffice\PhpSpreadsheet\Shared\Escher
- */
- public function getEscher()
- {
- return $this->escher;
- }
-
- /**
- * Set Escher object.
- *
- * @param \PhpOffice\PhpSpreadsheet\Shared\Escher $pValue
- */
- public function setEscher(?\PhpOffice\PhpSpreadsheet\Shared\Escher $pValue = null): void
- {
- $this->escher = $pValue;
- }
-
- /**
- * Write MSODRAWING record.
- */
- private function writeMsoDrawing(): void
- {
- // write the Escher stream if necessary
- if (isset($this->escher)) {
- $writer = new Escher($this->escher);
- $data = $writer->close();
- $spOffsets = $writer->getSpOffsets();
- $spTypes = $writer->getSpTypes();
- // write the neccesary MSODRAWING, OBJ records
-
- // split the Escher stream
- $spOffsets[0] = 0;
- $nm = count($spOffsets) - 1; // number of shapes excluding first shape
- for ($i = 1; $i <= $nm; ++$i) {
- // MSODRAWING record
- $record = 0x00EC; // Record identifier
-
- // chunk of Escher stream for one shape
- $dataChunk = substr($data, $spOffsets[$i - 1], $spOffsets[$i] - $spOffsets[$i - 1]);
-
- $length = strlen($dataChunk);
- $header = pack('vv', $record, $length);
-
- $this->append($header . $dataChunk);
-
- // OBJ record
- $record = 0x005D; // record identifier
- $objData = '';
-
- // ftCmo
- if ($spTypes[$i] == 0x00C9) {
- // Add ftCmo (common object data) subobject
- $objData .=
- pack(
- 'vvvvvVVV',
- 0x0015, // 0x0015 = ftCmo
- 0x0012, // length of ftCmo data
- 0x0014, // object type, 0x0014 = filter
- $i, // object id number, Excel seems to use 1-based index, local for the sheet
- 0x2101, // option flags, 0x2001 is what OpenOffice.org uses
- 0, // reserved
- 0, // reserved
- 0 // reserved
- );
-
- // Add ftSbs Scroll bar subobject
- $objData .= pack('vv', 0x00C, 0x0014);
- $objData .= pack('H*', '0000000000000000640001000A00000010000100');
- // Add ftLbsData (List box data) subobject
- $objData .= pack('vv', 0x0013, 0x1FEE);
- $objData .= pack('H*', '00000000010001030000020008005700');
- } else {
- // Add ftCmo (common object data) subobject
- $objData .=
- pack(
- 'vvvvvVVV',
- 0x0015, // 0x0015 = ftCmo
- 0x0012, // length of ftCmo data
- 0x0008, // object type, 0x0008 = picture
- $i, // object id number, Excel seems to use 1-based index, local for the sheet
- 0x6011, // option flags, 0x6011 is what OpenOffice.org uses
- 0, // reserved
- 0, // reserved
- 0 // reserved
- );
- }
-
- // ftEnd
- $objData .=
- pack(
- 'vv',
- 0x0000, // 0x0000 = ftEnd
- 0x0000 // length of ftEnd data
- );
-
- $length = strlen($objData);
- $header = pack('vv', $record, $length);
- $this->append($header . $objData);
- }
- }
- }
-
- /**
- * Store the DATAVALIDATIONS and DATAVALIDATION records.
- */
- private function writeDataValidity(): void
- {
- // Datavalidation collection
- $dataValidationCollection = $this->phpSheet->getDataValidationCollection();
-
- // Write data validations?
- if (!empty($dataValidationCollection)) {
- // DATAVALIDATIONS record
- $record = 0x01B2; // Record identifier
- $length = 0x0012; // Bytes to follow
-
- $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records
- $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position
- $verPos = 0x00000000; // Vertical position of prompt box, if fixed position
- $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible
-
- $header = pack('vv', $record, $length);
- $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, count($dataValidationCollection));
- $this->append($header . $data);
-
- // DATAVALIDATION records
- $record = 0x01BE; // Record identifier
-
- foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) {
- // initialize record data
- $data = '';
-
- // options
- $options = 0x00000000;
-
- // data type
- $type = 0x00;
- switch ($dataValidation->getType()) {
- case DataValidation::TYPE_NONE:
- $type = 0x00;
-
- break;
- case DataValidation::TYPE_WHOLE:
- $type = 0x01;
-
- break;
- case DataValidation::TYPE_DECIMAL:
- $type = 0x02;
-
- break;
- case DataValidation::TYPE_LIST:
- $type = 0x03;
-
- break;
- case DataValidation::TYPE_DATE:
- $type = 0x04;
-
- break;
- case DataValidation::TYPE_TIME:
- $type = 0x05;
-
- break;
- case DataValidation::TYPE_TEXTLENGTH:
- $type = 0x06;
-
- break;
- case DataValidation::TYPE_CUSTOM:
- $type = 0x07;
-
- break;
- }
-
- $options |= $type << 0;
-
- // error style
- $errorStyle = 0x00;
- switch ($dataValidation->getErrorStyle()) {
- case DataValidation::STYLE_STOP:
- $errorStyle = 0x00;
-
- break;
- case DataValidation::STYLE_WARNING:
- $errorStyle = 0x01;
-
- break;
- case DataValidation::STYLE_INFORMATION:
- $errorStyle = 0x02;
-
- break;
- }
-
- $options |= $errorStyle << 4;
-
- // explicit formula?
- if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) {
- $options |= 0x01 << 7;
- }
-
- // empty cells allowed
- $options |= $dataValidation->getAllowBlank() << 8;
-
- // show drop down
- $options |= (!$dataValidation->getShowDropDown()) << 9;
-
- // show input message
- $options |= $dataValidation->getShowInputMessage() << 18;
-
- // show error message
- $options |= $dataValidation->getShowErrorMessage() << 19;
-
- // condition operator
- $operator = 0x00;
- switch ($dataValidation->getOperator()) {
- case DataValidation::OPERATOR_BETWEEN:
- $operator = 0x00;
-
- break;
- case DataValidation::OPERATOR_NOTBETWEEN:
- $operator = 0x01;
-
- break;
- case DataValidation::OPERATOR_EQUAL:
- $operator = 0x02;
-
- break;
- case DataValidation::OPERATOR_NOTEQUAL:
- $operator = 0x03;
-
- break;
- case DataValidation::OPERATOR_GREATERTHAN:
- $operator = 0x04;
-
- break;
- case DataValidation::OPERATOR_LESSTHAN:
- $operator = 0x05;
-
- break;
- case DataValidation::OPERATOR_GREATERTHANOREQUAL:
- $operator = 0x06;
-
- break;
- case DataValidation::OPERATOR_LESSTHANOREQUAL:
- $operator = 0x07;
-
- break;
- }
-
- $options |= $operator << 20;
-
- $data = pack('V', $options);
-
- // prompt title
- $promptTitle = $dataValidation->getPromptTitle() !== '' ?
- $dataValidation->getPromptTitle() : chr(0);
- $data .= StringHelper::UTF8toBIFF8UnicodeLong($promptTitle);
-
- // error title
- $errorTitle = $dataValidation->getErrorTitle() !== '' ?
- $dataValidation->getErrorTitle() : chr(0);
- $data .= StringHelper::UTF8toBIFF8UnicodeLong($errorTitle);
-
- // prompt text
- $prompt = $dataValidation->getPrompt() !== '' ?
- $dataValidation->getPrompt() : chr(0);
- $data .= StringHelper::UTF8toBIFF8UnicodeLong($prompt);
-
- // error text
- $error = $dataValidation->getError() !== '' ?
- $dataValidation->getError() : chr(0);
- $data .= StringHelper::UTF8toBIFF8UnicodeLong($error);
-
- // formula 1
- try {
- $formula1 = $dataValidation->getFormula1();
- if ($type == 0x03) { // list type
- $formula1 = str_replace(',', chr(0), $formula1);
- }
- $this->parser->parse($formula1);
- $formula1 = $this->parser->toReversePolish();
- $sz1 = strlen($formula1);
- } catch (PhpSpreadsheetException $e) {
- $sz1 = 0;
- $formula1 = '';
- }
- $data .= pack('vv', $sz1, 0x0000);
- $data .= $formula1;
-
- // formula 2
- try {
- $formula2 = $dataValidation->getFormula2();
- if ($formula2 === '') {
- throw new WriterException('No formula2');
- }
- $this->parser->parse($formula2);
- $formula2 = $this->parser->toReversePolish();
- $sz2 = strlen($formula2);
- } catch (PhpSpreadsheetException $e) {
- $sz2 = 0;
- $formula2 = '';
- }
- $data .= pack('vv', $sz2, 0x0000);
- $data .= $formula2;
-
- // cell range address list
- $data .= pack('v', 0x0001);
- $data .= $this->writeBIFF8CellRangeAddressFixed($cellCoordinate);
-
- $length = strlen($data);
- $header = pack('vv', $record, $length);
-
- $this->append($header . $data);
- }
- }
- }
-
- /**
- * Map Error code.
- *
- * @param string $errorCode
- *
- * @return int
- */
- private static function mapErrorCode($errorCode)
- {
- switch ($errorCode) {
- case '#NULL!':
- return 0x00;
- case '#DIV/0!':
- return 0x07;
- case '#VALUE!':
- return 0x0F;
- case '#REF!':
- return 0x17;
- case '#NAME?':
- return 0x1D;
- case '#NUM!':
- return 0x24;
- case '#N/A':
- return 0x2A;
- }
-
- return 0;
- }
-
- /**
- * Write PLV Record.
- */
- private function writePageLayoutView(): void
- {
- $record = 0x088B; // Record identifier
- $length = 0x0010; // Bytes to follow
-
- $rt = 0x088B; // 2
- $grbitFrt = 0x0000; // 2
- $reserved = 0x0000000000000000; // 8
- $wScalvePLV = $this->phpSheet->getSheetView()->getZoomScale(); // 2
-
- // The options flags that comprise $grbit
- if ($this->phpSheet->getSheetView()->getView() == SheetView::SHEETVIEW_PAGE_LAYOUT) {
- $fPageLayoutView = 1;
- } else {
- $fPageLayoutView = 0;
- }
- $fRulerVisible = 0;
- $fWhitespaceHidden = 0;
-
- $grbit = $fPageLayoutView; // 2
- $grbit |= $fRulerVisible << 1;
- $grbit |= $fWhitespaceHidden << 3;
-
- $header = pack('vv', $record, $length);
- $data = pack('vvVVvv', $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit);
- $this->append($header . $data);
- }
-
- /**
- * Write CFRule Record.
- */
- private function writeCFRule(Conditional $conditional): void
- {
- $record = 0x01B1; // Record identifier
-
- // $type : Type of the CF
- // $operatorType : Comparison operator
- if ($conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
- $type = 0x02;
- $operatorType = 0x00;
- } elseif ($conditional->getConditionType() == Conditional::CONDITION_CELLIS) {
- $type = 0x01;
-
- switch ($conditional->getOperatorType()) {
- case Conditional::OPERATOR_NONE:
- $operatorType = 0x00;
-
- break;
- case Conditional::OPERATOR_EQUAL:
- $operatorType = 0x03;
-
- break;
- case Conditional::OPERATOR_GREATERTHAN:
- $operatorType = 0x05;
-
- break;
- case Conditional::OPERATOR_GREATERTHANOREQUAL:
- $operatorType = 0x07;
-
- break;
- case Conditional::OPERATOR_LESSTHAN:
- $operatorType = 0x06;
-
- break;
- case Conditional::OPERATOR_LESSTHANOREQUAL:
- $operatorType = 0x08;
-
- break;
- case Conditional::OPERATOR_NOTEQUAL:
- $operatorType = 0x04;
-
- break;
- case Conditional::OPERATOR_BETWEEN:
- $operatorType = 0x01;
-
- break;
- // not OPERATOR_NOTBETWEEN 0x02
- }
- }
-
- // $szValue1 : size of the formula data for first value or formula
- // $szValue2 : size of the formula data for second value or formula
- $arrConditions = $conditional->getConditions();
- $numConditions = count($arrConditions);
- if ($numConditions == 1) {
- $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000);
- $szValue2 = 0x0000;
- $operand1 = pack('Cv', 0x1E, $arrConditions[0]);
- $operand2 = null;
- } elseif ($numConditions == 2 && ($conditional->getOperatorType() == Conditional::OPERATOR_BETWEEN)) {
- $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000);
- $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000);
- $operand1 = pack('Cv', 0x1E, $arrConditions[0]);
- $operand2 = pack('Cv', 0x1E, $arrConditions[1]);
- } else {
- $szValue1 = 0x0000;
- $szValue2 = 0x0000;
- $operand1 = null;
- $operand2 = null;
- }
-
- // $flags : Option flags
- // Alignment
- $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0);
- $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0);
- $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0);
- $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0);
- $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0);
- $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0);
- if ($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0) {
- $bFormatAlign = 1;
- } else {
- $bFormatAlign = 0;
- }
- // Protection
- $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0);
- $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0);
- if ($bProtLocked == 0 || $bProtHidden == 0) {
- $bFormatProt = 1;
- } else {
- $bFormatProt = 0;
- }
- // Border
- $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == Color::COLOR_BLACK
- && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == Border::BORDER_NONE ? 1 : 0);
- $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == Color::COLOR_BLACK
- && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == Border::BORDER_NONE ? 1 : 0);
- $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == Color::COLOR_BLACK
- && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == Border::BORDER_NONE ? 1 : 0);
- $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == Color::COLOR_BLACK
- && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == Border::BORDER_NONE ? 1 : 0);
- if ($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0) {
- $bFormatBorder = 1;
- } else {
- $bFormatBorder = 0;
- }
- // Pattern
- $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1);
- $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1);
- $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1);
- if ($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0) {
- $bFormatFill = 1;
- } else {
- $bFormatFill = 0;
- }
- // Font
- if (
- $conditional->getStyle()->getFont()->getName() != null
- || $conditional->getStyle()->getFont()->getSize() != null
- || $conditional->getStyle()->getFont()->getBold() != null
- || $conditional->getStyle()->getFont()->getItalic() != null
- || $conditional->getStyle()->getFont()->getSuperscript() != null
- || $conditional->getStyle()->getFont()->getSubscript() != null
- || $conditional->getStyle()->getFont()->getUnderline() != null
- || $conditional->getStyle()->getFont()->getStrikethrough() != null
- || $conditional->getStyle()->getFont()->getColor()->getARGB() != null
- ) {
- $bFormatFont = 1;
- } else {
- $bFormatFont = 0;
- }
- // Alignment
- $flags = 0;
- $flags |= (1 == $bAlignHz ? 0x00000001 : 0);
- $flags |= (1 == $bAlignVt ? 0x00000002 : 0);
- $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0);
- $flags |= (1 == $bTxRotation ? 0x00000008 : 0);
- // Justify last line flag
- $flags |= (1 == 1 ? 0x00000010 : 0);
- $flags |= (1 == $bIndent ? 0x00000020 : 0);
- $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0);
- // Default
- $flags |= (1 == 1 ? 0x00000080 : 0);
- // Protection
- $flags |= (1 == $bProtLocked ? 0x00000100 : 0);
- $flags |= (1 == $bProtHidden ? 0x00000200 : 0);
- // Border
- $flags |= (1 == $bBorderLeft ? 0x00000400 : 0);
- $flags |= (1 == $bBorderRight ? 0x00000800 : 0);
- $flags |= (1 == $bBorderTop ? 0x00001000 : 0);
- $flags |= (1 == $bBorderBottom ? 0x00002000 : 0);
- $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border
- $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border
- // Pattern
- $flags |= (1 == $bFillStyle ? 0x00010000 : 0);
- $flags |= (1 == $bFillColor ? 0x00020000 : 0);
- $flags |= (1 == $bFillColorBg ? 0x00040000 : 0);
- $flags |= (1 == 1 ? 0x00380000 : 0);
- // Font
- $flags |= (1 == $bFormatFont ? 0x04000000 : 0);
- // Alignment:
- $flags |= (1 == $bFormatAlign ? 0x08000000 : 0);
- // Border
- $flags |= (1 == $bFormatBorder ? 0x10000000 : 0);
- // Pattern
- $flags |= (1 == $bFormatFill ? 0x20000000 : 0);
- // Protection
- $flags |= (1 == $bFormatProt ? 0x40000000 : 0);
- // Text direction
- $flags |= (1 == 0 ? 0x80000000 : 0);
-
- // Data Blocks
- if ($bFormatFont == 1) {
- // Font Name
- if ($conditional->getStyle()->getFont()->getName() == null) {
- $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
- $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
- } else {
- $dataBlockFont = StringHelper::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName());
- }
- // Font Size
- if ($conditional->getStyle()->getFont()->getSize() == null) {
- $dataBlockFont .= pack('V', 20 * 11);
- } else {
- $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize());
- }
- // Font Options
- $dataBlockFont .= pack('V', 0);
- // Font weight
- if ($conditional->getStyle()->getFont()->getBold() == true) {
- $dataBlockFont .= pack('v', 0x02BC);
- } else {
- $dataBlockFont .= pack('v', 0x0190);
- }
- // Escapement type
- if ($conditional->getStyle()->getFont()->getSubscript() == true) {
- $dataBlockFont .= pack('v', 0x02);
- $fontEscapement = 0;
- } elseif ($conditional->getStyle()->getFont()->getSuperscript() == true) {
- $dataBlockFont .= pack('v', 0x01);
- $fontEscapement = 0;
- } else {
- $dataBlockFont .= pack('v', 0x00);
- $fontEscapement = 1;
- }
- // Underline type
- switch ($conditional->getStyle()->getFont()->getUnderline()) {
- case \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_NONE:
- $dataBlockFont .= pack('C', 0x00);
- $fontUnderline = 0;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE:
- $dataBlockFont .= pack('C', 0x02);
- $fontUnderline = 0;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLEACCOUNTING:
- $dataBlockFont .= pack('C', 0x22);
- $fontUnderline = 0;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE:
- $dataBlockFont .= pack('C', 0x01);
- $fontUnderline = 0;
-
- break;
- case \PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLEACCOUNTING:
- $dataBlockFont .= pack('C', 0x21);
- $fontUnderline = 0;
-
- break;
- default:
- $dataBlockFont .= pack('C', 0x00);
- $fontUnderline = 1;
-
- break;
- }
- // Not used (3)
- $dataBlockFont .= pack('vC', 0x0000, 0x00);
- // Font color index
- switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) {
- case '000000':
- $colorIdx = 0x08;
-
- break;
- case 'FFFFFF':
- $colorIdx = 0x09;
-
- break;
- case 'FF0000':
- $colorIdx = 0x0A;
-
- break;
- case '00FF00':
- $colorIdx = 0x0B;
-
- break;
- case '0000FF':
- $colorIdx = 0x0C;
-
- break;
- case 'FFFF00':
- $colorIdx = 0x0D;
-
- break;
- case 'FF00FF':
- $colorIdx = 0x0E;
-
- break;
- case '00FFFF':
- $colorIdx = 0x0F;
-
- break;
- case '800000':
- $colorIdx = 0x10;
-
- break;
- case '008000':
- $colorIdx = 0x11;
-
- break;
- case '000080':
- $colorIdx = 0x12;
-
- break;
- case '808000':
- $colorIdx = 0x13;
-
- break;
- case '800080':
- $colorIdx = 0x14;
-
- break;
- case '008080':
- $colorIdx = 0x15;
-
- break;
- case 'C0C0C0':
- $colorIdx = 0x16;
-
- break;
- case '808080':
- $colorIdx = 0x17;
-
- break;
- case '9999FF':
- $colorIdx = 0x18;
-
- break;
- case '993366':
- $colorIdx = 0x19;
-
- break;
- case 'FFFFCC':
- $colorIdx = 0x1A;
-
- break;
- case 'CCFFFF':
- $colorIdx = 0x1B;
-
- break;
- case '660066':
- $colorIdx = 0x1C;
-
- break;
- case 'FF8080':
- $colorIdx = 0x1D;
-
- break;
- case '0066CC':
- $colorIdx = 0x1E;
-
- break;
- case 'CCCCFF':
- $colorIdx = 0x1F;
-
- break;
- case '000080':
- $colorIdx = 0x20;
-
- break;
- case 'FF00FF':
- $colorIdx = 0x21;
-
- break;
- case 'FFFF00':
- $colorIdx = 0x22;
-
- break;
- case '00FFFF':
- $colorIdx = 0x23;
-
- break;
- case '800080':
- $colorIdx = 0x24;
-
- break;
- case '800000':
- $colorIdx = 0x25;
-
- break;
- case '008080':
- $colorIdx = 0x26;
-
- break;
- case '0000FF':
- $colorIdx = 0x27;
-
- break;
- case '00CCFF':
- $colorIdx = 0x28;
-
- break;
- case 'CCFFFF':
- $colorIdx = 0x29;
-
- break;
- case 'CCFFCC':
- $colorIdx = 0x2A;
-
- break;
- case 'FFFF99':
- $colorIdx = 0x2B;
-
- break;
- case '99CCFF':
- $colorIdx = 0x2C;
-
- break;
- case 'FF99CC':
- $colorIdx = 0x2D;
-
- break;
- case 'CC99FF':
- $colorIdx = 0x2E;
-
- break;
- case 'FFCC99':
- $colorIdx = 0x2F;
-
- break;
- case '3366FF':
- $colorIdx = 0x30;
-
- break;
- case '33CCCC':
- $colorIdx = 0x31;
-
- break;
- case '99CC00':
- $colorIdx = 0x32;
-
- break;
- case 'FFCC00':
- $colorIdx = 0x33;
-
- break;
- case 'FF9900':
- $colorIdx = 0x34;
-
- break;
- case 'FF6600':
- $colorIdx = 0x35;
-
- break;
- case '666699':
- $colorIdx = 0x36;
-
- break;
- case '969696':
- $colorIdx = 0x37;
-
- break;
- case '003366':
- $colorIdx = 0x38;
-
- break;
- case '339966':
- $colorIdx = 0x39;
-
- break;
- case '003300':
- $colorIdx = 0x3A;
-
- break;
- case '333300':
- $colorIdx = 0x3B;
-
- break;
- case '993300':
- $colorIdx = 0x3C;
-
- break;
- case '993366':
- $colorIdx = 0x3D;
-
- break;
- case '333399':
- $colorIdx = 0x3E;
-
- break;
- case '333333':
- $colorIdx = 0x3F;
-
- break;
- default:
- $colorIdx = 0x00;
-
- break;
- }
- $dataBlockFont .= pack('V', $colorIdx);
- // Not used (4)
- $dataBlockFont .= pack('V', 0x00000000);
- // Options flags for modified font attributes
- $optionsFlags = 0;
- $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0);
- $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0);
- $optionsFlags |= (1 == 1 ? 0x00000008 : 0);
- $optionsFlags |= (1 == 1 ? 0x00000010 : 0);
- $optionsFlags |= (1 == 0 ? 0x00000020 : 0);
- $optionsFlags |= (1 == 1 ? 0x00000080 : 0);
- $dataBlockFont .= pack('V', $optionsFlags);
- // Escapement type
- $dataBlockFont .= pack('V', $fontEscapement);
- // Underline type
- $dataBlockFont .= pack('V', $fontUnderline);
- // Always
- $dataBlockFont .= pack('V', 0x00000000);
- // Always
- $dataBlockFont .= pack('V', 0x00000000);
- // Not used (8)
- $dataBlockFont .= pack('VV', 0x00000000, 0x00000000);
- // Always
- $dataBlockFont .= pack('v', 0x0001);
- }
- if ($bFormatAlign == 1) {
- $blockAlign = 0;
- // Alignment and text break
- switch ($conditional->getStyle()->getAlignment()->getHorizontal()) {
- case Alignment::HORIZONTAL_GENERAL:
- $blockAlign = 0;
-
- break;
- case Alignment::HORIZONTAL_LEFT:
- $blockAlign = 1;
-
- break;
- case Alignment::HORIZONTAL_RIGHT:
- $blockAlign = 3;
-
- break;
- case Alignment::HORIZONTAL_CENTER:
- $blockAlign = 2;
-
- break;
- case Alignment::HORIZONTAL_CENTER_CONTINUOUS:
- $blockAlign = 6;
-
- break;
- case Alignment::HORIZONTAL_JUSTIFY:
- $blockAlign = 5;
-
- break;
- }
- if ($conditional->getStyle()->getAlignment()->getWrapText() == true) {
- $blockAlign |= 1 << 3;
- } else {
- $blockAlign |= 0 << 3;
- }
- switch ($conditional->getStyle()->getAlignment()->getVertical()) {
- case Alignment::VERTICAL_BOTTOM:
- $blockAlign = 2 << 4;
-
- break;
- case Alignment::VERTICAL_TOP:
- $blockAlign = 0 << 4;
-
- break;
- case Alignment::VERTICAL_CENTER:
- $blockAlign = 1 << 4;
-
- break;
- case Alignment::VERTICAL_JUSTIFY:
- $blockAlign = 3 << 4;
-
- break;
- }
- $blockAlign |= 0 << 7;
-
- // Text rotation angle
- $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation();
-
- // Indentation
- $blockIndent = $conditional->getStyle()->getAlignment()->getIndent();
- if ($conditional->getStyle()->getAlignment()->getShrinkToFit() == true) {
- $blockIndent |= 1 << 4;
- } else {
- $blockIndent |= 0 << 4;
- }
- $blockIndent |= 0 << 6;
-
- // Relative indentation
- $blockIndentRelative = 255;
-
- $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000);
- }
- if ($bFormatBorder == 1) {
- $blockLineStyle = 0;
- switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()) {
- case Border::BORDER_NONE:
- $blockLineStyle |= 0x00;
-
- break;
- case Border::BORDER_THIN:
- $blockLineStyle |= 0x01;
-
- break;
- case Border::BORDER_MEDIUM:
- $blockLineStyle |= 0x02;
-
- break;
- case Border::BORDER_DASHED:
- $blockLineStyle |= 0x03;
-
- break;
- case Border::BORDER_DOTTED:
- $blockLineStyle |= 0x04;
-
- break;
- case Border::BORDER_THICK:
- $blockLineStyle |= 0x05;
-
- break;
- case Border::BORDER_DOUBLE:
- $blockLineStyle |= 0x06;
-
- break;
- case Border::BORDER_HAIR:
- $blockLineStyle |= 0x07;
-
- break;
- case Border::BORDER_MEDIUMDASHED:
- $blockLineStyle |= 0x08;
-
- break;
- case Border::BORDER_DASHDOT:
- $blockLineStyle |= 0x09;
-
- break;
- case Border::BORDER_MEDIUMDASHDOT:
- $blockLineStyle |= 0x0A;
-
- break;
- case Border::BORDER_DASHDOTDOT:
- $blockLineStyle |= 0x0B;
-
- break;
- case Border::BORDER_MEDIUMDASHDOTDOT:
- $blockLineStyle |= 0x0C;
-
- break;
- case Border::BORDER_SLANTDASHDOT:
- $blockLineStyle |= 0x0D;
-
- break;
- }
- switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()) {
- case Border::BORDER_NONE:
- $blockLineStyle |= 0x00 << 4;
-
- break;
- case Border::BORDER_THIN:
- $blockLineStyle |= 0x01 << 4;
-
- break;
- case Border::BORDER_MEDIUM:
- $blockLineStyle |= 0x02 << 4;
-
- break;
- case Border::BORDER_DASHED:
- $blockLineStyle |= 0x03 << 4;
-
- break;
- case Border::BORDER_DOTTED:
- $blockLineStyle |= 0x04 << 4;
-
- break;
- case Border::BORDER_THICK:
- $blockLineStyle |= 0x05 << 4;
-
- break;
- case Border::BORDER_DOUBLE:
- $blockLineStyle |= 0x06 << 4;
-
- break;
- case Border::BORDER_HAIR:
- $blockLineStyle |= 0x07 << 4;
-
- break;
- case Border::BORDER_MEDIUMDASHED:
- $blockLineStyle |= 0x08 << 4;
-
- break;
- case Border::BORDER_DASHDOT:
- $blockLineStyle |= 0x09 << 4;
-
- break;
- case Border::BORDER_MEDIUMDASHDOT:
- $blockLineStyle |= 0x0A << 4;
-
- break;
- case Border::BORDER_DASHDOTDOT:
- $blockLineStyle |= 0x0B << 4;
-
- break;
- case Border::BORDER_MEDIUMDASHDOTDOT:
- $blockLineStyle |= 0x0C << 4;
-
- break;
- case Border::BORDER_SLANTDASHDOT:
- $blockLineStyle |= 0x0D << 4;
-
- break;
- }
- switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()) {
- case Border::BORDER_NONE:
- $blockLineStyle |= 0x00 << 8;
-
- break;
- case Border::BORDER_THIN:
- $blockLineStyle |= 0x01 << 8;
-
- break;
- case Border::BORDER_MEDIUM:
- $blockLineStyle |= 0x02 << 8;
-
- break;
- case Border::BORDER_DASHED:
- $blockLineStyle |= 0x03 << 8;
-
- break;
- case Border::BORDER_DOTTED:
- $blockLineStyle |= 0x04 << 8;
-
- break;
- case Border::BORDER_THICK:
- $blockLineStyle |= 0x05 << 8;
-
- break;
- case Border::BORDER_DOUBLE:
- $blockLineStyle |= 0x06 << 8;
-
- break;
- case Border::BORDER_HAIR:
- $blockLineStyle |= 0x07 << 8;
-
- break;
- case Border::BORDER_MEDIUMDASHED:
- $blockLineStyle |= 0x08 << 8;
-
- break;
- case Border::BORDER_DASHDOT:
- $blockLineStyle |= 0x09 << 8;
-
- break;
- case Border::BORDER_MEDIUMDASHDOT:
- $blockLineStyle |= 0x0A << 8;
-
- break;
- case Border::BORDER_DASHDOTDOT:
- $blockLineStyle |= 0x0B << 8;
-
- break;
- case Border::BORDER_MEDIUMDASHDOTDOT:
- $blockLineStyle |= 0x0C << 8;
-
- break;
- case Border::BORDER_SLANTDASHDOT:
- $blockLineStyle |= 0x0D << 8;
-
- break;
- }
- switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()) {
- case Border::BORDER_NONE:
- $blockLineStyle |= 0x00 << 12;
-
- break;
- case Border::BORDER_THIN:
- $blockLineStyle |= 0x01 << 12;
-
- break;
- case Border::BORDER_MEDIUM:
- $blockLineStyle |= 0x02 << 12;
-
- break;
- case Border::BORDER_DASHED:
- $blockLineStyle |= 0x03 << 12;
-
- break;
- case Border::BORDER_DOTTED:
- $blockLineStyle |= 0x04 << 12;
-
- break;
- case Border::BORDER_THICK:
- $blockLineStyle |= 0x05 << 12;
-
- break;
- case Border::BORDER_DOUBLE:
- $blockLineStyle |= 0x06 << 12;
-
- break;
- case Border::BORDER_HAIR:
- $blockLineStyle |= 0x07 << 12;
-
- break;
- case Border::BORDER_MEDIUMDASHED:
- $blockLineStyle |= 0x08 << 12;
-
- break;
- case Border::BORDER_DASHDOT:
- $blockLineStyle |= 0x09 << 12;
-
- break;
- case Border::BORDER_MEDIUMDASHDOT:
- $blockLineStyle |= 0x0A << 12;
-
- break;
- case Border::BORDER_DASHDOTDOT:
- $blockLineStyle |= 0x0B << 12;
-
- break;
- case Border::BORDER_MEDIUMDASHDOTDOT:
- $blockLineStyle |= 0x0C << 12;
-
- break;
- case Border::BORDER_SLANTDASHDOT:
- $blockLineStyle |= 0x0D << 12;
-
- break;
- }
-
- // TODO writeCFRule() => $blockLineStyle => Index Color for left line
- // TODO writeCFRule() => $blockLineStyle => Index Color for right line
- // TODO writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off
- // TODO writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off
- $blockColor = 0;
- // TODO writeCFRule() => $blockColor => Index Color for top line
- // TODO writeCFRule() => $blockColor => Index Color for bottom line
- // TODO writeCFRule() => $blockColor => Index Color for diagonal line
- switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()) {
- case Border::BORDER_NONE:
- $blockColor |= 0x00 << 21;
-
- break;
- case Border::BORDER_THIN:
- $blockColor |= 0x01 << 21;
-
- break;
- case Border::BORDER_MEDIUM:
- $blockColor |= 0x02 << 21;
-
- break;
- case Border::BORDER_DASHED:
- $blockColor |= 0x03 << 21;
-
- break;
- case Border::BORDER_DOTTED:
- $blockColor |= 0x04 << 21;
-
- break;
- case Border::BORDER_THICK:
- $blockColor |= 0x05 << 21;
-
- break;
- case Border::BORDER_DOUBLE:
- $blockColor |= 0x06 << 21;
-
- break;
- case Border::BORDER_HAIR:
- $blockColor |= 0x07 << 21;
-
- break;
- case Border::BORDER_MEDIUMDASHED:
- $blockColor |= 0x08 << 21;
-
- break;
- case Border::BORDER_DASHDOT:
- $blockColor |= 0x09 << 21;
-
- break;
- case Border::BORDER_MEDIUMDASHDOT:
- $blockColor |= 0x0A << 21;
-
- break;
- case Border::BORDER_DASHDOTDOT:
- $blockColor |= 0x0B << 21;
-
- break;
- case Border::BORDER_MEDIUMDASHDOTDOT:
- $blockColor |= 0x0C << 21;
-
- break;
- case Border::BORDER_SLANTDASHDOT:
- $blockColor |= 0x0D << 21;
-
- break;
- }
- $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor);
- }
- if ($bFormatFill == 1) {
- // Fill Patern Style
- $blockFillPatternStyle = 0;
- switch ($conditional->getStyle()->getFill()->getFillType()) {
- case Fill::FILL_NONE:
- $blockFillPatternStyle = 0x00;
-
- break;
- case Fill::FILL_SOLID:
- $blockFillPatternStyle = 0x01;
-
- break;
- case Fill::FILL_PATTERN_MEDIUMGRAY:
- $blockFillPatternStyle = 0x02;
-
- break;
- case Fill::FILL_PATTERN_DARKGRAY:
- $blockFillPatternStyle = 0x03;
-
- break;
- case Fill::FILL_PATTERN_LIGHTGRAY:
- $blockFillPatternStyle = 0x04;
-
- break;
- case Fill::FILL_PATTERN_DARKHORIZONTAL:
- $blockFillPatternStyle = 0x05;
-
- break;
- case Fill::FILL_PATTERN_DARKVERTICAL:
- $blockFillPatternStyle = 0x06;
-
- break;
- case Fill::FILL_PATTERN_DARKDOWN:
- $blockFillPatternStyle = 0x07;
-
- break;
- case Fill::FILL_PATTERN_DARKUP:
- $blockFillPatternStyle = 0x08;
-
- break;
- case Fill::FILL_PATTERN_DARKGRID:
- $blockFillPatternStyle = 0x09;
-
- break;
- case Fill::FILL_PATTERN_DARKTRELLIS:
- $blockFillPatternStyle = 0x0A;
-
- break;
- case Fill::FILL_PATTERN_LIGHTHORIZONTAL:
- $blockFillPatternStyle = 0x0B;
-
- break;
- case Fill::FILL_PATTERN_LIGHTVERTICAL:
- $blockFillPatternStyle = 0x0C;
-
- break;
- case Fill::FILL_PATTERN_LIGHTDOWN:
- $blockFillPatternStyle = 0x0D;
-
- break;
- case Fill::FILL_PATTERN_LIGHTUP:
- $blockFillPatternStyle = 0x0E;
-
- break;
- case Fill::FILL_PATTERN_LIGHTGRID:
- $blockFillPatternStyle = 0x0F;
-
- break;
- case Fill::FILL_PATTERN_LIGHTTRELLIS:
- $blockFillPatternStyle = 0x10;
-
- break;
- case Fill::FILL_PATTERN_GRAY125:
- $blockFillPatternStyle = 0x11;
-
- break;
- case Fill::FILL_PATTERN_GRAY0625:
- $blockFillPatternStyle = 0x12;
-
- break;
- case Fill::FILL_GRADIENT_LINEAR:
- $blockFillPatternStyle = 0x00;
-
- break; // does not exist in BIFF8
- case Fill::FILL_GRADIENT_PATH:
- $blockFillPatternStyle = 0x00;
-
- break; // does not exist in BIFF8
- default:
- $blockFillPatternStyle = 0x00;
-
- break;
- }
- // Color
- switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) {
- case '000000':
- $colorIdxBg = 0x08;
-
- break;
- case 'FFFFFF':
- $colorIdxBg = 0x09;
-
- break;
- case 'FF0000':
- $colorIdxBg = 0x0A;
-
- break;
- case '00FF00':
- $colorIdxBg = 0x0B;
-
- break;
- case '0000FF':
- $colorIdxBg = 0x0C;
-
- break;
- case 'FFFF00':
- $colorIdxBg = 0x0D;
-
- break;
- case 'FF00FF':
- $colorIdxBg = 0x0E;
-
- break;
- case '00FFFF':
- $colorIdxBg = 0x0F;
-
- break;
- case '800000':
- $colorIdxBg = 0x10;
-
- break;
- case '008000':
- $colorIdxBg = 0x11;
-
- break;
- case '000080':
- $colorIdxBg = 0x12;
-
- break;
- case '808000':
- $colorIdxBg = 0x13;
-
- break;
- case '800080':
- $colorIdxBg = 0x14;
-
- break;
- case '008080':
- $colorIdxBg = 0x15;
-
- break;
- case 'C0C0C0':
- $colorIdxBg = 0x16;
-
- break;
- case '808080':
- $colorIdxBg = 0x17;
-
- break;
- case '9999FF':
- $colorIdxBg = 0x18;
-
- break;
- case '993366':
- $colorIdxBg = 0x19;
-
- break;
- case 'FFFFCC':
- $colorIdxBg = 0x1A;
-
- break;
- case 'CCFFFF':
- $colorIdxBg = 0x1B;
-
- break;
- case '660066':
- $colorIdxBg = 0x1C;
-
- break;
- case 'FF8080':
- $colorIdxBg = 0x1D;
-
- break;
- case '0066CC':
- $colorIdxBg = 0x1E;
-
- break;
- case 'CCCCFF':
- $colorIdxBg = 0x1F;
-
- break;
- case '000080':
- $colorIdxBg = 0x20;
-
- break;
- case 'FF00FF':
- $colorIdxBg = 0x21;
-
- break;
- case 'FFFF00':
- $colorIdxBg = 0x22;
-
- break;
- case '00FFFF':
- $colorIdxBg = 0x23;
-
- break;
- case '800080':
- $colorIdxBg = 0x24;
-
- break;
- case '800000':
- $colorIdxBg = 0x25;
-
- break;
- case '008080':
- $colorIdxBg = 0x26;
-
- break;
- case '0000FF':
- $colorIdxBg = 0x27;
-
- break;
- case '00CCFF':
- $colorIdxBg = 0x28;
-
- break;
- case 'CCFFFF':
- $colorIdxBg = 0x29;
-
- break;
- case 'CCFFCC':
- $colorIdxBg = 0x2A;
-
- break;
- case 'FFFF99':
- $colorIdxBg = 0x2B;
-
- break;
- case '99CCFF':
- $colorIdxBg = 0x2C;
-
- break;
- case 'FF99CC':
- $colorIdxBg = 0x2D;
-
- break;
- case 'CC99FF':
- $colorIdxBg = 0x2E;
-
- break;
- case 'FFCC99':
- $colorIdxBg = 0x2F;
-
- break;
- case '3366FF':
- $colorIdxBg = 0x30;
-
- break;
- case '33CCCC':
- $colorIdxBg = 0x31;
-
- break;
- case '99CC00':
- $colorIdxBg = 0x32;
-
- break;
- case 'FFCC00':
- $colorIdxBg = 0x33;
-
- break;
- case 'FF9900':
- $colorIdxBg = 0x34;
-
- break;
- case 'FF6600':
- $colorIdxBg = 0x35;
-
- break;
- case '666699':
- $colorIdxBg = 0x36;
-
- break;
- case '969696':
- $colorIdxBg = 0x37;
-
- break;
- case '003366':
- $colorIdxBg = 0x38;
-
- break;
- case '339966':
- $colorIdxBg = 0x39;
-
- break;
- case '003300':
- $colorIdxBg = 0x3A;
-
- break;
- case '333300':
- $colorIdxBg = 0x3B;
-
- break;
- case '993300':
- $colorIdxBg = 0x3C;
-
- break;
- case '993366':
- $colorIdxBg = 0x3D;
-
- break;
- case '333399':
- $colorIdxBg = 0x3E;
-
- break;
- case '333333':
- $colorIdxBg = 0x3F;
-
- break;
- default:
- $colorIdxBg = 0x41;
-
- break;
- }
- // Fg Color
- switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) {
- case '000000':
- $colorIdxFg = 0x08;
-
- break;
- case 'FFFFFF':
- $colorIdxFg = 0x09;
-
- break;
- case 'FF0000':
- $colorIdxFg = 0x0A;
-
- break;
- case '00FF00':
- $colorIdxFg = 0x0B;
-
- break;
- case '0000FF':
- $colorIdxFg = 0x0C;
-
- break;
- case 'FFFF00':
- $colorIdxFg = 0x0D;
-
- break;
- case 'FF00FF':
- $colorIdxFg = 0x0E;
-
- break;
- case '00FFFF':
- $colorIdxFg = 0x0F;
-
- break;
- case '800000':
- $colorIdxFg = 0x10;
-
- break;
- case '008000':
- $colorIdxFg = 0x11;
-
- break;
- case '000080':
- $colorIdxFg = 0x12;
-
- break;
- case '808000':
- $colorIdxFg = 0x13;
-
- break;
- case '800080':
- $colorIdxFg = 0x14;
-
- break;
- case '008080':
- $colorIdxFg = 0x15;
-
- break;
- case 'C0C0C0':
- $colorIdxFg = 0x16;
-
- break;
- case '808080':
- $colorIdxFg = 0x17;
-
- break;
- case '9999FF':
- $colorIdxFg = 0x18;
-
- break;
- case '993366':
- $colorIdxFg = 0x19;
-
- break;
- case 'FFFFCC':
- $colorIdxFg = 0x1A;
-
- break;
- case 'CCFFFF':
- $colorIdxFg = 0x1B;
-
- break;
- case '660066':
- $colorIdxFg = 0x1C;
-
- break;
- case 'FF8080':
- $colorIdxFg = 0x1D;
-
- break;
- case '0066CC':
- $colorIdxFg = 0x1E;
-
- break;
- case 'CCCCFF':
- $colorIdxFg = 0x1F;
-
- break;
- case '000080':
- $colorIdxFg = 0x20;
-
- break;
- case 'FF00FF':
- $colorIdxFg = 0x21;
-
- break;
- case 'FFFF00':
- $colorIdxFg = 0x22;
-
- break;
- case '00FFFF':
- $colorIdxFg = 0x23;
-
- break;
- case '800080':
- $colorIdxFg = 0x24;
-
- break;
- case '800000':
- $colorIdxFg = 0x25;
-
- break;
- case '008080':
- $colorIdxFg = 0x26;
-
- break;
- case '0000FF':
- $colorIdxFg = 0x27;
-
- break;
- case '00CCFF':
- $colorIdxFg = 0x28;
-
- break;
- case 'CCFFFF':
- $colorIdxFg = 0x29;
-
- break;
- case 'CCFFCC':
- $colorIdxFg = 0x2A;
-
- break;
- case 'FFFF99':
- $colorIdxFg = 0x2B;
-
- break;
- case '99CCFF':
- $colorIdxFg = 0x2C;
-
- break;
- case 'FF99CC':
- $colorIdxFg = 0x2D;
-
- break;
- case 'CC99FF':
- $colorIdxFg = 0x2E;
-
- break;
- case 'FFCC99':
- $colorIdxFg = 0x2F;
-
- break;
- case '3366FF':
- $colorIdxFg = 0x30;
-
- break;
- case '33CCCC':
- $colorIdxFg = 0x31;
-
- break;
- case '99CC00':
- $colorIdxFg = 0x32;
-
- break;
- case 'FFCC00':
- $colorIdxFg = 0x33;
-
- break;
- case 'FF9900':
- $colorIdxFg = 0x34;
-
- break;
- case 'FF6600':
- $colorIdxFg = 0x35;
-
- break;
- case '666699':
- $colorIdxFg = 0x36;
-
- break;
- case '969696':
- $colorIdxFg = 0x37;
-
- break;
- case '003366':
- $colorIdxFg = 0x38;
-
- break;
- case '339966':
- $colorIdxFg = 0x39;
-
- break;
- case '003300':
- $colorIdxFg = 0x3A;
-
- break;
- case '333300':
- $colorIdxFg = 0x3B;
-
- break;
- case '993300':
- $colorIdxFg = 0x3C;
-
- break;
- case '993366':
- $colorIdxFg = 0x3D;
-
- break;
- case '333399':
- $colorIdxFg = 0x3E;
-
- break;
- case '333333':
- $colorIdxFg = 0x3F;
-
- break;
- default:
- $colorIdxFg = 0x40;
-
- break;
- }
- $dataBlockFill = pack('v', $blockFillPatternStyle);
- $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7));
- }
- if ($bFormatProt == 1) {
- $dataBlockProtection = 0;
- if ($conditional->getStyle()->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED) {
- $dataBlockProtection = 1;
- }
- if ($conditional->getStyle()->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED) {
- $dataBlockProtection = 1 << 1;
- }
- }
-
- $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000);
- if ($bFormatFont == 1) { // Block Formatting : OK
- $data .= $dataBlockFont;
- }
- if ($bFormatAlign == 1) {
- $data .= $dataBlockAlign;
- }
- if ($bFormatBorder == 1) {
- $data .= $dataBlockBorder;
- }
- if ($bFormatFill == 1) { // Block Formatting : OK
- $data .= $dataBlockFill;
- }
- if ($bFormatProt == 1) {
- $data .= $dataBlockProtection;
- }
- if ($operand1 !== null) {
- $data .= $operand1;
- }
- if ($operand2 !== null) {
- $data .= $operand2;
- }
- $header = pack('vv', $record, strlen($data));
- $this->append($header . $data);
- }
-
- /**
- * Write CFHeader record.
- */
- private function writeCFHeader(): void
- {
- $record = 0x01B0; // Record identifier
- $length = 0x0016; // Bytes to follow
-
- $numColumnMin = null;
- $numColumnMax = null;
- $numRowMin = null;
- $numRowMax = null;
- $arrConditional = [];
- foreach ($this->phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
- foreach ($conditionalStyles as $conditional) {
- if (
- $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
- || $conditional->getConditionType() == Conditional::CONDITION_CELLIS
- ) {
- if (!in_array($conditional->getHashCode(), $arrConditional)) {
- $arrConditional[] = $conditional->getHashCode();
- }
- // Cells
- $arrCoord = Coordinate::coordinateFromString($cellCoordinate);
- if (!is_numeric($arrCoord[0])) {
- $arrCoord[0] = Coordinate::columnIndexFromString($arrCoord[0]);
- }
- if ($numColumnMin === null || ($numColumnMin > $arrCoord[0])) {
- $numColumnMin = $arrCoord[0];
- }
- if ($numColumnMax === null || ($numColumnMax < $arrCoord[0])) {
- $numColumnMax = $arrCoord[0];
- }
- if ($numRowMin === null || ($numRowMin > $arrCoord[1])) {
- $numRowMin = $arrCoord[1];
- }
- if ($numRowMax === null || ($numRowMax < $arrCoord[1])) {
- $numRowMax = $arrCoord[1];
- }
- }
- }
- }
- $needRedraw = 1;
- $cellRange = pack('vvvv', $numRowMin - 1, $numRowMax - 1, $numColumnMin - 1, $numColumnMax - 1);
-
- $header = pack('vv', $record, $length);
- $data = pack('vv', count($arrConditional), $needRedraw);
- $data .= $cellRange;
- $data .= pack('v', 0x0001);
- $data .= $cellRange;
- $this->append($header . $data);
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xls/Xf.php b/vendor/PhpSpreadsheet/Writer/Xls/Xf.php
deleted file mode 100644
index 3e8169b..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xls/Xf.php
+++ /dev/null
@@ -1,548 +0,0 @@
-
-// *
-// * The majority of this is _NOT_ my code. I simply ported it from the
-// * PERL Spreadsheet::WriteExcel module.
-// *
-// * The author of the Spreadsheet::WriteExcel module is John McNamara
-// *
-// *
-// * I _DO_ maintain this code, and John McNamara has nothing to do with the
-// * porting of this code to PHP. Any questions directly related to this
-// * class library should be directed to me.
-// *
-// * License Information:
-// *
-// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets
-// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com
-// *
-// * This library is free software; you can redistribute it and/or
-// * modify it under the terms of the GNU Lesser General Public
-// * License as published by the Free Software Foundation; either
-// * version 2.1 of the License, or (at your option) any later version.
-// *
-// * This library is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// * Lesser General Public License for more details.
-// *
-// * You should have received a copy of the GNU Lesser General Public
-// * License along with this library; if not, write to the Free Software
-// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-// */
-class Xf
-{
- /**
- * Style XF or a cell XF ?
- *
- * @var bool
- */
- private $isStyleXf;
-
- /**
- * Index to the FONT record. Index 4 does not exist.
- *
- * @var int
- */
- private $fontIndex;
-
- /**
- * An index (2 bytes) to a FORMAT record (number format).
- *
- * @var int
- */
- private $numberFormatIndex;
-
- /**
- * 1 bit, apparently not used.
- *
- * @var int
- */
- private $textJustLast;
-
- /**
- * The cell's foreground color.
- *
- * @var int
- */
- private $foregroundColor;
-
- /**
- * The cell's background color.
- *
- * @var int
- */
- private $backgroundColor;
-
- /**
- * Color of the bottom border of the cell.
- *
- * @var int
- */
- private $bottomBorderColor;
-
- /**
- * Color of the top border of the cell.
- *
- * @var int
- */
- private $topBorderColor;
-
- /**
- * Color of the left border of the cell.
- *
- * @var int
- */
- private $leftBorderColor;
-
- /**
- * Color of the right border of the cell.
- *
- * @var int
- */
- private $rightBorderColor;
-
- /**
- * Constructor.
- *
- * @param Style $style The XF format
- */
- public function __construct(Style $style)
- {
- $this->isStyleXf = false;
- $this->fontIndex = 0;
-
- $this->numberFormatIndex = 0;
-
- $this->textJustLast = 0;
-
- $this->foregroundColor = 0x40;
- $this->backgroundColor = 0x41;
-
- $this->_diag = 0;
-
- $this->bottomBorderColor = 0x40;
- $this->topBorderColor = 0x40;
- $this->leftBorderColor = 0x40;
- $this->rightBorderColor = 0x40;
- $this->_diag_color = 0x40;
- $this->_style = $style;
- }
-
- /**
- * Generate an Excel BIFF XF record (style or cell).
- *
- * @return string The XF record
- */
- public function writeXf()
- {
- // Set the type of the XF record and some of the attributes.
- if ($this->isStyleXf) {
- $style = 0xFFF5;
- } else {
- $style = self::mapLocked($this->_style->getProtection()->getLocked());
- $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1;
- }
-
- // Flags to indicate if attributes have been set.
- $atr_num = ($this->numberFormatIndex != 0) ? 1 : 0;
- $atr_fnt = ($this->fontIndex != 0) ? 1 : 0;
- $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0;
- $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle())) ? 1 : 0;
- $atr_pat = (($this->foregroundColor != 0x40) ||
- ($this->backgroundColor != 0x41) ||
- self::mapFillType($this->_style->getFill()->getFillType())) ? 1 : 0;
- $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked())
- | self::mapHidden($this->_style->getProtection()->getHidden());
-
- // Zero the default border colour if the border has not been set.
- if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) {
- $this->bottomBorderColor = 0;
- }
- if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) {
- $this->topBorderColor = 0;
- }
- if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) {
- $this->rightBorderColor = 0;
- }
- if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) {
- $this->leftBorderColor = 0;
- }
- if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) {
- $this->_diag_color = 0;
- }
-
- $record = 0x00E0; // Record identifier
- $length = 0x0014; // Number of bytes to follow
-
- $ifnt = $this->fontIndex; // Index to FONT record
- $ifmt = $this->numberFormatIndex; // Index to FORMAT record
-
- $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment
- $align |= (int) $this->_style->getAlignment()->getWrapText() << 3;
- $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4;
- $align |= $this->textJustLast << 7;
-
- $used_attrib = $atr_num << 2;
- $used_attrib |= $atr_fnt << 3;
- $used_attrib |= $atr_alc << 4;
- $used_attrib |= $atr_bdr << 5;
- $used_attrib |= $atr_pat << 6;
- $used_attrib |= $atr_prot << 7;
-
- $icv = $this->foregroundColor; // fg and bg pattern colors
- $icv |= $this->backgroundColor << 7;
-
- $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4;
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8;
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12;
- $border1 |= $this->leftBorderColor << 16;
- $border1 |= $this->rightBorderColor << 23;
-
- $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection();
- $diag_tl_to_rb = $diagonalDirection == Borders::DIAGONAL_BOTH
- || $diagonalDirection == Borders::DIAGONAL_DOWN;
- $diag_tr_to_lb = $diagonalDirection == Borders::DIAGONAL_BOTH
- || $diagonalDirection == Borders::DIAGONAL_UP;
- $border1 |= $diag_tl_to_rb << 30;
- $border1 |= $diag_tr_to_lb << 31;
-
- $border2 = $this->topBorderColor; // Border color
- $border2 |= $this->bottomBorderColor << 7;
- $border2 |= $this->_diag_color << 14;
- $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21;
- $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26;
-
- $header = pack('vv', $record, $length);
-
- //BIFF8 options: identation, shrinkToFit and text direction
- $biff8_options = $this->_style->getAlignment()->getIndent();
- $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4;
-
- $data = pack('vvvC', $ifnt, $ifmt, $style, $align);
- $data .= pack('CCC', self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib);
- $data .= pack('VVv', $border1, $border2, $icv);
-
- return $header . $data;
- }
-
- /**
- * Is this a style XF ?
- *
- * @param bool $value
- */
- public function setIsStyleXf($value): void
- {
- $this->isStyleXf = $value;
- }
-
- /**
- * Sets the cell's bottom border color.
- *
- * @param int $colorIndex Color index
- */
- public function setBottomColor($colorIndex): void
- {
- $this->bottomBorderColor = $colorIndex;
- }
-
- /**
- * Sets the cell's top border color.
- *
- * @param int $colorIndex Color index
- */
- public function setTopColor($colorIndex): void
- {
- $this->topBorderColor = $colorIndex;
- }
-
- /**
- * Sets the cell's left border color.
- *
- * @param int $colorIndex Color index
- */
- public function setLeftColor($colorIndex): void
- {
- $this->leftBorderColor = $colorIndex;
- }
-
- /**
- * Sets the cell's right border color.
- *
- * @param int $colorIndex Color index
- */
- public function setRightColor($colorIndex): void
- {
- $this->rightBorderColor = $colorIndex;
- }
-
- /**
- * Sets the cell's diagonal border color.
- *
- * @param int $colorIndex Color index
- */
- public function setDiagColor($colorIndex): void
- {
- $this->_diag_color = $colorIndex;
- }
-
- /**
- * Sets the cell's foreground color.
- *
- * @param int $colorIndex Color index
- */
- public function setFgColor($colorIndex): void
- {
- $this->foregroundColor = $colorIndex;
- }
-
- /**
- * Sets the cell's background color.
- *
- * @param int $colorIndex Color index
- */
- public function setBgColor($colorIndex): void
- {
- $this->backgroundColor = $colorIndex;
- }
-
- /**
- * Sets the index to the number format record
- * It can be date, time, currency, etc...
- *
- * @param int $numberFormatIndex Index to format record
- */
- public function setNumberFormatIndex($numberFormatIndex): void
- {
- $this->numberFormatIndex = $numberFormatIndex;
- }
-
- /**
- * Set the font index.
- *
- * @param int $value Font index, note that value 4 does not exist
- */
- public function setFontIndex($value): void
- {
- $this->fontIndex = $value;
- }
-
- /**
- * Map of BIFF2-BIFF8 codes for border styles.
- *
- * @var array of int
- */
- private static $mapBorderStyles = [
- Border::BORDER_NONE => 0x00,
- Border::BORDER_THIN => 0x01,
- Border::BORDER_MEDIUM => 0x02,
- Border::BORDER_DASHED => 0x03,
- Border::BORDER_DOTTED => 0x04,
- Border::BORDER_THICK => 0x05,
- Border::BORDER_DOUBLE => 0x06,
- Border::BORDER_HAIR => 0x07,
- Border::BORDER_MEDIUMDASHED => 0x08,
- Border::BORDER_DASHDOT => 0x09,
- Border::BORDER_MEDIUMDASHDOT => 0x0A,
- Border::BORDER_DASHDOTDOT => 0x0B,
- Border::BORDER_MEDIUMDASHDOTDOT => 0x0C,
- Border::BORDER_SLANTDASHDOT => 0x0D,
- ];
-
- /**
- * Map border style.
- *
- * @param string $borderStyle
- *
- * @return int
- */
- private static function mapBorderStyle($borderStyle)
- {
- if (isset(self::$mapBorderStyles[$borderStyle])) {
- return self::$mapBorderStyles[$borderStyle];
- }
-
- return 0x00;
- }
-
- /**
- * Map of BIFF2-BIFF8 codes for fill types.
- *
- * @var array of int
- */
- private static $mapFillTypes = [
- Fill::FILL_NONE => 0x00,
- Fill::FILL_SOLID => 0x01,
- Fill::FILL_PATTERN_MEDIUMGRAY => 0x02,
- Fill::FILL_PATTERN_DARKGRAY => 0x03,
- Fill::FILL_PATTERN_LIGHTGRAY => 0x04,
- Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05,
- Fill::FILL_PATTERN_DARKVERTICAL => 0x06,
- Fill::FILL_PATTERN_DARKDOWN => 0x07,
- Fill::FILL_PATTERN_DARKUP => 0x08,
- Fill::FILL_PATTERN_DARKGRID => 0x09,
- Fill::FILL_PATTERN_DARKTRELLIS => 0x0A,
- Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B,
- Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C,
- Fill::FILL_PATTERN_LIGHTDOWN => 0x0D,
- Fill::FILL_PATTERN_LIGHTUP => 0x0E,
- Fill::FILL_PATTERN_LIGHTGRID => 0x0F,
- Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10,
- Fill::FILL_PATTERN_GRAY125 => 0x11,
- Fill::FILL_PATTERN_GRAY0625 => 0x12,
- Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8
- Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8
- ];
-
- /**
- * Map fill type.
- *
- * @param string $fillType
- *
- * @return int
- */
- private static function mapFillType($fillType)
- {
- if (isset(self::$mapFillTypes[$fillType])) {
- return self::$mapFillTypes[$fillType];
- }
-
- return 0x00;
- }
-
- /**
- * Map of BIFF2-BIFF8 codes for horizontal alignment.
- *
- * @var array of int
- */
- private static $mapHAlignments = [
- Alignment::HORIZONTAL_GENERAL => 0,
- Alignment::HORIZONTAL_LEFT => 1,
- Alignment::HORIZONTAL_CENTER => 2,
- Alignment::HORIZONTAL_RIGHT => 3,
- Alignment::HORIZONTAL_FILL => 4,
- Alignment::HORIZONTAL_JUSTIFY => 5,
- Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6,
- ];
-
- /**
- * Map to BIFF2-BIFF8 codes for horizontal alignment.
- *
- * @param string $hAlign
- *
- * @return int
- */
- private function mapHAlign($hAlign)
- {
- if (isset(self::$mapHAlignments[$hAlign])) {
- return self::$mapHAlignments[$hAlign];
- }
-
- return 0;
- }
-
- /**
- * Map of BIFF2-BIFF8 codes for vertical alignment.
- *
- * @var array of int
- */
- private static $mapVAlignments = [
- Alignment::VERTICAL_TOP => 0,
- Alignment::VERTICAL_CENTER => 1,
- Alignment::VERTICAL_BOTTOM => 2,
- Alignment::VERTICAL_JUSTIFY => 3,
- ];
-
- /**
- * Map to BIFF2-BIFF8 codes for vertical alignment.
- *
- * @param string $vAlign
- *
- * @return int
- */
- private static function mapVAlign($vAlign)
- {
- if (isset(self::$mapVAlignments[$vAlign])) {
- return self::$mapVAlignments[$vAlign];
- }
-
- return 2;
- }
-
- /**
- * Map to BIFF8 codes for text rotation angle.
- *
- * @param int $textRotation
- *
- * @return int
- */
- private static function mapTextRotation($textRotation)
- {
- if ($textRotation >= 0) {
- return $textRotation;
- } elseif ($textRotation == -165) {
- return 255;
- } elseif ($textRotation < 0) {
- return 90 - $textRotation;
- }
- }
-
- /**
- * Map locked.
- *
- * @param string $locked
- *
- * @return int
- */
- private static function mapLocked($locked)
- {
- switch ($locked) {
- case Protection::PROTECTION_INHERIT:
- return 1;
- case Protection::PROTECTION_PROTECTED:
- return 1;
- case Protection::PROTECTION_UNPROTECTED:
- return 0;
- default:
- return 1;
- }
- }
-
- /**
- * Map hidden.
- *
- * @param string $hidden
- *
- * @return int
- */
- private static function mapHidden($hidden)
- {
- switch ($hidden) {
- case Protection::PROTECTION_INHERIT:
- return 0;
- case Protection::PROTECTION_PROTECTED:
- return 1;
- case Protection::PROTECTION_UNPROTECTED:
- return 0;
- default:
- return 0;
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx.php b/vendor/PhpSpreadsheet/Writer/Xlsx.php
deleted file mode 100644
index 4cb1028..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx.php
+++ /dev/null
@@ -1,556 +0,0 @@
-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 resource|string $pFilename
- */
- public function save($pFilename): void
- {
- if ($this->spreadSheet !== null) {
- // garbage collect
- $this->pathNames = [];
- $this->spreadSheet->garbageCollect();
-
- $this->openFileHandle($pFilename);
-
- $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 < $this->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));
-
- $options = new Archive();
- $options->setEnableZip64(false);
- $options->setOutputStream($this->fileHandle);
-
- $this->zip = new ZipStream(null, $options);
-
- // Add [Content_Types].xml to ZIP file
- $this->addZipFile('[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 ?
- $this->addZipFile('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
- $this->addZipFile('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
- $this->addZipFile('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');
- $this->addZipFile($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) {
- $this->addZipFile($tmpRootPath . $aPath, $aContent);
- }
- //the rels for files
- $this->addZipFile($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
- }
- }
-
- // Add relationships to ZIP file
- $this->addZipFile('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
- $this->addZipFile('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
-
- // Add document properties to ZIP file
- $this->addZipFile('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
- $this->addZipFile('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
- $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
- if ($customPropertiesPart !== null) {
- $this->addZipFile('docProps/custom.xml', $customPropertiesPart);
- }
-
- // Add theme to ZIP file
- $this->addZipFile('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
-
- // Add string table to ZIP file
- $this->addZipFile('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
-
- // Add styles to ZIP file
- $this->addZipFile('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
-
- // Add workbook to ZIP file
- $this->addZipFile('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
-
- $chartCount = 0;
- // Add worksheets
- for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
- $this->addZipFile('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) {
- $this->addZipFile('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
- ++$chartCount;
- }
- }
- }
- }
-
- $chartRef1 = 0;
- // Add worksheet relationships (drawings, ...)
- for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
- // Add relationships
- $this->addZipFile('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) {
- $this->addZipFile($ctrlProp['filePath'], $ctrlProp['content']);
- }
- }
- if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
- foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
- $this->addZipFile($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
- $this->addZipFile('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
-
- // Drawings
- $this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
- } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
- // Drawings
- $this->addZipFile('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, '.');
- $this->addZipFile('xl' . $drawingFile, $drawingXml);
- }
- }
- }
-
- // Add comment relationship parts
- if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
- // VML Comments
- $this->addZipFile('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
-
- // Comments
- $this->addZipFile('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) {
- $this->addZipFile($vmlDrawing['filePath'], $vmlDrawing['content']);
- }
- }
-
- // Add header/footer relationship parts
- if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
- // VML Drawings
- $this->addZipFile('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
-
- // VML Drawing relationships
- $this->addZipFile('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) {
- $this->addZipFile('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
- }
- }
- }
-
- // Add media
- for ($i = 0; $i < $this->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);
- }
-
- $this->addZipFile('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();
-
- $this->addZipFile('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
- }
- }
-
- Functions::setReturnDateType($saveDateReturnType);
- Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
-
- // Close file
- try {
- $this->zip->finish();
- } catch (OverflowException $e) {
- throw new WriterException('Could not close resource.');
- }
-
- $this->maybeCloseFileHandle();
- } else {
- throw new WriterException('PhpSpreadsheet object unassigned.');
- }
- }
-
- /**
- * Get Spreadsheet object.
- *
- * @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 $this
- */
- 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 $this
- */
- public function setOffice2003Compatibility($pValue)
- {
- $this->office2003compatibility = $pValue;
-
- return $this;
- }
-
- private $pathNames = [];
-
- private function addZipFile(string $path, string $content): void
- {
- if (!in_array($path, $this->pathNames)) {
- $this->pathNames[] = $path;
- $this->zip->addFile($path, $content);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Chart.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Chart.php
deleted file mode 100644
index 583b262..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Chart.php
+++ /dev/null
@@ -1,1516 +0,0 @@
-calculateCellValues = $calculateCellValues;
-
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
- // Ensure that data series values are up-to-date before we save
- if ($this->calculateCellValues) {
- $pChart->refresh();
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // c:chartSpace
- $objWriter->startElement('c:chartSpace');
- $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
- $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
-
- $objWriter->startElement('c:date1904');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- $objWriter->startElement('c:lang');
- $objWriter->writeAttribute('val', 'en-GB');
- $objWriter->endElement();
- $objWriter->startElement('c:roundedCorners');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $this->writeAlternateContent($objWriter);
-
- $objWriter->startElement('c:chart');
-
- $this->writeTitle($objWriter, $pChart->getTitle());
-
- $objWriter->startElement('c:autoTitleDeleted');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $this->writePlotArea($objWriter, $pChart->getWorksheet(), $pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines());
-
- $this->writeLegend($objWriter, $pChart->getLegend());
-
- $objWriter->startElement('c:plotVisOnly');
- $objWriter->writeAttribute('val', (int) $pChart->getPlotVisibleOnly());
- $objWriter->endElement();
-
- $objWriter->startElement('c:dispBlanksAs');
- $objWriter->writeAttribute('val', $pChart->getDisplayBlanksAs());
- $objWriter->endElement();
-
- $objWriter->startElement('c:showDLblsOverMax');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $this->writePrintSettings($objWriter);
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write Chart Title.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Title $title
- */
- private function writeTitle(XMLWriter $objWriter, ?Title $title = null): void
- {
- if ($title === null) {
- return;
- }
-
- $objWriter->startElement('c:title');
- $objWriter->startElement('c:tx');
- $objWriter->startElement('c:rich');
-
- $objWriter->startElement('a:bodyPr');
- $objWriter->endElement();
-
- $objWriter->startElement('a:lstStyle');
- $objWriter->endElement();
-
- $objWriter->startElement('a:p');
-
- $caption = $title->getCaption();
- if ((is_array($caption)) && (count($caption) > 0)) {
- $caption = $caption[0];
- }
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a');
-
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- $this->writeLayout($objWriter, $title->getLayout());
-
- $objWriter->startElement('c:overlay');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Chart Legend.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Legend $legend
- */
- private function writeLegend(XMLWriter $objWriter, ?Legend $legend = null): void
- {
- if ($legend === null) {
- return;
- }
-
- $objWriter->startElement('c:legend');
-
- $objWriter->startElement('c:legendPos');
- $objWriter->writeAttribute('val', $legend->getPosition());
- $objWriter->endElement();
-
- $this->writeLayout($objWriter, $legend->getLayout());
-
- $objWriter->startElement('c:overlay');
- $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');
- $objWriter->endElement();
-
- $objWriter->startElement('c:txPr');
- $objWriter->startElement('a:bodyPr');
- $objWriter->endElement();
-
- $objWriter->startElement('a:lstStyle');
- $objWriter->endElement();
-
- $objWriter->startElement('a:p');
- $objWriter->startElement('a:pPr');
- $objWriter->writeAttribute('rtl', 0);
-
- $objWriter->startElement('a:defRPr');
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('a:endParaRPr');
- $objWriter->writeAttribute('lang', 'en-US');
- $objWriter->endElement();
-
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Chart Plot Area.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Title $xAxisLabel
- * @param Title $yAxisLabel
- * @param Axis $xAxis
- * @param Axis $yAxis
- */
- private function writePlotArea(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pSheet, PlotArea $plotArea, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null): void
- {
- if ($plotArea === null) {
- return;
- }
-
- $id1 = $id2 = 0;
- $this->seriesIndex = 0;
- $objWriter->startElement('c:plotArea');
-
- $layout = $plotArea->getLayout();
-
- $this->writeLayout($objWriter, $layout);
-
- $chartTypes = self::getChartType($plotArea);
- $catIsMultiLevelSeries = $valIsMultiLevelSeries = false;
- $plotGroupingType = '';
- foreach ($chartTypes as $chartType) {
- $objWriter->startElement('c:' . $chartType);
-
- $groupCount = $plotArea->getPlotGroupCount();
- for ($i = 0; $i < $groupCount; ++$i) {
- $plotGroup = $plotArea->getPlotGroupByIndex($i);
- $groupType = $plotGroup->getPlotType();
- if ($groupType == $chartType) {
- $plotStyle = $plotGroup->getPlotStyle();
- if ($groupType === DataSeries::TYPE_RADARCHART) {
- $objWriter->startElement('c:radarStyle');
- $objWriter->writeAttribute('val', $plotStyle);
- $objWriter->endElement();
- } elseif ($groupType === DataSeries::TYPE_SCATTERCHART) {
- $objWriter->startElement('c:scatterStyle');
- $objWriter->writeAttribute('val', $plotStyle);
- $objWriter->endElement();
- }
-
- $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType);
- }
- }
-
- $this->writeDataLabels($objWriter, $layout);
-
- if ($chartType === DataSeries::TYPE_LINECHART) {
- // Line only, Line3D can't be smoothed
- $objWriter->startElement('c:smooth');
- $objWriter->writeAttribute('val', (int) $plotGroup->getSmoothLine());
- $objWriter->endElement();
- } elseif (($chartType === DataSeries::TYPE_BARCHART) || ($chartType === DataSeries::TYPE_BARCHART_3D)) {
- $objWriter->startElement('c:gapWidth');
- $objWriter->writeAttribute('val', 150);
- $objWriter->endElement();
-
- if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') {
- $objWriter->startElement('c:overlap');
- $objWriter->writeAttribute('val', 100);
- $objWriter->endElement();
- }
- } elseif ($chartType === DataSeries::TYPE_BUBBLECHART) {
- $objWriter->startElement('c:bubbleScale');
- $objWriter->writeAttribute('val', 25);
- $objWriter->endElement();
-
- $objWriter->startElement('c:showNegBubbles');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- } elseif ($chartType === DataSeries::TYPE_STOCKCHART) {
- $objWriter->startElement('c:hiLowLines');
- $objWriter->endElement();
-
- $objWriter->startElement('c:upDownBars');
-
- $objWriter->startElement('c:gapWidth');
- $objWriter->writeAttribute('val', 300);
- $objWriter->endElement();
-
- $objWriter->startElement('c:upBars');
- $objWriter->endElement();
-
- $objWriter->startElement('c:downBars');
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- // Generate 2 unique numbers to use for axId values
- $id1 = '75091328';
- $id2 = '75089408';
-
- if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
- $objWriter->startElement('c:axId');
- $objWriter->writeAttribute('val', $id1);
- $objWriter->endElement();
- $objWriter->startElement('c:axId');
- $objWriter->writeAttribute('val', $id2);
- $objWriter->endElement();
- } else {
- $objWriter->startElement('c:firstSliceAng');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- if ($chartType === DataSeries::TYPE_DONUTCHART) {
- $objWriter->startElement('c:holeSize');
- $objWriter->writeAttribute('val', 50);
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
- }
-
- if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
- if ($chartType === DataSeries::TYPE_BUBBLECHART) {
- $this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
- } else {
- $this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $yAxis);
- }
-
- $this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Data Labels.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param \PhpOffice\PhpSpreadsheet\Chart\Layout $chartLayout Chart layout
- */
- private function writeDataLabels(XMLWriter $objWriter, ?Layout $chartLayout = null): void
- {
- $objWriter->startElement('c:dLbls');
-
- $objWriter->startElement('c:showLegendKey');
- $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey();
- $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showVal');
- $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal();
- $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showCatName');
- $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName();
- $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showSerName');
- $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName();
- $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showPercent');
- $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent();
- $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showBubbleSize');
- $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize();
- $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->startElement('c:showLeaderLines');
- $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines();
- $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1));
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Category Axis.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Title $xAxisLabel
- * @param string $id1
- * @param string $id2
- * @param bool $isMultiLevelSeries
- */
- private function writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis): void
- {
- $objWriter->startElement('c:catAx');
-
- if ($id1 > 0) {
- $objWriter->startElement('c:axId');
- $objWriter->writeAttribute('val', $id1);
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:scaling');
- $objWriter->startElement('c:orientation');
- $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation'));
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('c:delete');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->startElement('c:axPos');
- $objWriter->writeAttribute('val', 'b');
- $objWriter->endElement();
-
- if ($xAxisLabel !== null) {
- $objWriter->startElement('c:title');
- $objWriter->startElement('c:tx');
- $objWriter->startElement('c:rich');
-
- $objWriter->startElement('a:bodyPr');
- $objWriter->endElement();
-
- $objWriter->startElement('a:lstStyle');
- $objWriter->endElement();
-
- $objWriter->startElement('a:p');
- $objWriter->startElement('a:r');
-
- $caption = $xAxisLabel->getCaption();
- if (is_array($caption)) {
- $caption = $caption[0];
- }
- $objWriter->startElement('a:t');
- $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
- $objWriter->endElement();
-
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- $layout = $xAxisLabel->getLayout();
- $this->writeLayout($objWriter, $layout);
-
- $objWriter->startElement('c:overlay');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:numFmt');
- $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat());
- $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked());
- $objWriter->endElement();
-
- $objWriter->startElement('c:majorTickMark');
- $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark'));
- $objWriter->endElement();
-
- $objWriter->startElement('c:minorTickMark');
- $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark'));
- $objWriter->endElement();
-
- $objWriter->startElement('c:tickLblPos');
- $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels'));
- $objWriter->endElement();
-
- if ($id2 > 0) {
- $objWriter->startElement('c:crossAx');
- $objWriter->writeAttribute('val', $id2);
- $objWriter->endElement();
-
- $objWriter->startElement('c:crosses');
- $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses'));
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:auto');
- $objWriter->writeAttribute('val', 1);
- $objWriter->endElement();
-
- $objWriter->startElement('c:lblAlgn');
- $objWriter->writeAttribute('val', 'ctr');
- $objWriter->endElement();
-
- $objWriter->startElement('c:lblOffset');
- $objWriter->writeAttribute('val', 100);
- $objWriter->endElement();
-
- if ($isMultiLevelSeries) {
- $objWriter->startElement('c:noMultiLvlLbl');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- }
- $objWriter->endElement();
- }
-
- /**
- * Write Value Axis.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Title $yAxisLabel
- * @param string $groupType Chart type
- * @param string $id1
- * @param string $id2
- * @param bool $isMultiLevelSeries
- */
- private function writeValueAxis($objWriter, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, GridLines $majorGridlines, GridLines $minorGridlines): void
- {
- $objWriter->startElement('c:valAx');
-
- if ($id2 > 0) {
- $objWriter->startElement('c:axId');
- $objWriter->writeAttribute('val', $id2);
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:scaling');
-
- if ($xAxis->getAxisOptionsProperty('maximum') !== null) {
- $objWriter->startElement('c:max');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum'));
- $objWriter->endElement();
- }
-
- if ($xAxis->getAxisOptionsProperty('minimum') !== null) {
- $objWriter->startElement('c:min');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum'));
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:orientation');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation'));
-
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('c:delete');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->startElement('c:axPos');
- $objWriter->writeAttribute('val', 'l');
- $objWriter->endElement();
-
- $objWriter->startElement('c:majorGridlines');
- $objWriter->startElement('c:spPr');
-
- if ($majorGridlines->getLineColorProperty('value') !== null) {
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width'));
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}");
- $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha'));
- $objWriter->endElement(); //end alpha
- $objWriter->endElement(); //end srgbClr
- $objWriter->endElement(); //end solidFill
-
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash'));
- $objWriter->endElement();
-
- if ($majorGridlines->getLineStyleProperty('join') == 'miter') {
- $objWriter->startElement('a:miter');
- $objWriter->writeAttribute('lim', '800000');
- $objWriter->endElement();
- } else {
- $objWriter->startElement('a:bevel');
- $objWriter->endElement();
- }
-
- if ($majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
- $objWriter->startElement('a:headEnd');
- $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']));
- $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w'));
- $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len'));
- $objWriter->endElement();
- }
-
- if ($majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
- $objWriter->startElement('a:tailEnd');
- $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']));
- $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w'));
- $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len'));
- $objWriter->endElement();
- }
- $objWriter->endElement(); //end ln
- }
- $objWriter->startElement('a:effectLst');
-
- if ($majorGridlines->getGlowSize() !== null) {
- $objWriter->startElement('a:glow');
- $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize());
- $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}");
- $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha'));
- $objWriter->endElement(); //end alpha
- $objWriter->endElement(); //end schemeClr
- $objWriter->endElement(); //end glow
- }
-
- if ($majorGridlines->getShadowProperty('presets') !== null) {
- $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}");
- if ($majorGridlines->getShadowProperty('blur') !== null) {
- $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur'));
- }
- if ($majorGridlines->getShadowProperty('distance') !== null) {
- $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance'));
- }
- if ($majorGridlines->getShadowProperty('direction') !== null) {
- $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction'));
- }
- if ($majorGridlines->getShadowProperty('algn') !== null) {
- $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn'));
- }
- if ($majorGridlines->getShadowProperty(['size', 'sx']) !== null) {
- $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx']));
- }
- if ($majorGridlines->getShadowProperty(['size', 'sy']) !== null) {
- $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy']));
- }
- if ($majorGridlines->getShadowProperty(['size', 'kx']) !== null) {
- $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx']));
- }
- if ($majorGridlines->getShadowProperty('rotWithShape') !== null) {
- $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape'));
- }
- $objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}");
- $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value']));
-
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha']));
- $objWriter->endElement(); //end alpha
-
- $objWriter->endElement(); //end color:type
- $objWriter->endElement(); //end shadow
- }
-
- if ($majorGridlines->getSoftEdgesSize() !== null) {
- $objWriter->startElement('a:softEdge');
- $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize());
- $objWriter->endElement(); //end softEdge
- }
-
- $objWriter->endElement(); //end effectLst
- $objWriter->endElement(); //end spPr
- $objWriter->endElement(); //end majorGridLines
-
- if ($minorGridlines->getObjectState()) {
- $objWriter->startElement('c:minorGridlines');
- $objWriter->startElement('c:spPr');
-
- if ($minorGridlines->getLineColorProperty('value') !== null) {
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width'));
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}");
- $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha'));
- $objWriter->endElement(); //end alpha
- $objWriter->endElement(); //end srgbClr
- $objWriter->endElement(); //end solidFill
-
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash'));
- $objWriter->endElement();
-
- if ($minorGridlines->getLineStyleProperty('join') == 'miter') {
- $objWriter->startElement('a:miter');
- $objWriter->writeAttribute('lim', '800000');
- $objWriter->endElement();
- } else {
- $objWriter->startElement('a:bevel');
- $objWriter->endElement();
- }
-
- if ($minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
- $objWriter->startElement('a:headEnd');
- $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']));
- $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w'));
- $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len'));
- $objWriter->endElement();
- }
-
- if ($minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
- $objWriter->startElement('a:tailEnd');
- $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']));
- $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w'));
- $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len'));
- $objWriter->endElement();
- }
- $objWriter->endElement(); //end ln
- }
-
- $objWriter->startElement('a:effectLst');
-
- if ($minorGridlines->getGlowSize() !== null) {
- $objWriter->startElement('a:glow');
- $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize());
- $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}");
- $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha'));
- $objWriter->endElement(); //end alpha
- $objWriter->endElement(); //end schemeClr
- $objWriter->endElement(); //end glow
- }
-
- if ($minorGridlines->getShadowProperty('presets') !== null) {
- $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}");
- if ($minorGridlines->getShadowProperty('blur') !== null) {
- $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur'));
- }
- if ($minorGridlines->getShadowProperty('distance') !== null) {
- $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance'));
- }
- if ($minorGridlines->getShadowProperty('direction') !== null) {
- $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction'));
- }
- if ($minorGridlines->getShadowProperty('algn') !== null) {
- $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn'));
- }
- if ($minorGridlines->getShadowProperty(['size', 'sx']) !== null) {
- $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx']));
- }
- if ($minorGridlines->getShadowProperty(['size', 'sy']) !== null) {
- $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy']));
- }
- if ($minorGridlines->getShadowProperty(['size', 'kx']) !== null) {
- $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx']));
- }
- if ($minorGridlines->getShadowProperty('rotWithShape') !== null) {
- $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape'));
- }
- $objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}");
- $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value']));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha']));
- $objWriter->endElement(); //end alpha
- $objWriter->endElement(); //end color:type
- $objWriter->endElement(); //end shadow
- }
-
- if ($minorGridlines->getSoftEdgesSize() !== null) {
- $objWriter->startElement('a:softEdge');
- $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize());
- $objWriter->endElement(); //end softEdge
- }
-
- $objWriter->endElement(); //end effectLst
- $objWriter->endElement(); //end spPr
- $objWriter->endElement(); //end minorGridLines
- }
-
- if ($yAxisLabel !== null) {
- $objWriter->startElement('c:title');
- $objWriter->startElement('c:tx');
- $objWriter->startElement('c:rich');
-
- $objWriter->startElement('a:bodyPr');
- $objWriter->endElement();
-
- $objWriter->startElement('a:lstStyle');
- $objWriter->endElement();
-
- $objWriter->startElement('a:p');
- $objWriter->startElement('a:r');
-
- $caption = $yAxisLabel->getCaption();
- if (is_array($caption)) {
- $caption = $caption[0];
- }
-
- $objWriter->startElement('a:t');
- $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
- $objWriter->endElement();
-
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- if ($groupType !== DataSeries::TYPE_BUBBLECHART) {
- $layout = $yAxisLabel->getLayout();
- $this->writeLayout($objWriter, $layout);
- }
-
- $objWriter->startElement('c:overlay');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:numFmt');
- $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat());
- $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked());
- $objWriter->endElement();
-
- $objWriter->startElement('c:majorTickMark');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark'));
- $objWriter->endElement();
-
- $objWriter->startElement('c:minorTickMark');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark'));
- $objWriter->endElement();
-
- $objWriter->startElement('c:tickLblPos');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels'));
- $objWriter->endElement();
-
- $objWriter->startElement('c:spPr');
-
- if ($xAxis->getFillProperty('value') !== null) {
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement('a:' . $xAxis->getFillProperty('type'));
- $objWriter->writeAttribute('val', $xAxis->getFillProperty('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha'));
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- }
-
- $objWriter->startElement('a:ln');
-
- $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width'));
- $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap'));
- $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound'));
-
- if ($xAxis->getLineProperty('value') !== null) {
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement('a:' . $xAxis->getLineProperty('type'));
- $objWriter->writeAttribute('val', $xAxis->getLineProperty('value'));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha'));
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- }
-
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash'));
- $objWriter->endElement();
-
- if ($xAxis->getLineStyleProperty('join') == 'miter') {
- $objWriter->startElement('a:miter');
- $objWriter->writeAttribute('lim', '800000');
- $objWriter->endElement();
- } else {
- $objWriter->startElement('a:bevel');
- $objWriter->endElement();
- }
-
- if ($xAxis->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
- $objWriter->startElement('a:headEnd');
- $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'head', 'type']));
- $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head'));
- $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head'));
- $objWriter->endElement();
- }
-
- if ($xAxis->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
- $objWriter->startElement('a:tailEnd');
- $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'end', 'type']));
- $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end'));
- $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end'));
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
-
- $objWriter->startElement('a:effectLst');
-
- if ($xAxis->getGlowProperty('size') !== null) {
- $objWriter->startElement('a:glow');
- $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size'));
- $objWriter->startElement("a:{$xAxis->getGlowProperty(['color', 'type'])}");
- $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'value']));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'alpha']));
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- }
-
- if ($xAxis->getShadowProperty('presets') !== null) {
- $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}");
-
- if ($xAxis->getShadowProperty('blur') !== null) {
- $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur'));
- }
- if ($xAxis->getShadowProperty('distance') !== null) {
- $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance'));
- }
- if ($xAxis->getShadowProperty('direction') !== null) {
- $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction'));
- }
- if ($xAxis->getShadowProperty('algn') !== null) {
- $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn'));
- }
- if ($xAxis->getShadowProperty(['size', 'sx']) !== null) {
- $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size', 'sx']));
- }
- if ($xAxis->getShadowProperty(['size', 'sy']) !== null) {
- $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size', 'sy']));
- }
- if ($xAxis->getShadowProperty(['size', 'kx']) !== null) {
- $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size', 'kx']));
- }
- if ($xAxis->getShadowProperty('rotWithShape') !== null) {
- $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape'));
- }
-
- $objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}");
- $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'value']));
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'alpha']));
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- if ($xAxis->getSoftEdgesSize() !== null) {
- $objWriter->startElement('a:softEdge');
- $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize());
- $objWriter->endElement();
- }
-
- $objWriter->endElement(); //effectList
- $objWriter->endElement(); //end spPr
-
- if ($id1 > 0) {
- $objWriter->startElement('c:crossAx');
- $objWriter->writeAttribute('val', $id2);
- $objWriter->endElement();
-
- if ($xAxis->getAxisOptionsProperty('horizontal_crosses_value') !== null) {
- $objWriter->startElement('c:crossesAt');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value'));
- $objWriter->endElement();
- } else {
- $objWriter->startElement('c:crosses');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses'));
- $objWriter->endElement();
- }
-
- $objWriter->startElement('c:crossBetween');
- $objWriter->writeAttribute('val', 'midCat');
- $objWriter->endElement();
-
- if ($xAxis->getAxisOptionsProperty('major_unit') !== null) {
- $objWriter->startElement('c:majorUnit');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit'));
- $objWriter->endElement();
- }
-
- if ($xAxis->getAxisOptionsProperty('minor_unit') !== null) {
- $objWriter->startElement('c:minorUnit');
- $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit'));
- $objWriter->endElement();
- }
- }
-
- if ($isMultiLevelSeries) {
- if ($groupType !== DataSeries::TYPE_BUBBLECHART) {
- $objWriter->startElement('c:noMultiLvlLbl');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Get the data series type(s) for a chart plot series.
- *
- * @param PlotArea $plotArea
- *
- * @return array|string
- */
- private static function getChartType($plotArea)
- {
- $groupCount = $plotArea->getPlotGroupCount();
-
- if ($groupCount == 1) {
- $chartType = [$plotArea->getPlotGroupByIndex(0)->getPlotType()];
- } else {
- $chartTypes = [];
- for ($i = 0; $i < $groupCount; ++$i) {
- $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType();
- }
- $chartType = array_unique($chartTypes);
- if (count($chartTypes) == 0) {
- throw new WriterException('Chart is not yet implemented');
- }
- }
-
- return $chartType;
- }
-
- /**
- * Method writing plot series values.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param int $val value for idx (default: 3)
- * @param string $fillColor hex color (default: FF9900)
- *
- * @return XMLWriter XML Writer
- */
- private function writePlotSeriesValuesElement($objWriter, $val = 3, $fillColor = 'FF9900')
- {
- $objWriter->startElement('c:dPt');
- $objWriter->startElement('c:idx');
- $objWriter->writeAttribute('val', $val);
- $objWriter->endElement();
-
- $objWriter->startElement('c:bubble3D');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
-
- $objWriter->startElement('c:spPr');
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', $fillColor);
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- return $objWriter;
- }
-
- /**
- * Write Plot Group (series of related plots).
- *
- * @param DataSeries $plotGroup
- * @param string $groupType Type of plot for dataseries
- * @param XMLWriter $objWriter XML Writer
- * @param bool &$catIsMultiLevelSeries Is category a multi-series category
- * @param bool &$valIsMultiLevelSeries Is value set a multi-series set
- * @param string &$plotGroupingType Type of grouping for multi-series values
- */
- private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
- {
- if ($plotGroup === null) {
- return;
- }
-
- if (($groupType == DataSeries::TYPE_BARCHART) || ($groupType == DataSeries::TYPE_BARCHART_3D)) {
- $objWriter->startElement('c:barDir');
- $objWriter->writeAttribute('val', $plotGroup->getPlotDirection());
- $objWriter->endElement();
- }
-
- if ($plotGroup->getPlotGrouping() !== null) {
- $plotGroupingType = $plotGroup->getPlotGrouping();
- $objWriter->startElement('c:grouping');
- $objWriter->writeAttribute('val', $plotGroupingType);
- $objWriter->endElement();
- }
-
- // Get these details before the loop, because we can use the count to check for varyColors
- $plotSeriesOrder = $plotGroup->getPlotOrder();
- $plotSeriesCount = count($plotSeriesOrder);
-
- if (($groupType !== DataSeries::TYPE_RADARCHART) && ($groupType !== DataSeries::TYPE_STOCKCHART)) {
- if ($groupType !== DataSeries::TYPE_LINECHART) {
- if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) {
- $objWriter->startElement('c:varyColors');
- $objWriter->writeAttribute('val', 1);
- $objWriter->endElement();
- } else {
- $objWriter->startElement('c:varyColors');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- }
- }
- }
-
- foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) {
- $objWriter->startElement('c:ser');
-
- $plotLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx);
- if ($plotLabel) {
- $fillColor = $plotLabel->getFillColor();
- if ($fillColor !== null && !is_array($fillColor)) {
- $objWriter->startElement('c:spPr');
- $objWriter->startElement('a:solidFill');
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', $fillColor);
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- }
- }
-
- $objWriter->startElement('c:idx');
- $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesIdx);
- $objWriter->endElement();
-
- $objWriter->startElement('c:order');
- $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesRef);
- $objWriter->endElement();
-
- // Values
- $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef);
-
- if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) {
- $fillColorValues = $plotSeriesValues->getFillColor();
- if ($fillColorValues !== null && is_array($fillColorValues)) {
- foreach ($plotSeriesValues->getDataValues() as $dataKey => $dataValue) {
- $this->writePlotSeriesValuesElement($objWriter, $dataKey, ($fillColorValues[$dataKey] ?? 'FF9900'));
- }
- } else {
- $this->writePlotSeriesValuesElement($objWriter);
- }
- }
-
- // Labels
- $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef);
- if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) {
- $objWriter->startElement('c:tx');
- $objWriter->startElement('c:strRef');
- $this->writePlotSeriesLabel($plotSeriesLabel, $objWriter);
- $objWriter->endElement();
- $objWriter->endElement();
- }
-
- // Formatting for the points
- if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART)) {
- $plotLineWidth = 12700;
- if ($plotSeriesValues) {
- $plotLineWidth = $plotSeriesValues->getLineWidth();
- }
-
- $objWriter->startElement('c:spPr');
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', $plotLineWidth);
- if ($groupType == DataSeries::TYPE_STOCKCHART) {
- $objWriter->startElement('a:noFill');
- $objWriter->endElement();
- }
- $objWriter->endElement();
- $objWriter->endElement();
- }
-
- if ($plotSeriesValues) {
- $plotSeriesMarker = $plotSeriesValues->getPointMarker();
- if ($plotSeriesMarker) {
- $objWriter->startElement('c:marker');
- $objWriter->startElement('c:symbol');
- $objWriter->writeAttribute('val', $plotSeriesMarker);
- $objWriter->endElement();
-
- if ($plotSeriesMarker !== 'none') {
- $objWriter->startElement('c:size');
- $objWriter->writeAttribute('val', 3);
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- if (($groupType === DataSeries::TYPE_BARCHART) || ($groupType === DataSeries::TYPE_BARCHART_3D) || ($groupType === DataSeries::TYPE_BUBBLECHART)) {
- $objWriter->startElement('c:invertIfNegative');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- }
-
- // Category Labels
- $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef);
- if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) {
- $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries();
-
- if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) {
- if ($plotGroup->getPlotStyle() !== null) {
- $plotStyle = $plotGroup->getPlotStyle();
- if ($plotStyle) {
- $objWriter->startElement('c:explosion');
- $objWriter->writeAttribute('val', 25);
- $objWriter->endElement();
- }
- }
- }
-
- if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) {
- $objWriter->startElement('c:xVal');
- } else {
- $objWriter->startElement('c:cat');
- }
-
- $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str');
- $objWriter->endElement();
- }
-
- // Values
- if ($plotSeriesValues) {
- $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries();
-
- if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) {
- $objWriter->startElement('c:yVal');
- } else {
- $objWriter->startElement('c:val');
- }
-
- $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num');
- $objWriter->endElement();
- }
-
- if ($groupType === DataSeries::TYPE_BUBBLECHART) {
- $this->writeBubbles($plotSeriesValues, $objWriter);
- }
-
- $objWriter->endElement();
- }
-
- $this->seriesIndex += $plotSeriesIdx + 1;
- }
-
- /**
- * Write Plot Series Label.
- *
- * @param DataSeriesValues $plotSeriesLabel
- * @param XMLWriter $objWriter XML Writer
- */
- private function writePlotSeriesLabel($plotSeriesLabel, $objWriter): void
- {
- if ($plotSeriesLabel === null) {
- return;
- }
-
- $objWriter->startElement('c:f');
- $objWriter->writeRawData($plotSeriesLabel->getDataSource());
- $objWriter->endElement();
-
- $objWriter->startElement('c:strCache');
- $objWriter->startElement('c:ptCount');
- $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount());
- $objWriter->endElement();
-
- foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) {
- $objWriter->startElement('c:pt');
- $objWriter->writeAttribute('idx', $plotLabelKey);
-
- $objWriter->startElement('c:v');
- $objWriter->writeRawData($plotLabelValue);
- $objWriter->endElement();
- $objWriter->endElement();
- }
- $objWriter->endElement();
- }
-
- /**
- * Write Plot Series Values.
- *
- * @param DataSeriesValues $plotSeriesValues
- * @param XMLWriter $objWriter XML Writer
- * @param string $groupType Type of plot for dataseries
- * @param string $dataType Datatype of series values
- */
- private function writePlotSeriesValues($plotSeriesValues, XMLWriter $objWriter, $groupType, $dataType = 'str'): void
- {
- if ($plotSeriesValues === null) {
- return;
- }
-
- if ($plotSeriesValues->isMultiLevelSeries()) {
- $levelCount = $plotSeriesValues->multiLevelCount();
-
- $objWriter->startElement('c:multiLvlStrRef');
-
- $objWriter->startElement('c:f');
- $objWriter->writeRawData($plotSeriesValues->getDataSource());
- $objWriter->endElement();
-
- $objWriter->startElement('c:multiLvlStrCache');
-
- $objWriter->startElement('c:ptCount');
- $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
- $objWriter->endElement();
-
- for ($level = 0; $level < $levelCount; ++$level) {
- $objWriter->startElement('c:lvl');
-
- foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) {
- if (isset($plotSeriesValue[$level])) {
- $objWriter->startElement('c:pt');
- $objWriter->writeAttribute('idx', $plotSeriesKey);
-
- $objWriter->startElement('c:v');
- $objWriter->writeRawData($plotSeriesValue[$level]);
- $objWriter->endElement();
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- } else {
- $objWriter->startElement('c:' . $dataType . 'Ref');
-
- $objWriter->startElement('c:f');
- $objWriter->writeRawData($plotSeriesValues->getDataSource());
- $objWriter->endElement();
-
- $objWriter->startElement('c:' . $dataType . 'Cache');
-
- if (($groupType != DataSeries::TYPE_PIECHART) && ($groupType != DataSeries::TYPE_PIECHART_3D) && ($groupType != DataSeries::TYPE_DONUTCHART)) {
- if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) {
- $objWriter->startElement('c:formatCode');
- $objWriter->writeRawData($plotSeriesValues->getFormatCode());
- $objWriter->endElement();
- }
- }
-
- $objWriter->startElement('c:ptCount');
- $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
- $objWriter->endElement();
-
- $dataValues = $plotSeriesValues->getDataValues();
- if (!empty($dataValues)) {
- if (is_array($dataValues)) {
- foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
- $objWriter->startElement('c:pt');
- $objWriter->writeAttribute('idx', $plotSeriesKey);
-
- $objWriter->startElement('c:v');
- $objWriter->writeRawData($plotSeriesValue);
- $objWriter->endElement();
- $objWriter->endElement();
- }
- }
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write Bubble Chart Details.
- *
- * @param DataSeriesValues $plotSeriesValues
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeBubbles($plotSeriesValues, $objWriter): void
- {
- if ($plotSeriesValues === null) {
- return;
- }
-
- $objWriter->startElement('c:bubbleSize');
- $objWriter->startElement('c:numLit');
-
- $objWriter->startElement('c:formatCode');
- $objWriter->writeRawData('General');
- $objWriter->endElement();
-
- $objWriter->startElement('c:ptCount');
- $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
- $objWriter->endElement();
-
- $dataValues = $plotSeriesValues->getDataValues();
- if (!empty($dataValues)) {
- if (is_array($dataValues)) {
- foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
- $objWriter->startElement('c:pt');
- $objWriter->writeAttribute('idx', $plotSeriesKey);
- $objWriter->startElement('c:v');
- $objWriter->writeRawData(1);
- $objWriter->endElement();
- $objWriter->endElement();
- }
- }
- }
-
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('c:bubble3D');
- $objWriter->writeAttribute('val', 0);
- $objWriter->endElement();
- }
-
- /**
- * Write Layout.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Layout $layout
- */
- private function writeLayout(XMLWriter $objWriter, ?Layout $layout = null): void
- {
- $objWriter->startElement('c:layout');
-
- if ($layout !== null) {
- $objWriter->startElement('c:manualLayout');
-
- $layoutTarget = $layout->getLayoutTarget();
- if ($layoutTarget !== null) {
- $objWriter->startElement('c:layoutTarget');
- $objWriter->writeAttribute('val', $layoutTarget);
- $objWriter->endElement();
- }
-
- $xMode = $layout->getXMode();
- if ($xMode !== null) {
- $objWriter->startElement('c:xMode');
- $objWriter->writeAttribute('val', $xMode);
- $objWriter->endElement();
- }
-
- $yMode = $layout->getYMode();
- if ($yMode !== null) {
- $objWriter->startElement('c:yMode');
- $objWriter->writeAttribute('val', $yMode);
- $objWriter->endElement();
- }
-
- $x = $layout->getXPosition();
- if ($x !== null) {
- $objWriter->startElement('c:x');
- $objWriter->writeAttribute('val', $x);
- $objWriter->endElement();
- }
-
- $y = $layout->getYPosition();
- if ($y !== null) {
- $objWriter->startElement('c:y');
- $objWriter->writeAttribute('val', $y);
- $objWriter->endElement();
- }
-
- $w = $layout->getWidth();
- if ($w !== null) {
- $objWriter->startElement('c:w');
- $objWriter->writeAttribute('val', $w);
- $objWriter->endElement();
- }
-
- $h = $layout->getHeight();
- if ($h !== null) {
- $objWriter->startElement('c:h');
- $objWriter->writeAttribute('val', $h);
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Alternate Content block.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeAlternateContent($objWriter): void
- {
- $objWriter->startElement('mc:AlternateContent');
- $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
-
- $objWriter->startElement('mc:Choice');
- $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart');
- $objWriter->writeAttribute('Requires', 'c14');
-
- $objWriter->startElement('c14:style');
- $objWriter->writeAttribute('val', '102');
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('mc:Fallback');
- $objWriter->startElement('c:style');
- $objWriter->writeAttribute('val', '2');
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Printer Settings.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writePrintSettings($objWriter): void
- {
- $objWriter->startElement('c:printSettings');
-
- $objWriter->startElement('c:headerFooter');
- $objWriter->endElement();
-
- $objWriter->startElement('c:pageMargins');
- $objWriter->writeAttribute('footer', 0.3);
- $objWriter->writeAttribute('header', 0.3);
- $objWriter->writeAttribute('r', 0.7);
- $objWriter->writeAttribute('l', 0.7);
- $objWriter->writeAttribute('t', 0.75);
- $objWriter->writeAttribute('b', 0.75);
- $objWriter->endElement();
-
- $objWriter->startElement('c:pageSetup');
- $objWriter->writeAttribute('orientation', 'portrait');
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Comments.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Comments.php
deleted file mode 100644
index 73c4308..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Comments.php
+++ /dev/null
@@ -1,232 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Comments cache
- $comments = $pWorksheet->getComments();
-
- // Authors cache
- $authors = [];
- $authorId = 0;
- foreach ($comments as $comment) {
- if (!isset($authors[$comment->getAuthor()])) {
- $authors[$comment->getAuthor()] = $authorId++;
- }
- }
-
- // comments
- $objWriter->startElement('comments');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
-
- // Loop through authors
- $objWriter->startElement('authors');
- foreach ($authors as $author => $index) {
- $objWriter->writeElement('author', $author);
- }
- $objWriter->endElement();
-
- // Loop through comments
- $objWriter->startElement('commentList');
- foreach ($comments as $key => $value) {
- $this->writeComment($objWriter, $key, $value, $authors);
- }
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write comment to XML format.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pCellReference Cell reference
- * @param Comment $pComment Comment
- * @param array $pAuthors Array of authors
- */
- private function writeComment(XMLWriter $objWriter, $pCellReference, Comment $pComment, array $pAuthors): void
- {
- // comment
- $objWriter->startElement('comment');
- $objWriter->writeAttribute('ref', $pCellReference);
- $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]);
-
- // text
- $objWriter->startElement('text');
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText());
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write VML comments to XML format.
- *
- * @return string XML Output
- */
- public function writeVMLComments(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Comments cache
- $comments = $pWorksheet->getComments();
-
- // xml
- $objWriter->startElement('xml');
- $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
- $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
- $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
-
- // o:shapelayout
- $objWriter->startElement('o:shapelayout');
- $objWriter->writeAttribute('v:ext', 'edit');
-
- // o:idmap
- $objWriter->startElement('o:idmap');
- $objWriter->writeAttribute('v:ext', 'edit');
- $objWriter->writeAttribute('data', '1');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // v:shapetype
- $objWriter->startElement('v:shapetype');
- $objWriter->writeAttribute('id', '_x0000_t202');
- $objWriter->writeAttribute('coordsize', '21600,21600');
- $objWriter->writeAttribute('o:spt', '202');
- $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe');
-
- // v:stroke
- $objWriter->startElement('v:stroke');
- $objWriter->writeAttribute('joinstyle', 'miter');
- $objWriter->endElement();
-
- // v:path
- $objWriter->startElement('v:path');
- $objWriter->writeAttribute('gradientshapeok', 't');
- $objWriter->writeAttribute('o:connecttype', 'rect');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // Loop through comments
- foreach ($comments as $key => $value) {
- $this->writeVMLComment($objWriter, $key, $value);
- }
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write VML comment to XML format.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pCellReference Cell reference, eg: 'A1'
- * @param Comment $pComment Comment
- */
- private function writeVMLComment(XMLWriter $objWriter, $pCellReference, Comment $pComment): void
- {
- // Metadata
- [$column, $row] = Coordinate::coordinateFromString($pCellReference);
- $column = Coordinate::columnIndexFromString($column);
- $id = 1024 + $column + $row;
- $id = substr($id, 0, 4);
-
- // v:shape
- $objWriter->startElement('v:shape');
- $objWriter->writeAttribute('id', '_x0000_s' . $id);
- $objWriter->writeAttribute('type', '#_x0000_t202');
- $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden'));
- $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB());
- $objWriter->writeAttribute('o:insetmode', 'auto');
-
- // v:fill
- $objWriter->startElement('v:fill');
- $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB());
- $objWriter->endElement();
-
- // v:shadow
- $objWriter->startElement('v:shadow');
- $objWriter->writeAttribute('on', 't');
- $objWriter->writeAttribute('color', 'black');
- $objWriter->writeAttribute('obscured', 't');
- $objWriter->endElement();
-
- // v:path
- $objWriter->startElement('v:path');
- $objWriter->writeAttribute('o:connecttype', 'none');
- $objWriter->endElement();
-
- // v:textbox
- $objWriter->startElement('v:textbox');
- $objWriter->writeAttribute('style', 'mso-direction-alt:auto');
-
- // div
- $objWriter->startElement('div');
- $objWriter->writeAttribute('style', 'text-align:left');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // x:ClientData
- $objWriter->startElement('x:ClientData');
- $objWriter->writeAttribute('ObjectType', 'Note');
-
- // x:MoveWithCells
- $objWriter->writeElement('x:MoveWithCells', '');
-
- // x:SizeWithCells
- $objWriter->writeElement('x:SizeWithCells', '');
-
- // x:AutoFill
- $objWriter->writeElement('x:AutoFill', 'False');
-
- // x:Row
- $objWriter->writeElement('x:Row', ($row - 1));
-
- // x:Column
- $objWriter->writeElement('x:Column', ($column - 1));
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/vendor/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php
deleted file mode 100644
index 2cff1a8..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php
+++ /dev/null
@@ -1,240 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Types
- $objWriter->startElement('Types');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');
-
- // Theme
- $this->writeOverrideContentType($objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml');
-
- // Styles
- $this->writeOverrideContentType($objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml');
-
- // Rels
- $this->writeDefaultContentType($objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml');
-
- // XML
- $this->writeDefaultContentType($objWriter, 'xml', 'application/xml');
-
- // VML
- $this->writeDefaultContentType($objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
-
- // Workbook
- if ($spreadsheet->hasMacros()) { //Macros in workbook ?
- // Yes : not standard content but "macroEnabled"
- $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml');
- //... and define a new type for the VBA project
- // Better use Override, because we can use 'bin' also for xl\printerSettings\printerSettings1.bin
- $this->writeOverrideContentType($objWriter, '/xl/vbaProject.bin', 'application/vnd.ms-office.vbaProject');
- if ($spreadsheet->hasMacrosCertificate()) {
- // signed macros ?
- // Yes : add needed information
- $this->writeOverrideContentType($objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature');
- }
- } else {
- // no macros in workbook, so standard type
- $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml');
- }
-
- // DocProps
- $this->writeOverrideContentType($objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml');
-
- $this->writeOverrideContentType($objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml');
-
- $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
- if (!empty($customPropertyList)) {
- $this->writeOverrideContentType($objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml');
- }
-
- // Worksheets
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml');
- }
-
- // Shared strings
- $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml');
-
- // Add worksheet relationship content types
- $unparsedLoadedData = $spreadsheet->getUnparsedLoadedData();
- $chart = 1;
- for ($i = 0; $i < $sheetCount; ++$i) {
- $drawings = $spreadsheet->getSheet($i)->getDrawingCollection();
- $drawingCount = count($drawings);
- $chartCount = ($includeCharts) ? $spreadsheet->getSheet($i)->getChartCount() : 0;
- $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$spreadsheet->getSheet($i)->getCodeName()]['drawingOriginalIds']);
-
- // We need a drawing relationship for the worksheet if we have either drawings or charts
- if (($drawingCount > 0) || ($chartCount > 0) || $hasUnparsedDrawing) {
- $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml');
- }
-
- // If we have charts, then we need a chart relationship for every individual chart
- if ($chartCount > 0) {
- for ($c = 0; $c < $chartCount; ++$c) {
- $this->writeOverrideContentType($objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
- }
- }
- }
-
- // Comments
- for ($i = 0; $i < $sheetCount; ++$i) {
- if (count($spreadsheet->getSheet($i)->getComments()) > 0) {
- $this->writeOverrideContentType($objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
- }
- }
-
- // Add media content-types
- $aMediaContentTypes = [];
- $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count();
- for ($i = 0; $i < $mediaCount; ++$i) {
- $extension = '';
- $mimeType = '';
-
- if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing) {
- $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension());
- $mimeType = $this->getImageMimeType($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath());
- } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
- $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType());
- $extension = explode('/', $extension);
- $extension = $extension[1];
-
- $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType();
- }
-
- if (!isset($aMediaContentTypes[$extension])) {
- $aMediaContentTypes[$extension] = $mimeType;
-
- $this->writeDefaultContentType($objWriter, $extension, $mimeType);
- }
- }
- if ($spreadsheet->hasRibbonBinObjects()) {
- // Some additional objects in the ribbon ?
- // we need to write "Extension" but not already write for media content
- $tabRibbonTypes = array_diff($spreadsheet->getRibbonBinObjects('types'), array_keys($aMediaContentTypes));
- foreach ($tabRibbonTypes as $aRibbonType) {
- $mimeType = 'image/.' . $aRibbonType; //we wrote $mimeType like customUI Editor
- $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType);
- }
- }
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- if (count($spreadsheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
- foreach ($spreadsheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
- if (!isset($aMediaContentTypes[strtolower($image->getExtension())])) {
- $aMediaContentTypes[strtolower($image->getExtension())] = $this->getImageMimeType($image->getPath());
-
- $this->writeDefaultContentType($objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]);
- }
- }
- }
- }
-
- // unparsed defaults
- if (isset($unparsedLoadedData['default_content_types'])) {
- foreach ($unparsedLoadedData['default_content_types'] as $extName => $contentType) {
- $this->writeDefaultContentType($objWriter, $extName, $contentType);
- }
- }
-
- // unparsed overrides
- if (isset($unparsedLoadedData['override_content_types'])) {
- foreach ($unparsedLoadedData['override_content_types'] as $partName => $overrideType) {
- $this->writeOverrideContentType($objWriter, $partName, $overrideType);
- }
- }
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Get image mime type.
- *
- * @param string $pFile Filename
- *
- * @return string Mime Type
- */
- private function getImageMimeType($pFile)
- {
- if (File::fileExists($pFile)) {
- $image = getimagesize($pFile);
-
- return image_type_to_mime_type($image[2]);
- }
-
- throw new WriterException("File $pFile does not exist");
- }
-
- /**
- * Write Default content type.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pPartname Part name
- * @param string $pContentType Content type
- */
- private function writeDefaultContentType(XMLWriter $objWriter, $pPartname, $pContentType): void
- {
- if ($pPartname != '' && $pContentType != '') {
- // Write content type
- $objWriter->startElement('Default');
- $objWriter->writeAttribute('Extension', $pPartname);
- $objWriter->writeAttribute('ContentType', $pContentType);
- $objWriter->endElement();
- } else {
- throw new WriterException('Invalid parameters passed.');
- }
- }
-
- /**
- * Write Override content type.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pPartname Part name
- * @param string $pContentType Content type
- */
- private function writeOverrideContentType(XMLWriter $objWriter, $pPartname, $pContentType): void
- {
- if ($pPartname != '' && $pContentType != '') {
- // Write content type
- $objWriter->startElement('Override');
- $objWriter->writeAttribute('PartName', $pPartname);
- $objWriter->writeAttribute('ContentType', $pContentType);
- $objWriter->endElement();
- } else {
- throw new WriterException('Invalid parameters passed.');
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php b/vendor/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
deleted file mode 100644
index 8c3da82..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
+++ /dev/null
@@ -1,223 +0,0 @@
-objWriter = $objWriter;
- $this->spreadsheet = $spreadsheet;
- }
-
- public function write(): void
- {
- // Write defined names
- $this->objWriter->startElement('definedNames');
-
- // Named ranges
- if (count($this->spreadsheet->getDefinedNames()) > 0) {
- // Named ranges
- $this->writeNamedRangesAndFormulae();
- }
-
- // Other defined names
- $sheetCount = $this->spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- // NamedRange for autoFilter
- $this->writeNamedRangeForAutofilter($this->spreadsheet->getSheet($i), $i);
-
- // NamedRange for Print_Titles
- $this->writeNamedRangeForPrintTitles($this->spreadsheet->getSheet($i), $i);
-
- // NamedRange for Print_Area
- $this->writeNamedRangeForPrintArea($this->spreadsheet->getSheet($i), $i);
- }
-
- $this->objWriter->endElement();
- }
-
- /**
- * Write defined names.
- */
- private function writeNamedRangesAndFormulae(): void
- {
- // Loop named ranges
- $definedNames = $this->spreadsheet->getDefinedNames();
- foreach ($definedNames as $definedName) {
- $this->writeDefinedName($definedName);
- }
- }
-
- /**
- * Write Defined Name for named range.
- */
- private function writeDefinedName(DefinedName $pDefinedName): void
- {
- // definedName for named range
- $this->objWriter->startElement('definedName');
- $this->objWriter->writeAttribute('name', $pDefinedName->getName());
- if ($pDefinedName->getLocalOnly() && $pDefinedName->getScope() !== null) {
- $this->objWriter->writeAttribute('localSheetId', $pDefinedName->getScope()->getParent()->getIndex($pDefinedName->getScope()));
- }
-
- $definedRange = $pDefinedName->getValue();
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
- $definedRange,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
-
- $worksheets = $splitRanges[2];
- $columns = $splitRanges[6];
- $rows = $splitRanges[7];
-
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $worksheet = $worksheets[$splitCount][0];
- $column = $columns[$splitCount][0];
- $row = $rows[$splitCount][0];
-
- $newRange = '';
- if (empty($worksheet)) {
- if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
- // We should have a worksheet
- $worksheet = $pDefinedName->getWorksheet()->getTitle();
- }
- } else {
- $worksheet = str_replace("''", "'", trim($worksheet, "'"));
- }
- if (!empty($worksheet)) {
- $newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
- }
-
- if (!empty($column)) {
- $newRange .= $column;
- }
- if (!empty($row)) {
- $newRange .= $row;
- }
-
- $definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
- }
-
- if (substr($definedRange, 0, 1) === '=') {
- $definedRange = substr($definedRange, 1);
- }
-
- $this->objWriter->writeRawData($definedRange);
-
- $this->objWriter->endElement();
- }
-
- /**
- * Write Defined Name for autoFilter.
- */
- private function writeNamedRangeForAutofilter(Worksheet $pSheet, int $pSheetId = 0): void
- {
- // NamedRange for autoFilter
- $autoFilterRange = $pSheet->getAutoFilter()->getRange();
- if (!empty($autoFilterRange)) {
- $this->objWriter->startElement('definedName');
- $this->objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
- $this->objWriter->writeAttribute('localSheetId', $pSheetId);
- $this->objWriter->writeAttribute('hidden', '1');
-
- // Create absolute coordinate and write as raw text
- $range = Coordinate::splitRange($autoFilterRange);
- $range = $range[0];
- // Strip any worksheet ref so we can make the cell ref absolute
- [$ws, $range[0]] = Worksheet::extractSheetTitle($range[0], true);
-
- $range[0] = Coordinate::absoluteCoordinate($range[0]);
- $range[1] = Coordinate::absoluteCoordinate($range[1]);
- $range = implode(':', $range);
-
- $this->objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range);
-
- $this->objWriter->endElement();
- }
- }
-
- /**
- * Write Defined Name for PrintTitles.
- */
- private function writeNamedRangeForPrintTitles(Worksheet $pSheet, int $pSheetId = 0): void
- {
- // NamedRange for PrintTitles
- if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
- $this->objWriter->startElement('definedName');
- $this->objWriter->writeAttribute('name', '_xlnm.Print_Titles');
- $this->objWriter->writeAttribute('localSheetId', $pSheetId);
-
- // Setting string
- $settingString = '';
-
- // Columns to repeat
- if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
- $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft();
-
- $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
- }
-
- // Rows to repeat
- if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
- if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
- $settingString .= ',';
- }
-
- $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop();
-
- $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
- }
-
- $this->objWriter->writeRawData($settingString);
-
- $this->objWriter->endElement();
- }
- }
-
- /**
- * Write Defined Name for PrintTitles.
- */
- private function writeNamedRangeForPrintArea(Worksheet $pSheet, int $pSheetId = 0): void
- {
- // NamedRange for PrintArea
- if ($pSheet->getPageSetup()->isPrintAreaSet()) {
- $this->objWriter->startElement('definedName');
- $this->objWriter->writeAttribute('name', '_xlnm.Print_Area');
- $this->objWriter->writeAttribute('localSheetId', $pSheetId);
-
- // Print area
- $printArea = Coordinate::splitRange($pSheet->getPageSetup()->getPrintArea());
-
- $chunks = [];
- foreach ($printArea as $printAreaRect) {
- $printAreaRect[0] = Coordinate::absoluteReference($printAreaRect[0]);
- $printAreaRect[1] = Coordinate::absoluteReference($printAreaRect[1]);
- $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect);
- }
-
- $this->objWriter->writeRawData(implode(',', $chunks));
-
- $this->objWriter->endElement();
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/DocProps.php b/vendor/PhpSpreadsheet/Writer/Xlsx/DocProps.php
deleted file mode 100644
index bcbc237..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/DocProps.php
+++ /dev/null
@@ -1,239 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Properties
- $objWriter->startElement('Properties');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties');
- $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
-
- // Application
- $objWriter->writeElement('Application', 'Microsoft Excel');
-
- // DocSecurity
- $objWriter->writeElement('DocSecurity', '0');
-
- // ScaleCrop
- $objWriter->writeElement('ScaleCrop', 'false');
-
- // HeadingPairs
- $objWriter->startElement('HeadingPairs');
-
- // Vector
- $objWriter->startElement('vt:vector');
- $objWriter->writeAttribute('size', '2');
- $objWriter->writeAttribute('baseType', 'variant');
-
- // Variant
- $objWriter->startElement('vt:variant');
- $objWriter->writeElement('vt:lpstr', 'Worksheets');
- $objWriter->endElement();
-
- // Variant
- $objWriter->startElement('vt:variant');
- $objWriter->writeElement('vt:i4', $spreadsheet->getSheetCount());
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // TitlesOfParts
- $objWriter->startElement('TitlesOfParts');
-
- // Vector
- $objWriter->startElement('vt:vector');
- $objWriter->writeAttribute('size', $spreadsheet->getSheetCount());
- $objWriter->writeAttribute('baseType', 'lpstr');
-
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- $objWriter->writeElement('vt:lpstr', $spreadsheet->getSheet($i)->getTitle());
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // Company
- $objWriter->writeElement('Company', $spreadsheet->getProperties()->getCompany());
-
- // Company
- $objWriter->writeElement('Manager', $spreadsheet->getProperties()->getManager());
-
- // LinksUpToDate
- $objWriter->writeElement('LinksUpToDate', 'false');
-
- // SharedDoc
- $objWriter->writeElement('SharedDoc', 'false');
-
- // HyperlinksChanged
- $objWriter->writeElement('HyperlinksChanged', 'false');
-
- // AppVersion
- $objWriter->writeElement('AppVersion', '12.0000');
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write docProps/core.xml to XML format.
- *
- * @return string XML Output
- */
- public function writeDocPropsCore(Spreadsheet $spreadsheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // cp:coreProperties
- $objWriter->startElement('cp:coreProperties');
- $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties');
- $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
- $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/');
- $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/');
- $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
-
- // dc:creator
- $objWriter->writeElement('dc:creator', $spreadsheet->getProperties()->getCreator());
-
- // cp:lastModifiedBy
- $objWriter->writeElement('cp:lastModifiedBy', $spreadsheet->getProperties()->getLastModifiedBy());
-
- // dcterms:created
- $objWriter->startElement('dcterms:created');
- $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');
- $objWriter->writeRawData(date(DATE_W3C, $spreadsheet->getProperties()->getCreated()));
- $objWriter->endElement();
-
- // dcterms:modified
- $objWriter->startElement('dcterms:modified');
- $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');
- $objWriter->writeRawData(date(DATE_W3C, $spreadsheet->getProperties()->getModified()));
- $objWriter->endElement();
-
- // dc:title
- $objWriter->writeElement('dc:title', $spreadsheet->getProperties()->getTitle());
-
- // dc:description
- $objWriter->writeElement('dc:description', $spreadsheet->getProperties()->getDescription());
-
- // dc:subject
- $objWriter->writeElement('dc:subject', $spreadsheet->getProperties()->getSubject());
-
- // cp:keywords
- $objWriter->writeElement('cp:keywords', $spreadsheet->getProperties()->getKeywords());
-
- // cp:category
- $objWriter->writeElement('cp:category', $spreadsheet->getProperties()->getCategory());
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write docProps/custom.xml to XML format.
- *
- * @return string XML Output
- */
- public function writeDocPropsCustom(Spreadsheet $spreadsheet)
- {
- $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
- if (empty($customPropertyList)) {
- return;
- }
-
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // cp:coreProperties
- $objWriter->startElement('Properties');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties');
- $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
-
- foreach ($customPropertyList as $key => $customProperty) {
- $propertyValue = $spreadsheet->getProperties()->getCustomPropertyValue($customProperty);
- $propertyType = $spreadsheet->getProperties()->getCustomPropertyType($customProperty);
-
- $objWriter->startElement('property');
- $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}');
- $objWriter->writeAttribute('pid', $key + 2);
- $objWriter->writeAttribute('name', $customProperty);
-
- switch ($propertyType) {
- case 'i':
- $objWriter->writeElement('vt:i4', $propertyValue);
-
- break;
- case 'f':
- $objWriter->writeElement('vt:r8', $propertyValue);
-
- break;
- case 'b':
- $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false');
-
- break;
- case 'd':
- $objWriter->startElement('vt:filetime');
- $objWriter->writeRawData(date(DATE_W3C, $propertyValue));
- $objWriter->endElement();
-
- break;
- default:
- $objWriter->writeElement('vt:lpwstr', $propertyValue);
-
- break;
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Drawing.php
deleted file mode 100644
index 1713b98..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+++ /dev/null
@@ -1,505 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // xdr:wsDr
- $objWriter->startElement('xdr:wsDr');
- $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
- $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
-
- // Loop through images and write drawings
- $i = 1;
- $iterator = $pWorksheet->getDrawingCollection()->getIterator();
- while ($iterator->valid()) {
- /** @var BaseDrawing $pDrawing */
- $pDrawing = $iterator->current();
- $pRelationId = $i;
- $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i;
-
- $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId);
-
- $iterator->next();
- ++$i;
- }
-
- if ($includeCharts) {
- $chartCount = $pWorksheet->getChartCount();
- // Loop through charts and write the chart position
- if ($chartCount > 0) {
- for ($c = 0; $c < $chartCount; ++$c) {
- $this->writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c + $i);
- }
- }
- }
-
- // unparsed AlternateContent
- $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
- if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'])) {
- foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) {
- $objWriter->writeRaw($drawingAlternateContent);
- }
- }
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write drawings to XML format.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param int $pRelationId
- */
- public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1): void
- {
- $tl = $pChart->getTopLeftPosition();
- $tl['colRow'] = Coordinate::coordinateFromString($tl['cell']);
- $br = $pChart->getBottomRightPosition();
- $br['colRow'] = Coordinate::coordinateFromString($br['cell']);
-
- $objWriter->startElement('xdr:twoCellAnchor');
-
- $objWriter->startElement('xdr:from');
- $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($tl['colRow'][0]) - 1);
- $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset']));
- $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);
- $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset']));
- $objWriter->endElement();
- $objWriter->startElement('xdr:to');
- $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($br['colRow'][0]) - 1);
- $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset']));
- $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);
- $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset']));
- $objWriter->endElement();
-
- $objWriter->startElement('xdr:graphicFrame');
- $objWriter->writeAttribute('macro', '');
- $objWriter->startElement('xdr:nvGraphicFramePr');
- $objWriter->startElement('xdr:cNvPr');
- $objWriter->writeAttribute('name', 'Chart ' . $pRelationId);
- $objWriter->writeAttribute('id', 1025 * $pRelationId);
- $objWriter->endElement();
- $objWriter->startElement('xdr:cNvGraphicFramePr');
- $objWriter->startElement('a:graphicFrameLocks');
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('xdr:xfrm');
- $objWriter->startElement('a:off');
- $objWriter->writeAttribute('x', '0');
- $objWriter->writeAttribute('y', '0');
- $objWriter->endElement();
- $objWriter->startElement('a:ext');
- $objWriter->writeAttribute('cx', '0');
- $objWriter->writeAttribute('cy', '0');
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('a:graphic');
- $objWriter->startElement('a:graphicData');
- $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
- $objWriter->startElement('c:chart');
- $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
- $objWriter->writeAttribute('r:id', 'rId' . $pRelationId);
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
-
- $objWriter->startElement('xdr:clientData');
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write drawings to XML format.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param int $pRelationId
- * @param null|int $hlinkClickId
- */
- public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1, $hlinkClickId = null): void
- {
- if ($pRelationId >= 0) {
- // xdr:oneCellAnchor
- $objWriter->startElement('xdr:oneCellAnchor');
- // Image location
- $aCoordinates = Coordinate::coordinateFromString($pDrawing->getCoordinates());
- $aCoordinates[0] = Coordinate::columnIndexFromString($aCoordinates[0]);
-
- // xdr:from
- $objWriter->startElement('xdr:from');
- $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);
- $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetX()));
- $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);
- $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getOffsetY()));
- $objWriter->endElement();
-
- // xdr:ext
- $objWriter->startElement('xdr:ext');
- $objWriter->writeAttribute('cx', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getWidth()));
- $objWriter->writeAttribute('cy', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getHeight()));
- $objWriter->endElement();
-
- // xdr:pic
- $objWriter->startElement('xdr:pic');
-
- // xdr:nvPicPr
- $objWriter->startElement('xdr:nvPicPr');
-
- // xdr:cNvPr
- $objWriter->startElement('xdr:cNvPr');
- $objWriter->writeAttribute('id', $pRelationId);
- $objWriter->writeAttribute('name', $pDrawing->getName());
- $objWriter->writeAttribute('descr', $pDrawing->getDescription());
-
- //a:hlinkClick
- $this->writeHyperLinkDrawing($objWriter, $hlinkClickId);
-
- $objWriter->endElement();
-
- // xdr:cNvPicPr
- $objWriter->startElement('xdr:cNvPicPr');
-
- // a:picLocks
- $objWriter->startElement('a:picLocks');
- $objWriter->writeAttribute('noChangeAspect', '1');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // xdr:blipFill
- $objWriter->startElement('xdr:blipFill');
-
- // a:blip
- $objWriter->startElement('a:blip');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
- $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);
- $objWriter->endElement();
-
- // a:stretch
- $objWriter->startElement('a:stretch');
- $objWriter->writeElement('a:fillRect', null);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // xdr:spPr
- $objWriter->startElement('xdr:spPr');
-
- // a:xfrm
- $objWriter->startElement('a:xfrm');
- $objWriter->writeAttribute('rot', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getRotation()));
- $objWriter->endElement();
-
- // a:prstGeom
- $objWriter->startElement('a:prstGeom');
- $objWriter->writeAttribute('prst', 'rect');
-
- // a:avLst
- $objWriter->writeElement('a:avLst', null);
-
- $objWriter->endElement();
-
- if ($pDrawing->getShadow()->getVisible()) {
- // a:effectLst
- $objWriter->startElement('a:effectLst');
-
- // a:outerShdw
- $objWriter->startElement('a:outerShdw');
- $objWriter->writeAttribute('blurRad', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));
- $objWriter->writeAttribute('dist', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));
- $objWriter->writeAttribute('dir', \PhpOffice\PhpSpreadsheet\Shared\Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));
- $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment());
- $objWriter->writeAttribute('rotWithShape', '0');
-
- // a:srgbClr
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB());
-
- // a:alpha
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // xdr:clientData
- $objWriter->writeElement('xdr:clientData', null);
-
- $objWriter->endElement();
- } else {
- throw new WriterException('Invalid parameters passed.');
- }
- }
-
- /**
- * Write VML header/footer images to XML format.
- *
- * @return string XML Output
- */
- public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Header/footer images
- $images = $pWorksheet->getHeaderFooter()->getImages();
-
- // xml
- $objWriter->startElement('xml');
- $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');
- $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');
- $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');
-
- // o:shapelayout
- $objWriter->startElement('o:shapelayout');
- $objWriter->writeAttribute('v:ext', 'edit');
-
- // o:idmap
- $objWriter->startElement('o:idmap');
- $objWriter->writeAttribute('v:ext', 'edit');
- $objWriter->writeAttribute('data', '1');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // v:shapetype
- $objWriter->startElement('v:shapetype');
- $objWriter->writeAttribute('id', '_x0000_t75');
- $objWriter->writeAttribute('coordsize', '21600,21600');
- $objWriter->writeAttribute('o:spt', '75');
- $objWriter->writeAttribute('o:preferrelative', 't');
- $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe');
- $objWriter->writeAttribute('filled', 'f');
- $objWriter->writeAttribute('stroked', 'f');
-
- // v:stroke
- $objWriter->startElement('v:stroke');
- $objWriter->writeAttribute('joinstyle', 'miter');
- $objWriter->endElement();
-
- // v:formulas
- $objWriter->startElement('v:formulas');
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'sum @0 1 0');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'sum 0 0 @1');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @2 1 2');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'sum @0 0 1');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @6 1 2');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'sum @8 21600 0');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight');
- $objWriter->endElement();
-
- // v:f
- $objWriter->startElement('v:f');
- $objWriter->writeAttribute('eqn', 'sum @10 21600 0');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // v:path
- $objWriter->startElement('v:path');
- $objWriter->writeAttribute('o:extrusionok', 'f');
- $objWriter->writeAttribute('gradientshapeok', 't');
- $objWriter->writeAttribute('o:connecttype', 'rect');
- $objWriter->endElement();
-
- // o:lock
- $objWriter->startElement('o:lock');
- $objWriter->writeAttribute('v:ext', 'edit');
- $objWriter->writeAttribute('aspectratio', 't');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // Loop through images
- foreach ($images as $key => $value) {
- $this->writeVMLHeaderFooterImage($objWriter, $key, $value);
- }
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write VML comment to XML format.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pReference Reference
- * @param HeaderFooterDrawing $pImage Image
- */
- private function writeVMLHeaderFooterImage(XMLWriter $objWriter, $pReference, HeaderFooterDrawing $pImage): void
- {
- // Calculate object id
- preg_match('{(\d+)}', md5($pReference), $m);
- $id = 1500 + (substr($m[1], 0, 2) * 1);
-
- // Calculate offset
- $width = $pImage->getWidth();
- $height = $pImage->getHeight();
- $marginLeft = $pImage->getOffsetX();
- $marginTop = $pImage->getOffsetY();
-
- // v:shape
- $objWriter->startElement('v:shape');
- $objWriter->writeAttribute('id', $pReference);
- $objWriter->writeAttribute('o:spid', '_x0000_s' . $id);
- $objWriter->writeAttribute('type', '#_x0000_t75');
- $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1");
-
- // v:imagedata
- $objWriter->startElement('v:imagedata');
- $objWriter->writeAttribute('o:relid', 'rId' . $pReference);
- $objWriter->writeAttribute('o:title', $pImage->getName());
- $objWriter->endElement();
-
- // o:lock
- $objWriter->startElement('o:lock');
- $objWriter->writeAttribute('v:ext', 'edit');
- $objWriter->writeAttribute('textRotation', 't');
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Get an array of all drawings.
- *
- * @return \PhpOffice\PhpSpreadsheet\Worksheet\Drawing[] All drawings in PhpSpreadsheet
- */
- public function allDrawings(Spreadsheet $spreadsheet)
- {
- // Get an array of all drawings
- $aDrawings = [];
-
- // Loop through PhpSpreadsheet
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- // Loop through images and add to array
- $iterator = $spreadsheet->getSheet($i)->getDrawingCollection()->getIterator();
- while ($iterator->valid()) {
- $aDrawings[] = $iterator->current();
-
- $iterator->next();
- }
- }
-
- return $aDrawings;
- }
-
- /**
- * @param null|int $hlinkClickId
- */
- private function writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId): void
- {
- if ($hlinkClickId === null) {
- return;
- }
-
- $objWriter->startElement('a:hlinkClick');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
- $objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId);
- $objWriter->endElement();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Rels.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Rels.php
deleted file mode 100644
index 7984140..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Rels.php
+++ /dev/null
@@ -1,451 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
-
- $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
- if (!empty($customPropertyList)) {
- // Relationship docProps/app.xml
- $this->writeRelationship(
- $objWriter,
- 4,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
- 'docProps/custom.xml'
- );
- }
-
- // Relationship docProps/app.xml
- $this->writeRelationship(
- $objWriter,
- 3,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
- 'docProps/app.xml'
- );
-
- // Relationship docProps/core.xml
- $this->writeRelationship(
- $objWriter,
- 2,
- 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
- 'docProps/core.xml'
- );
-
- // Relationship xl/workbook.xml
- $this->writeRelationship(
- $objWriter,
- 1,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
- 'xl/workbook.xml'
- );
- // a custom UI in workbook ?
- if ($spreadsheet->hasRibbon()) {
- $this->writeRelationShip(
- $objWriter,
- 5,
- 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
- $spreadsheet->getRibbonXMLData('target')
- );
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write workbook relationships to XML format.
- *
- * @return string XML Output
- */
- public function writeWorkbookRelationships(Spreadsheet $spreadsheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
-
- // Relationship styles.xml
- $this->writeRelationship(
- $objWriter,
- 1,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
- 'styles.xml'
- );
-
- // Relationship theme/theme1.xml
- $this->writeRelationship(
- $objWriter,
- 2,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
- 'theme/theme1.xml'
- );
-
- // Relationship sharedStrings.xml
- $this->writeRelationship(
- $objWriter,
- 3,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
- 'sharedStrings.xml'
- );
-
- // Relationships with sheets
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- $this->writeRelationship(
- $objWriter,
- ($i + 1 + 3),
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
- 'worksheets/sheet' . ($i + 1) . '.xml'
- );
- }
- // Relationships for vbaProject if needed
- // id : just after the last sheet
- if ($spreadsheet->hasMacros()) {
- $this->writeRelationShip(
- $objWriter,
- ($i + 1 + 3),
- 'http://schemas.microsoft.com/office/2006/relationships/vbaProject',
- 'vbaProject.bin'
- );
- ++$i; //increment i if needed for an another relation
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write worksheet relationships to XML format.
- *
- * Numbering is as follows:
- * rId1 - Drawings
- * rId_hyperlink_x - Hyperlinks
- *
- * @param int $pWorksheetId
- * @param bool $includeCharts Flag indicating if we should write charts
- *
- * @return string XML Output
- */
- public function writeWorksheetRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, $pWorksheetId = 1, $includeCharts = false)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
-
- // Write drawing relationships?
- $drawingOriginalIds = [];
- $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
- if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) {
- $drawingOriginalIds = $unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'];
- }
-
- if ($includeCharts) {
- $charts = $pWorksheet->getChartCollection();
- } else {
- $charts = [];
- }
-
- if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) {
- $rId = 1;
-
- // Use original $relPath to get original $rId.
- // Take first. In future can be overwritten.
- // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Worksheet::writeDrawings)
- reset($drawingOriginalIds);
- $relPath = key($drawingOriginalIds);
- if (isset($drawingOriginalIds[$relPath])) {
- $rId = (int) (substr($drawingOriginalIds[$relPath], 3));
- }
-
- // Generate new $relPath to write drawing relationship
- $relPath = '../drawings/drawing' . $pWorksheetId . '.xml';
- $this->writeRelationship(
- $objWriter,
- $rId,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
- $relPath
- );
- }
-
- // Write hyperlink relationships?
- $i = 1;
- foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
- if (!$hyperlink->isInternal()) {
- $this->writeRelationship(
- $objWriter,
- '_hyperlink_' . $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
- $hyperlink->getUrl(),
- 'External'
- );
-
- ++$i;
- }
- }
-
- // Write comments relationship?
- $i = 1;
- if (count($pWorksheet->getComments()) > 0) {
- $this->writeRelationship(
- $objWriter,
- '_comments_vml' . $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
- '../drawings/vmlDrawing' . $pWorksheetId . '.vml'
- );
-
- $this->writeRelationship(
- $objWriter,
- '_comments' . $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',
- '../comments' . $pWorksheetId . '.xml'
- );
- }
-
- // Write header/footer relationship?
- $i = 1;
- if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {
- $this->writeRelationship(
- $objWriter,
- '_headerfooter_vml' . $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
- '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'
- );
- }
-
- $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp');
- $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing');
- $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings');
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type): void
- {
- $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData();
- if (!isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship])) {
- return;
- }
-
- foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) {
- $this->writeRelationship(
- $objWriter,
- $rId,
- $type,
- $value['relFilePath']
- );
- }
- }
-
- /**
- * Write drawing relationships to XML format.
- *
- * @param int &$chartRef Chart ID
- * @param bool $includeCharts Flag indicating if we should write charts
- *
- * @return string XML Output
- */
- public function writeDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, &$chartRef, $includeCharts = false)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
-
- // Loop through images and write relationships
- $i = 1;
- $iterator = $pWorksheet->getDrawingCollection()->getIterator();
- while ($iterator->valid()) {
- if (
- $iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing
- || $iterator->current() instanceof MemoryDrawing
- ) {
- // Write relationship for image drawing
- /** @var \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing */
- $drawing = $iterator->current();
- $this->writeRelationship(
- $objWriter,
- $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
- '../media/' . str_replace(' ', '', $drawing->getIndexedFilename())
- );
-
- $i = $this->writeDrawingHyperLink($objWriter, $drawing, $i);
- }
-
- $iterator->next();
- ++$i;
- }
-
- if ($includeCharts) {
- // Loop through charts and write relationships
- $chartCount = $pWorksheet->getChartCount();
- if ($chartCount > 0) {
- for ($c = 0; $c < $chartCount; ++$c) {
- $this->writeRelationship(
- $objWriter,
- $i++,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
- '../charts/chart' . ++$chartRef . '.xml'
- );
- }
- }
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write header/footer drawing relationships to XML format.
- *
- * @return string XML Output
- */
- public function writeHeaderFooterDrawingRelationships(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
-
- // Loop through images and write relationships
- foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {
- // Write relationship for image drawing
- $this->writeRelationship(
- $objWriter,
- $key,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
- '../media/' . $value->getIndexedFilename()
- );
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write Override content type.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param int $pId Relationship ID. rId will be prepended!
- * @param string $pType Relationship type
- * @param string $pTarget Relationship target
- * @param string $pTargetMode Relationship target mode
- */
- private function writeRelationship(XMLWriter $objWriter, $pId, $pType, $pTarget, $pTargetMode = ''): void
- {
- if ($pType != '' && $pTarget != '') {
- // Write relationship
- $objWriter->startElement('Relationship');
- $objWriter->writeAttribute('Id', 'rId' . $pId);
- $objWriter->writeAttribute('Type', $pType);
- $objWriter->writeAttribute('Target', $pTarget);
-
- if ($pTargetMode != '') {
- $objWriter->writeAttribute('TargetMode', $pTargetMode);
- }
-
- $objWriter->endElement();
- } else {
- throw new WriterException('Invalid parameters passed.');
- }
- }
-
- /**
- * @param $objWriter
- * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing
- * @param $i
- *
- * @return int
- */
- private function writeDrawingHyperLink($objWriter, $drawing, $i)
- {
- if ($drawing->getHyperlink() === null) {
- return $i;
- }
-
- ++$i;
- $this->writeRelationship(
- $objWriter,
- $i,
- 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
- $drawing->getHyperlink()->getUrl(),
- $drawing->getHyperlink()->getTypeHyperlink()
- );
-
- return $i;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php b/vendor/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php
deleted file mode 100644
index 8005207..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/RelsRibbon.php
+++ /dev/null
@@ -1,45 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
- $localRels = $spreadsheet->getRibbonBinObjects('names');
- if (is_array($localRels)) {
- foreach ($localRels as $aId => $aTarget) {
- $objWriter->startElement('Relationship');
- $objWriter->writeAttribute('Id', $aId);
- $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image');
- $objWriter->writeAttribute('Target', $aTarget);
- $objWriter->endElement();
- }
- }
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/RelsVBA.php b/vendor/PhpSpreadsheet/Writer/Xlsx/RelsVBA.php
deleted file mode 100644
index 55bcd36..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/RelsVBA.php
+++ /dev/null
@@ -1,40 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Relationships
- $objWriter->startElement('Relationships');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
- $objWriter->startElement('Relationship');
- $objWriter->writeAttribute('Id', 'rId1');
- $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature');
- $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin');
- $objWriter->endElement();
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/vendor/PhpSpreadsheet/Writer/Xlsx/StringTable.php
deleted file mode 100644
index b0f7d6d..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/StringTable.php
+++ /dev/null
@@ -1,282 +0,0 @@
-flipStringTable($aStringTable);
-
- // Loop through cells
- foreach ($pSheet->getCoordinates() as $coordinate) {
- $cell = $pSheet->getCell($coordinate);
- $cellValue = $cell->getValue();
- if (
- !is_object($cellValue) &&
- ($cellValue !== null) &&
- $cellValue !== '' &&
- !isset($aFlippedStringTable[$cellValue]) &&
- ($cell->getDataType() == DataType::TYPE_STRING || $cell->getDataType() == DataType::TYPE_STRING2 || $cell->getDataType() == DataType::TYPE_NULL)
- ) {
- $aStringTable[] = $cellValue;
- $aFlippedStringTable[$cellValue] = true;
- } elseif (
- $cellValue instanceof RichText &&
- ($cellValue !== null) &&
- !isset($aFlippedStringTable[$cellValue->getHashCode()])
- ) {
- $aStringTable[] = $cellValue;
- $aFlippedStringTable[$cellValue->getHashCode()] = true;
- }
- }
-
- return $aStringTable;
- }
-
- /**
- * Write string table to XML format.
- *
- * @param string[] $pStringTable
- *
- * @return string XML Output
- */
- public function writeStringTable(array $pStringTable)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // String table
- $objWriter->startElement('sst');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
- $objWriter->writeAttribute('uniqueCount', count($pStringTable));
-
- // Loop through string table
- foreach ($pStringTable as $textElement) {
- $objWriter->startElement('si');
-
- if (!$textElement instanceof RichText) {
- $textToWrite = StringHelper::controlCharacterPHP2OOXML($textElement);
- $objWriter->startElement('t');
- if ($textToWrite !== trim($textToWrite)) {
- $objWriter->writeAttribute('xml:space', 'preserve');
- }
- $objWriter->writeRawData($textToWrite);
- $objWriter->endElement();
- } elseif ($textElement instanceof RichText) {
- $this->writeRichText($objWriter, $textElement);
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
-
- return $objWriter->getData();
- }
-
- /**
- * Write Rich Text.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param RichText $pRichText Rich text
- * @param string $prefix Optional Namespace prefix
- */
- public function writeRichText(XMLWriter $objWriter, RichText $pRichText, $prefix = null): void
- {
- if ($prefix !== null) {
- $prefix .= ':';
- }
-
- // Loop through rich text elements
- $elements = $pRichText->getRichTextElements();
- foreach ($elements as $element) {
- // r
- $objWriter->startElement($prefix . 'r');
-
- // rPr
- if ($element instanceof Run) {
- // rPr
- $objWriter->startElement($prefix . 'rPr');
-
- // rFont
- $objWriter->startElement($prefix . 'rFont');
- $objWriter->writeAttribute('val', $element->getFont()->getName());
- $objWriter->endElement();
-
- // Bold
- $objWriter->startElement($prefix . 'b');
- $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false'));
- $objWriter->endElement();
-
- // Italic
- $objWriter->startElement($prefix . 'i');
- $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false'));
- $objWriter->endElement();
-
- // Superscript / subscript
- if ($element->getFont()->getSuperscript() || $element->getFont()->getSubscript()) {
- $objWriter->startElement($prefix . 'vertAlign');
- if ($element->getFont()->getSuperscript()) {
- $objWriter->writeAttribute('val', 'superscript');
- } elseif ($element->getFont()->getSubscript()) {
- $objWriter->writeAttribute('val', 'subscript');
- }
- $objWriter->endElement();
- }
-
- // Strikethrough
- $objWriter->startElement($prefix . 'strike');
- $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false'));
- $objWriter->endElement();
-
- // Color
- $objWriter->startElement($prefix . 'color');
- $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB());
- $objWriter->endElement();
-
- // Size
- $objWriter->startElement($prefix . 'sz');
- $objWriter->writeAttribute('val', $element->getFont()->getSize());
- $objWriter->endElement();
-
- // Underline
- $objWriter->startElement($prefix . 'u');
- $objWriter->writeAttribute('val', $element->getFont()->getUnderline());
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- // t
- $objWriter->startElement($prefix . 't');
- $objWriter->writeAttribute('xml:space', 'preserve');
- $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText()));
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write Rich Text.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param RichText|string $pRichText text string or Rich text
- * @param string $prefix Optional Namespace prefix
- */
- public function writeRichTextForCharts(XMLWriter $objWriter, $pRichText = null, $prefix = null): void
- {
- if (!$pRichText instanceof RichText) {
- $textRun = $pRichText;
- $pRichText = new RichText();
- $pRichText->createTextRun($textRun);
- }
-
- if ($prefix !== null) {
- $prefix .= ':';
- }
-
- // Loop through rich text elements
- $elements = $pRichText->getRichTextElements();
- foreach ($elements as $element) {
- // r
- $objWriter->startElement($prefix . 'r');
-
- // rPr
- $objWriter->startElement($prefix . 'rPr');
-
- // Bold
- $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0));
- // Italic
- $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0));
- // Underline
- $underlineType = $element->getFont()->getUnderline();
- switch ($underlineType) {
- case 'single':
- $underlineType = 'sng';
-
- break;
- case 'double':
- $underlineType = 'dbl';
-
- break;
- }
- $objWriter->writeAttribute('u', $underlineType);
- // Strikethrough
- $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));
-
- // rFont
- $objWriter->startElement($prefix . 'latin');
- $objWriter->writeAttribute('typeface', $element->getFont()->getName());
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // t
- $objWriter->startElement($prefix . 't');
- $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText()));
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Flip string table (for index searching).
- *
- * @param array $stringTable Stringtable
- *
- * @return array
- */
- public function flipStringTable(array $stringTable)
- {
- // Return value
- $returnValue = [];
-
- // Loop through stringtable and add flipped items to $returnValue
- foreach ($stringTable as $key => $value) {
- if (!$value instanceof RichText) {
- $returnValue[$value] = $key;
- } elseif ($value instanceof RichText) {
- $returnValue[$value->getHashCode()] = $key;
- }
- }
-
- return $returnValue;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Style.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Style.php
deleted file mode 100644
index 0c43fbf..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Style.php
+++ /dev/null
@@ -1,676 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // styleSheet
- $objWriter->startElement('styleSheet');
- $objWriter->writeAttribute('xml:space', 'preserve');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
-
- // numFmts
- $objWriter->startElement('numFmts');
- $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count());
-
- // numFmt
- for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) {
- $this->writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i);
- }
-
- $objWriter->endElement();
-
- // fonts
- $objWriter->startElement('fonts');
- $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count());
-
- // font
- for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {
- $this->writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i));
- }
-
- $objWriter->endElement();
-
- // fills
- $objWriter->startElement('fills');
- $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count());
-
- // fill
- for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) {
- $this->writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i));
- }
-
- $objWriter->endElement();
-
- // borders
- $objWriter->startElement('borders');
- $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count());
-
- // border
- for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) {
- $this->writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i));
- }
-
- $objWriter->endElement();
-
- // cellStyleXfs
- $objWriter->startElement('cellStyleXfs');
- $objWriter->writeAttribute('count', 1);
-
- // xf
- $objWriter->startElement('xf');
- $objWriter->writeAttribute('numFmtId', 0);
- $objWriter->writeAttribute('fontId', 0);
- $objWriter->writeAttribute('fillId', 0);
- $objWriter->writeAttribute('borderId', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // cellXfs
- $objWriter->startElement('cellXfs');
- $objWriter->writeAttribute('count', count($spreadsheet->getCellXfCollection()));
-
- // xf
- foreach ($spreadsheet->getCellXfCollection() as $cellXf) {
- $this->writeCellStyleXf($objWriter, $cellXf, $spreadsheet);
- }
-
- $objWriter->endElement();
-
- // cellStyles
- $objWriter->startElement('cellStyles');
- $objWriter->writeAttribute('count', 1);
-
- // cellStyle
- $objWriter->startElement('cellStyle');
- $objWriter->writeAttribute('name', 'Normal');
- $objWriter->writeAttribute('xfId', 0);
- $objWriter->writeAttribute('builtinId', 0);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // dxfs
- $objWriter->startElement('dxfs');
- $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count());
-
- // dxf
- for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {
- $this->writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle());
- }
-
- $objWriter->endElement();
-
- // tableStyles
- $objWriter->startElement('tableStyles');
- $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9');
- $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write Fill.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Fill $pFill Fill style
- */
- private function writeFill(XMLWriter $objWriter, Fill $pFill): void
- {
- // Check if this is a pattern type or gradient type
- if (
- $pFill->getFillType() === Fill::FILL_GRADIENT_LINEAR ||
- $pFill->getFillType() === Fill::FILL_GRADIENT_PATH
- ) {
- // Gradient fill
- $this->writeGradientFill($objWriter, $pFill);
- } elseif ($pFill->getFillType() !== null) {
- // Pattern fill
- $this->writePatternFill($objWriter, $pFill);
- }
- }
-
- /**
- * Write Gradient Fill.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Fill $pFill Fill style
- */
- private function writeGradientFill(XMLWriter $objWriter, Fill $pFill): void
- {
- // fill
- $objWriter->startElement('fill');
-
- // gradientFill
- $objWriter->startElement('gradientFill');
- $objWriter->writeAttribute('type', $pFill->getFillType());
- $objWriter->writeAttribute('degree', $pFill->getRotation());
-
- // stop
- $objWriter->startElement('stop');
- $objWriter->writeAttribute('position', '0');
-
- // color
- $objWriter->startElement('color');
- $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // stop
- $objWriter->startElement('stop');
- $objWriter->writeAttribute('position', '1');
-
- // color
- $objWriter->startElement('color');
- $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Pattern Fill.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Fill $pFill Fill style
- */
- private function writePatternFill(XMLWriter $objWriter, Fill $pFill): void
- {
- // fill
- $objWriter->startElement('fill');
-
- // patternFill
- $objWriter->startElement('patternFill');
- $objWriter->writeAttribute('patternType', $pFill->getFillType());
-
- if ($pFill->getFillType() !== Fill::FILL_NONE) {
- // fgColor
- if ($pFill->getStartColor()->getARGB()) {
- $objWriter->startElement('fgColor');
- $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());
- $objWriter->endElement();
- }
- }
- if ($pFill->getFillType() !== Fill::FILL_NONE) {
- // bgColor
- if ($pFill->getEndColor()->getARGB()) {
- $objWriter->startElement('bgColor');
- $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write Font.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Font $pFont Font style
- */
- private function writeFont(XMLWriter $objWriter, Font $pFont): void
- {
- // font
- $objWriter->startElement('font');
- // Weird! The order of these elements actually makes a difference when opening Xlsx
- // files in Excel2003 with the compatibility pack. It's not documented behaviour,
- // and makes for a real WTF!
-
- // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does
- // for conditional formatting). Otherwise it will apparently not be picked up in conditional
- // formatting style dialog
- if ($pFont->getBold() !== null) {
- $objWriter->startElement('b');
- $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0');
- $objWriter->endElement();
- }
-
- // Italic
- if ($pFont->getItalic() !== null) {
- $objWriter->startElement('i');
- $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0');
- $objWriter->endElement();
- }
-
- // Strikethrough
- if ($pFont->getStrikethrough() !== null) {
- $objWriter->startElement('strike');
- $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0');
- $objWriter->endElement();
- }
-
- // Underline
- if ($pFont->getUnderline() !== null) {
- $objWriter->startElement('u');
- $objWriter->writeAttribute('val', $pFont->getUnderline());
- $objWriter->endElement();
- }
-
- // Superscript / subscript
- if ($pFont->getSuperscript() === true || $pFont->getSubscript() === true) {
- $objWriter->startElement('vertAlign');
- if ($pFont->getSuperscript() === true) {
- $objWriter->writeAttribute('val', 'superscript');
- } elseif ($pFont->getSubscript() === true) {
- $objWriter->writeAttribute('val', 'subscript');
- }
- $objWriter->endElement();
- }
-
- // Size
- if ($pFont->getSize() !== null) {
- $objWriter->startElement('sz');
- $objWriter->writeAttribute('val', StringHelper::formatNumber($pFont->getSize()));
- $objWriter->endElement();
- }
-
- // Foreground color
- if ($pFont->getColor()->getARGB() !== null) {
- $objWriter->startElement('color');
- $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB());
- $objWriter->endElement();
- }
-
- // Name
- if ($pFont->getName() !== null) {
- $objWriter->startElement('name');
- $objWriter->writeAttribute('val', $pFont->getName());
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Border.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param Borders $pBorders Borders style
- */
- private function writeBorder(XMLWriter $objWriter, Borders $pBorders): void
- {
- // Write border
- $objWriter->startElement('border');
- // Diagonal?
- switch ($pBorders->getDiagonalDirection()) {
- case Borders::DIAGONAL_UP:
- $objWriter->writeAttribute('diagonalUp', 'true');
- $objWriter->writeAttribute('diagonalDown', 'false');
-
- break;
- case Borders::DIAGONAL_DOWN:
- $objWriter->writeAttribute('diagonalUp', 'false');
- $objWriter->writeAttribute('diagonalDown', 'true');
-
- break;
- case Borders::DIAGONAL_BOTH:
- $objWriter->writeAttribute('diagonalUp', 'true');
- $objWriter->writeAttribute('diagonalDown', 'true');
-
- break;
- }
-
- // BorderPr
- $this->writeBorderPr($objWriter, 'left', $pBorders->getLeft());
- $this->writeBorderPr($objWriter, 'right', $pBorders->getRight());
- $this->writeBorderPr($objWriter, 'top', $pBorders->getTop());
- $this->writeBorderPr($objWriter, 'bottom', $pBorders->getBottom());
- $this->writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal());
- $objWriter->endElement();
- }
-
- /**
- * Write Cell Style Xf.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param \PhpOffice\PhpSpreadsheet\Style\Style $pStyle Style
- * @param Spreadsheet $spreadsheet Workbook
- */
- private function writeCellStyleXf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $pStyle, Spreadsheet $spreadsheet): void
- {
- // xf
- $objWriter->startElement('xf');
- $objWriter->writeAttribute('xfId', 0);
- $objWriter->writeAttribute('fontId', (int) $this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode()));
- if ($pStyle->getQuotePrefix()) {
- $objWriter->writeAttribute('quotePrefix', 1);
- }
-
- if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) {
- $objWriter->writeAttribute('numFmtId', (int) ($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164));
- } else {
- $objWriter->writeAttribute('numFmtId', (int) $pStyle->getNumberFormat()->getBuiltInFormatCode());
- }
-
- $objWriter->writeAttribute('fillId', (int) $this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode()));
- $objWriter->writeAttribute('borderId', (int) $this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode()));
-
- // Apply styles?
- $objWriter->writeAttribute('applyFont', ($spreadsheet->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0');
- $objWriter->writeAttribute('applyNumberFormat', ($spreadsheet->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0');
- $objWriter->writeAttribute('applyFill', ($spreadsheet->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0');
- $objWriter->writeAttribute('applyBorder', ($spreadsheet->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0');
- $objWriter->writeAttribute('applyAlignment', ($spreadsheet->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0');
- if ($pStyle->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
- $objWriter->writeAttribute('applyProtection', 'true');
- }
-
- // alignment
- $objWriter->startElement('alignment');
- $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal());
- $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical());
-
- $textRotation = 0;
- if ($pStyle->getAlignment()->getTextRotation() >= 0) {
- $textRotation = $pStyle->getAlignment()->getTextRotation();
- } elseif ($pStyle->getAlignment()->getTextRotation() < 0) {
- $textRotation = 90 - $pStyle->getAlignment()->getTextRotation();
- }
- $objWriter->writeAttribute('textRotation', $textRotation);
-
- $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false'));
- $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false'));
-
- if ($pStyle->getAlignment()->getIndent() > 0) {
- $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent());
- }
- if ($pStyle->getAlignment()->getReadOrder() > 0) {
- $objWriter->writeAttribute('readingOrder', $pStyle->getAlignment()->getReadOrder());
- }
- $objWriter->endElement();
-
- // protection
- if ($pStyle->getProtection()->getLocked() != Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
- $objWriter->startElement('protection');
- if ($pStyle->getProtection()->getLocked() != Protection::PROTECTION_INHERIT) {
- $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
- }
- if ($pStyle->getProtection()->getHidden() != Protection::PROTECTION_INHERIT) {
- $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
- }
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Cell Style Dxf.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param \PhpOffice\PhpSpreadsheet\Style\Style $pStyle Style
- */
- private function writeCellStyleDxf(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Style\Style $pStyle): void
- {
- // dxf
- $objWriter->startElement('dxf');
-
- // font
- $this->writeFont($objWriter, $pStyle->getFont());
-
- // numFmt
- $this->writeNumFmt($objWriter, $pStyle->getNumberFormat());
-
- // fill
- $this->writeFill($objWriter, $pStyle->getFill());
-
- // alignment
- $objWriter->startElement('alignment');
- if ($pStyle->getAlignment()->getHorizontal() !== null) {
- $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal());
- }
- if ($pStyle->getAlignment()->getVertical() !== null) {
- $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical());
- }
-
- if ($pStyle->getAlignment()->getTextRotation() !== null) {
- $textRotation = 0;
- if ($pStyle->getAlignment()->getTextRotation() >= 0) {
- $textRotation = $pStyle->getAlignment()->getTextRotation();
- } elseif ($pStyle->getAlignment()->getTextRotation() < 0) {
- $textRotation = 90 - $pStyle->getAlignment()->getTextRotation();
- }
- $objWriter->writeAttribute('textRotation', $textRotation);
- }
- $objWriter->endElement();
-
- // border
- $this->writeBorder($objWriter, $pStyle->getBorders());
-
- // protection
- if (($pStyle->getProtection()->getLocked() !== null) || ($pStyle->getProtection()->getHidden() !== null)) {
- if (
- $pStyle->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT ||
- $pStyle->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT
- ) {
- $objWriter->startElement('protection');
- if (
- ($pStyle->getProtection()->getLocked() !== null) &&
- ($pStyle->getProtection()->getLocked() !== Protection::PROTECTION_INHERIT)
- ) {
- $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
- }
- if (
- ($pStyle->getProtection()->getHidden() !== null) &&
- ($pStyle->getProtection()->getHidden() !== Protection::PROTECTION_INHERIT)
- ) {
- $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED ? 'true' : 'false'));
- }
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write BorderPr.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pName Element name
- * @param Border $pBorder Border style
- */
- private function writeBorderPr(XMLWriter $objWriter, $pName, Border $pBorder): void
- {
- // Write BorderPr
- if ($pBorder->getBorderStyle() != Border::BORDER_NONE) {
- $objWriter->startElement($pName);
- $objWriter->writeAttribute('style', $pBorder->getBorderStyle());
-
- // color
- $objWriter->startElement('color');
- $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB());
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write NumberFormat.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param NumberFormat $pNumberFormat Number Format
- * @param int $pId Number Format identifier
- */
- private function writeNumFmt(XMLWriter $objWriter, NumberFormat $pNumberFormat, $pId = 0): void
- {
- // Translate formatcode
- $formatCode = $pNumberFormat->getFormatCode();
-
- // numFmt
- if ($formatCode !== null) {
- $objWriter->startElement('numFmt');
- $objWriter->writeAttribute('numFmtId', ($pId + 164));
- $objWriter->writeAttribute('formatCode', $formatCode);
- $objWriter->endElement();
- }
- }
-
- /**
- * Get an array of all styles.
- *
- * @return \PhpOffice\PhpSpreadsheet\Style\Style[] All styles in PhpSpreadsheet
- */
- public function allStyles(Spreadsheet $spreadsheet)
- {
- return $spreadsheet->getCellXfCollection();
- }
-
- /**
- * Get an array of all conditional styles.
- *
- * @return Conditional[] All conditional styles in PhpSpreadsheet
- */
- public function allConditionalStyles(Spreadsheet $spreadsheet)
- {
- // Get an array of all styles
- $aStyles = [];
-
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- foreach ($spreadsheet->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) {
- foreach ($conditionalStyles as $conditionalStyle) {
- $aStyles[] = $conditionalStyle;
- }
- }
- }
-
- return $aStyles;
- }
-
- /**
- * Get an array of all fills.
- *
- * @return Fill[] All fills in PhpSpreadsheet
- */
- public function allFills(Spreadsheet $spreadsheet)
- {
- // Get an array of unique fills
- $aFills = [];
-
- // Two first fills are predefined
- $fill0 = new Fill();
- $fill0->setFillType(Fill::FILL_NONE);
- $aFills[] = $fill0;
-
- $fill1 = new Fill();
- $fill1->setFillType(Fill::FILL_PATTERN_GRAY125);
- $aFills[] = $fill1;
- // The remaining fills
- $aStyles = $this->allStyles($spreadsheet);
- /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
- foreach ($aStyles as $style) {
- if (!isset($aFills[$style->getFill()->getHashCode()])) {
- $aFills[$style->getFill()->getHashCode()] = $style->getFill();
- }
- }
-
- return $aFills;
- }
-
- /**
- * Get an array of all fonts.
- *
- * @return Font[] All fonts in PhpSpreadsheet
- */
- public function allFonts(Spreadsheet $spreadsheet)
- {
- // Get an array of unique fonts
- $aFonts = [];
- $aStyles = $this->allStyles($spreadsheet);
-
- /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
- foreach ($aStyles as $style) {
- if (!isset($aFonts[$style->getFont()->getHashCode()])) {
- $aFonts[$style->getFont()->getHashCode()] = $style->getFont();
- }
- }
-
- return $aFonts;
- }
-
- /**
- * Get an array of all borders.
- *
- * @return Borders[] All borders in PhpSpreadsheet
- */
- public function allBorders(Spreadsheet $spreadsheet)
- {
- // Get an array of unique borders
- $aBorders = [];
- $aStyles = $this->allStyles($spreadsheet);
-
- /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
- foreach ($aStyles as $style) {
- if (!isset($aBorders[$style->getBorders()->getHashCode()])) {
- $aBorders[$style->getBorders()->getHashCode()] = $style->getBorders();
- }
- }
-
- return $aBorders;
- }
-
- /**
- * Get an array of all number formats.
- *
- * @return NumberFormat[] All number formats in PhpSpreadsheet
- */
- public function allNumberFormats(Spreadsheet $spreadsheet)
- {
- // Get an array of unique number formats
- $aNumFmts = [];
- $aStyles = $this->allStyles($spreadsheet);
-
- /** @var \PhpOffice\PhpSpreadsheet\Style\Style $style */
- foreach ($aStyles as $style) {
- if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !isset($aNumFmts[$style->getNumberFormat()->getHashCode()])) {
- $aNumFmts[$style->getNumberFormat()->getHashCode()] = $style->getNumberFormat();
- }
- }
-
- return $aNumFmts;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Theme.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Theme.php
deleted file mode 100644
index 3a47be7..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Theme.php
+++ /dev/null
@@ -1,837 +0,0 @@
- 'MS Pゴシック',
- 'Hang' => '맑은 고딕',
- 'Hans' => '宋体',
- 'Hant' => '新細明體',
- 'Arab' => 'Times New Roman',
- 'Hebr' => 'Times New Roman',
- 'Thai' => 'Tahoma',
- 'Ethi' => 'Nyala',
- 'Beng' => 'Vrinda',
- 'Gujr' => 'Shruti',
- 'Khmr' => 'MoolBoran',
- 'Knda' => 'Tunga',
- 'Guru' => 'Raavi',
- 'Cans' => 'Euphemia',
- 'Cher' => 'Plantagenet Cherokee',
- 'Yiii' => 'Microsoft Yi Baiti',
- 'Tibt' => 'Microsoft Himalaya',
- 'Thaa' => 'MV Boli',
- 'Deva' => 'Mangal',
- 'Telu' => 'Gautami',
- 'Taml' => 'Latha',
- 'Syrc' => 'Estrangelo Edessa',
- 'Orya' => 'Kalinga',
- 'Mlym' => 'Kartika',
- 'Laoo' => 'DokChampa',
- 'Sinh' => 'Iskoola Pota',
- 'Mong' => 'Mongolian Baiti',
- 'Viet' => 'Times New Roman',
- 'Uigh' => 'Microsoft Uighur',
- 'Geor' => 'Sylfaen',
- ];
-
- /**
- * Map of Minor fonts to write.
- *
- * @var array of string
- */
- private static $minorFonts = [
- 'Jpan' => 'MS Pゴシック',
- 'Hang' => '맑은 고딕',
- 'Hans' => '宋体',
- 'Hant' => '新細明體',
- 'Arab' => 'Arial',
- 'Hebr' => 'Arial',
- 'Thai' => 'Tahoma',
- 'Ethi' => 'Nyala',
- 'Beng' => 'Vrinda',
- 'Gujr' => 'Shruti',
- 'Khmr' => 'DaunPenh',
- 'Knda' => 'Tunga',
- 'Guru' => 'Raavi',
- 'Cans' => 'Euphemia',
- 'Cher' => 'Plantagenet Cherokee',
- 'Yiii' => 'Microsoft Yi Baiti',
- 'Tibt' => 'Microsoft Himalaya',
- 'Thaa' => 'MV Boli',
- 'Deva' => 'Mangal',
- 'Telu' => 'Gautami',
- 'Taml' => 'Latha',
- 'Syrc' => 'Estrangelo Edessa',
- 'Orya' => 'Kalinga',
- 'Mlym' => 'Kartika',
- 'Laoo' => 'DokChampa',
- 'Sinh' => 'Iskoola Pota',
- 'Mong' => 'Mongolian Baiti',
- 'Viet' => 'Arial',
- 'Uigh' => 'Microsoft Uighur',
- 'Geor' => 'Sylfaen',
- ];
-
- /**
- * Map of core colours.
- *
- * @var array of string
- */
- private static $colourScheme = [
- 'dk2' => '1F497D',
- 'lt2' => 'EEECE1',
- 'accent1' => '4F81BD',
- 'accent2' => 'C0504D',
- 'accent3' => '9BBB59',
- 'accent4' => '8064A2',
- 'accent5' => '4BACC6',
- 'accent6' => 'F79646',
- 'hlink' => '0000FF',
- 'folHlink' => '800080',
- ];
-
- /**
- * Write theme to XML format.
- *
- * @return string XML Output
- */
- public function writeTheme(Spreadsheet $spreadsheet)
- {
- // Create XML writer
- $objWriter = null;
- if ($this->getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // a:theme
- $objWriter->startElement('a:theme');
- $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
- $objWriter->writeAttribute('name', 'Office Theme');
-
- // a:themeElements
- $objWriter->startElement('a:themeElements');
-
- // a:clrScheme
- $objWriter->startElement('a:clrScheme');
- $objWriter->writeAttribute('name', 'Office');
-
- // a:dk1
- $objWriter->startElement('a:dk1');
-
- // a:sysClr
- $objWriter->startElement('a:sysClr');
- $objWriter->writeAttribute('val', 'windowText');
- $objWriter->writeAttribute('lastClr', '000000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:lt1
- $objWriter->startElement('a:lt1');
-
- // a:sysClr
- $objWriter->startElement('a:sysClr');
- $objWriter->writeAttribute('val', 'window');
- $objWriter->writeAttribute('lastClr', 'FFFFFF');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:dk2
- $this->writeColourScheme($objWriter);
-
- $objWriter->endElement();
-
- // a:fontScheme
- $objWriter->startElement('a:fontScheme');
- $objWriter->writeAttribute('name', 'Office');
-
- // a:majorFont
- $objWriter->startElement('a:majorFont');
- $this->writeFonts($objWriter, 'Cambria', self::$majorFonts);
- $objWriter->endElement();
-
- // a:minorFont
- $objWriter->startElement('a:minorFont');
- $this->writeFonts($objWriter, 'Calibri', self::$minorFonts);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:fmtScheme
- $objWriter->startElement('a:fmtScheme');
- $objWriter->writeAttribute('name', 'Office');
-
- // a:fillStyleLst
- $objWriter->startElement('a:fillStyleLst');
-
- // a:solidFill
- $objWriter->startElement('a:solidFill');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gradFill
- $objWriter->startElement('a:gradFill');
- $objWriter->writeAttribute('rotWithShape', '1');
-
- // a:gsLst
- $objWriter->startElement('a:gsLst');
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '0');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '50000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '300000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '35000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '37000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '300000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '100000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '15000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '350000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:lin
- $objWriter->startElement('a:lin');
- $objWriter->writeAttribute('ang', '16200000');
- $objWriter->writeAttribute('scaled', '1');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gradFill
- $objWriter->startElement('a:gradFill');
- $objWriter->writeAttribute('rotWithShape', '1');
-
- // a:gsLst
- $objWriter->startElement('a:gsLst');
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '0');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '51000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '130000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '80000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '93000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '130000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '100000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '94000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '135000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:lin
- $objWriter->startElement('a:lin');
- $objWriter->writeAttribute('ang', '16200000');
- $objWriter->writeAttribute('scaled', '0');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:lnStyleLst
- $objWriter->startElement('a:lnStyleLst');
-
- // a:ln
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', '9525');
- $objWriter->writeAttribute('cap', 'flat');
- $objWriter->writeAttribute('cmpd', 'sng');
- $objWriter->writeAttribute('algn', 'ctr');
-
- // a:solidFill
- $objWriter->startElement('a:solidFill');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '95000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '105000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:prstDash
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', 'solid');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:ln
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', '25400');
- $objWriter->writeAttribute('cap', 'flat');
- $objWriter->writeAttribute('cmpd', 'sng');
- $objWriter->writeAttribute('algn', 'ctr');
-
- // a:solidFill
- $objWriter->startElement('a:solidFill');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:prstDash
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', 'solid');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:ln
- $objWriter->startElement('a:ln');
- $objWriter->writeAttribute('w', '38100');
- $objWriter->writeAttribute('cap', 'flat');
- $objWriter->writeAttribute('cmpd', 'sng');
- $objWriter->writeAttribute('algn', 'ctr');
-
- // a:solidFill
- $objWriter->startElement('a:solidFill');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:prstDash
- $objWriter->startElement('a:prstDash');
- $objWriter->writeAttribute('val', 'solid');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:effectStyleLst
- $objWriter->startElement('a:effectStyleLst');
-
- // a:effectStyle
- $objWriter->startElement('a:effectStyle');
-
- // a:effectLst
- $objWriter->startElement('a:effectLst');
-
- // a:outerShdw
- $objWriter->startElement('a:outerShdw');
- $objWriter->writeAttribute('blurRad', '40000');
- $objWriter->writeAttribute('dist', '20000');
- $objWriter->writeAttribute('dir', '5400000');
- $objWriter->writeAttribute('rotWithShape', '0');
-
- // a:srgbClr
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', '000000');
-
- // a:alpha
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', '38000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:effectStyle
- $objWriter->startElement('a:effectStyle');
-
- // a:effectLst
- $objWriter->startElement('a:effectLst');
-
- // a:outerShdw
- $objWriter->startElement('a:outerShdw');
- $objWriter->writeAttribute('blurRad', '40000');
- $objWriter->writeAttribute('dist', '23000');
- $objWriter->writeAttribute('dir', '5400000');
- $objWriter->writeAttribute('rotWithShape', '0');
-
- // a:srgbClr
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', '000000');
-
- // a:alpha
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', '35000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:effectStyle
- $objWriter->startElement('a:effectStyle');
-
- // a:effectLst
- $objWriter->startElement('a:effectLst');
-
- // a:outerShdw
- $objWriter->startElement('a:outerShdw');
- $objWriter->writeAttribute('blurRad', '40000');
- $objWriter->writeAttribute('dist', '23000');
- $objWriter->writeAttribute('dir', '5400000');
- $objWriter->writeAttribute('rotWithShape', '0');
-
- // a:srgbClr
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', '000000');
-
- // a:alpha
- $objWriter->startElement('a:alpha');
- $objWriter->writeAttribute('val', '35000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:scene3d
- $objWriter->startElement('a:scene3d');
-
- // a:camera
- $objWriter->startElement('a:camera');
- $objWriter->writeAttribute('prst', 'orthographicFront');
-
- // a:rot
- $objWriter->startElement('a:rot');
- $objWriter->writeAttribute('lat', '0');
- $objWriter->writeAttribute('lon', '0');
- $objWriter->writeAttribute('rev', '0');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:lightRig
- $objWriter->startElement('a:lightRig');
- $objWriter->writeAttribute('rig', 'threePt');
- $objWriter->writeAttribute('dir', 't');
-
- // a:rot
- $objWriter->startElement('a:rot');
- $objWriter->writeAttribute('lat', '0');
- $objWriter->writeAttribute('lon', '0');
- $objWriter->writeAttribute('rev', '1200000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:sp3d
- $objWriter->startElement('a:sp3d');
-
- // a:bevelT
- $objWriter->startElement('a:bevelT');
- $objWriter->writeAttribute('w', '63500');
- $objWriter->writeAttribute('h', '25400');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:bgFillStyleLst
- $objWriter->startElement('a:bgFillStyleLst');
-
- // a:solidFill
- $objWriter->startElement('a:solidFill');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gradFill
- $objWriter->startElement('a:gradFill');
- $objWriter->writeAttribute('rotWithShape', '1');
-
- // a:gsLst
- $objWriter->startElement('a:gsLst');
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '0');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '40000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '350000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '40000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '45000');
- $objWriter->endElement();
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '99000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '350000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '100000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '20000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '255000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:path
- $objWriter->startElement('a:path');
- $objWriter->writeAttribute('path', 'circle');
-
- // a:fillToRect
- $objWriter->startElement('a:fillToRect');
- $objWriter->writeAttribute('l', '50000');
- $objWriter->writeAttribute('t', '-80000');
- $objWriter->writeAttribute('r', '50000');
- $objWriter->writeAttribute('b', '180000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gradFill
- $objWriter->startElement('a:gradFill');
- $objWriter->writeAttribute('rotWithShape', '1');
-
- // a:gsLst
- $objWriter->startElement('a:gsLst');
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '0');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:tint
- $objWriter->startElement('a:tint');
- $objWriter->writeAttribute('val', '80000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '300000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:gs
- $objWriter->startElement('a:gs');
- $objWriter->writeAttribute('pos', '100000');
-
- // a:schemeClr
- $objWriter->startElement('a:schemeClr');
- $objWriter->writeAttribute('val', 'phClr');
-
- // a:shade
- $objWriter->startElement('a:shade');
- $objWriter->writeAttribute('val', '30000');
- $objWriter->endElement();
-
- // a:satMod
- $objWriter->startElement('a:satMod');
- $objWriter->writeAttribute('val', '200000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:path
- $objWriter->startElement('a:path');
- $objWriter->writeAttribute('path', 'circle');
-
- // a:fillToRect
- $objWriter->startElement('a:fillToRect');
- $objWriter->writeAttribute('l', '50000');
- $objWriter->writeAttribute('t', '50000');
- $objWriter->writeAttribute('r', '50000');
- $objWriter->writeAttribute('b', '50000');
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- // a:objectDefaults
- $objWriter->writeElement('a:objectDefaults', null);
-
- // a:extraClrSchemeLst
- $objWriter->writeElement('a:extraClrSchemeLst', null);
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write fonts to XML format.
- *
- * @param XMLWriter $objWriter
- * @param string $latinFont
- * @param array of string $fontSet
- *
- * @return string XML Output
- */
- private function writeFonts($objWriter, $latinFont, $fontSet)
- {
- // a:latin
- $objWriter->startElement('a:latin');
- $objWriter->writeAttribute('typeface', $latinFont);
- $objWriter->endElement();
-
- // a:ea
- $objWriter->startElement('a:ea');
- $objWriter->writeAttribute('typeface', '');
- $objWriter->endElement();
-
- // a:cs
- $objWriter->startElement('a:cs');
- $objWriter->writeAttribute('typeface', '');
- $objWriter->endElement();
-
- foreach ($fontSet as $fontScript => $typeface) {
- $objWriter->startElement('a:font');
- $objWriter->writeAttribute('script', $fontScript);
- $objWriter->writeAttribute('typeface', $typeface);
- $objWriter->endElement();
- }
- }
-
- /**
- * Write colour scheme to XML format.
- *
- * @param XMLWriter $objWriter
- *
- * @return string XML Output
- */
- private function writeColourScheme($objWriter)
- {
- foreach (self::$colourScheme as $colourName => $colourValue) {
- $objWriter->startElement('a:' . $colourName);
-
- $objWriter->startElement('a:srgbClr');
- $objWriter->writeAttribute('val', $colourValue);
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Workbook.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Workbook.php
deleted file mode 100644
index 0a20ea9..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Workbook.php
+++ /dev/null
@@ -1,225 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // workbook
- $objWriter->startElement('workbook');
- $objWriter->writeAttribute('xml:space', 'preserve');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
-
- // fileVersion
- $this->writeFileVersion($objWriter);
-
- // workbookPr
- $this->writeWorkbookPr($objWriter);
-
- // workbookProtection
- $this->writeWorkbookProtection($objWriter, $spreadsheet);
-
- // bookViews
- if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
- $this->writeBookViews($objWriter, $spreadsheet);
- }
-
- // sheets
- $this->writeSheets($objWriter, $spreadsheet);
-
- // definedNames
- (new DefinedNamesWriter($objWriter, $spreadsheet))->write();
-
- // calcPr
- $this->writeCalcPr($objWriter, $recalcRequired);
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write file version.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeFileVersion(XMLWriter $objWriter): void
- {
- $objWriter->startElement('fileVersion');
- $objWriter->writeAttribute('appName', 'xl');
- $objWriter->writeAttribute('lastEdited', '4');
- $objWriter->writeAttribute('lowestEdited', '4');
- $objWriter->writeAttribute('rupBuild', '4505');
- $objWriter->endElement();
- }
-
- /**
- * Write WorkbookPr.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeWorkbookPr(XMLWriter $objWriter): void
- {
- $objWriter->startElement('workbookPr');
-
- if (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) {
- $objWriter->writeAttribute('date1904', '1');
- }
-
- $objWriter->writeAttribute('codeName', 'ThisWorkbook');
-
- $objWriter->endElement();
- }
-
- /**
- * Write BookViews.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeBookViews(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
- {
- // bookViews
- $objWriter->startElement('bookViews');
-
- // workbookView
- $objWriter->startElement('workbookView');
-
- $objWriter->writeAttribute('activeTab', $spreadsheet->getActiveSheetIndex());
- $objWriter->writeAttribute('autoFilterDateGrouping', ($spreadsheet->getAutoFilterDateGrouping() ? 'true' : 'false'));
- $objWriter->writeAttribute('firstSheet', $spreadsheet->getFirstSheetIndex());
- $objWriter->writeAttribute('minimized', ($spreadsheet->getMinimized() ? 'true' : 'false'));
- $objWriter->writeAttribute('showHorizontalScroll', ($spreadsheet->getShowHorizontalScroll() ? 'true' : 'false'));
- $objWriter->writeAttribute('showSheetTabs', ($spreadsheet->getShowSheetTabs() ? 'true' : 'false'));
- $objWriter->writeAttribute('showVerticalScroll', ($spreadsheet->getShowVerticalScroll() ? 'true' : 'false'));
- $objWriter->writeAttribute('tabRatio', $spreadsheet->getTabRatio());
- $objWriter->writeAttribute('visibility', $spreadsheet->getVisibility());
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write WorkbookProtection.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeWorkbookProtection(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
- {
- if ($spreadsheet->getSecurity()->isSecurityEnabled()) {
- $objWriter->startElement('workbookProtection');
- $objWriter->writeAttribute('lockRevision', ($spreadsheet->getSecurity()->getLockRevision() ? 'true' : 'false'));
- $objWriter->writeAttribute('lockStructure', ($spreadsheet->getSecurity()->getLockStructure() ? 'true' : 'false'));
- $objWriter->writeAttribute('lockWindows', ($spreadsheet->getSecurity()->getLockWindows() ? 'true' : 'false'));
-
- if ($spreadsheet->getSecurity()->getRevisionsPassword() != '') {
- $objWriter->writeAttribute('revisionsPassword', $spreadsheet->getSecurity()->getRevisionsPassword());
- }
-
- if ($spreadsheet->getSecurity()->getWorkbookPassword() != '') {
- $objWriter->writeAttribute('workbookPassword', $spreadsheet->getSecurity()->getWorkbookPassword());
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write calcPr.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param bool $recalcRequired Indicate whether formulas should be recalculated before writing
- */
- private function writeCalcPr(XMLWriter $objWriter, $recalcRequired = true): void
- {
- $objWriter->startElement('calcPr');
-
- // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc
- // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit
- // because the file has changed
- $objWriter->writeAttribute('calcId', '999999');
- $objWriter->writeAttribute('calcMode', 'auto');
- // fullCalcOnLoad isn't needed if we've recalculating for the save
- $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0);
- $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1);
- $objWriter->writeAttribute('forceFullCalc', ($recalcRequired) ? 0 : 1);
-
- $objWriter->endElement();
- }
-
- /**
- * Write sheets.
- *
- * @param XMLWriter $objWriter XML Writer
- */
- private function writeSheets(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
- {
- // Write sheets
- $objWriter->startElement('sheets');
- $sheetCount = $spreadsheet->getSheetCount();
- for ($i = 0; $i < $sheetCount; ++$i) {
- // sheet
- $this->writeSheet(
- $objWriter,
- $spreadsheet->getSheet($i)->getTitle(),
- ($i + 1),
- ($i + 1 + 3),
- $spreadsheet->getSheet($i)->getSheetState()
- );
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write sheet.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param string $pSheetname Sheet name
- * @param int $pSheetId Sheet id
- * @param int $pRelId Relationship ID
- * @param string $sheetState Sheet state (visible, hidden, veryHidden)
- */
- private function writeSheet(XMLWriter $objWriter, $pSheetname, $pSheetId = 1, $pRelId = 1, $sheetState = 'visible'): void
- {
- if ($pSheetname != '') {
- // Write sheet
- $objWriter->startElement('sheet');
- $objWriter->writeAttribute('name', $pSheetname);
- $objWriter->writeAttribute('sheetId', $pSheetId);
- if ($sheetState !== 'visible' && $sheetState != '') {
- $objWriter->writeAttribute('state', $sheetState);
- }
- $objWriter->writeAttribute('r:id', 'rId' . $pRelId);
- $objWriter->endElement();
- } else {
- throw new WriterException('Invalid parameters passed.');
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
deleted file mode 100644
index b6a6fc3..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+++ /dev/null
@@ -1,1282 +0,0 @@
-getParentWriter()->getUseDiskCaching()) {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
- } else {
- $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
- }
-
- // XML header
- $objWriter->startDocument('1.0', 'UTF-8', 'yes');
-
- // Worksheet
- $objWriter->startElement('worksheet');
- $objWriter->writeAttribute('xml:space', 'preserve');
- $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
- $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
-
- $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
- $objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
- $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
- $objWriter->writeAttribute('mc:Ignorable', 'x14ac');
- $objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
-
- // sheetPr
- $this->writeSheetPr($objWriter, $pSheet);
-
- // Dimension
- $this->writeDimension($objWriter, $pSheet);
-
- // sheetViews
- $this->writeSheetViews($objWriter, $pSheet);
-
- // sheetFormatPr
- $this->writeSheetFormatPr($objWriter, $pSheet);
-
- // cols
- $this->writeCols($objWriter, $pSheet);
-
- // sheetData
- $this->writeSheetData($objWriter, $pSheet, $pStringTable);
-
- // sheetProtection
- $this->writeSheetProtection($objWriter, $pSheet);
-
- // protectedRanges
- $this->writeProtectedRanges($objWriter, $pSheet);
-
- // autoFilter
- $this->writeAutoFilter($objWriter, $pSheet);
-
- // mergeCells
- $this->writeMergeCells($objWriter, $pSheet);
-
- // conditionalFormatting
- $this->writeConditionalFormatting($objWriter, $pSheet);
-
- // dataValidations
- $this->writeDataValidations($objWriter, $pSheet);
-
- // hyperlinks
- $this->writeHyperlinks($objWriter, $pSheet);
-
- // Print options
- $this->writePrintOptions($objWriter, $pSheet);
-
- // Page margins
- $this->writePageMargins($objWriter, $pSheet);
-
- // Page setup
- $this->writePageSetup($objWriter, $pSheet);
-
- // Header / footer
- $this->writeHeaderFooter($objWriter, $pSheet);
-
- // Breaks
- $this->writeBreaks($objWriter, $pSheet);
-
- // Drawings and/or Charts
- $this->writeDrawings($objWriter, $pSheet, $includeCharts);
-
- // LegacyDrawing
- $this->writeLegacyDrawing($objWriter, $pSheet);
-
- // LegacyDrawingHF
- $this->writeLegacyDrawingHF($objWriter, $pSheet);
-
- // AlternateContent
- $this->writeAlternateContent($objWriter, $pSheet);
-
- $objWriter->endElement();
-
- // Return
- return $objWriter->getData();
- }
-
- /**
- * Write SheetPr.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeSheetPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // sheetPr
- $objWriter->startElement('sheetPr');
- if ($pSheet->getParent()->hasMacros()) {
- //if the workbook have macros, we need to have codeName for the sheet
- if (!$pSheet->hasCodeName()) {
- $pSheet->setCodeName($pSheet->getTitle());
- }
- $objWriter->writeAttribute('codeName', $pSheet->getCodeName());
- }
- $autoFilterRange = $pSheet->getAutoFilter()->getRange();
- if (!empty($autoFilterRange)) {
- $objWriter->writeAttribute('filterMode', 1);
- $pSheet->getAutoFilter()->showHideRows();
- }
-
- // tabColor
- if ($pSheet->isTabColorSet()) {
- $objWriter->startElement('tabColor');
- $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB());
- $objWriter->endElement();
- }
-
- // outlinePr
- $objWriter->startElement('outlinePr');
- $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0'));
- $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0'));
- $objWriter->endElement();
-
- // pageSetUpPr
- if ($pSheet->getPageSetup()->getFitToPage()) {
- $objWriter->startElement('pageSetUpPr');
- $objWriter->writeAttribute('fitToPage', '1');
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Dimension.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeDimension(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // dimension
- $objWriter->startElement('dimension');
- $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());
- $objWriter->endElement();
- }
-
- /**
- * Write SheetViews.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeSheetViews(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // sheetViews
- $objWriter->startElement('sheetViews');
-
- // Sheet selected?
- $sheetSelected = false;
- if ($this->getParentWriter()->getSpreadsheet()->getIndex($pSheet) == $this->getParentWriter()->getSpreadsheet()->getActiveSheetIndex()) {
- $sheetSelected = true;
- }
-
- // sheetView
- $objWriter->startElement('sheetView');
- $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0');
- $objWriter->writeAttribute('workbookViewId', '0');
-
- // Zoom scales
- if ($pSheet->getSheetView()->getZoomScale() != 100) {
- $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale());
- }
- if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {
- $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal());
- }
-
- // Show zeros (Excel also writes this attribute only if set to false)
- if ($pSheet->getSheetView()->getShowZeros() === false) {
- $objWriter->writeAttribute('showZeros', 0);
- }
-
- // View Layout Type
- if ($pSheet->getSheetView()->getView() !== SheetView::SHEETVIEW_NORMAL) {
- $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView());
- }
-
- // Gridlines
- if ($pSheet->getShowGridlines()) {
- $objWriter->writeAttribute('showGridLines', 'true');
- } else {
- $objWriter->writeAttribute('showGridLines', 'false');
- }
-
- // Row and column headers
- if ($pSheet->getShowRowColHeaders()) {
- $objWriter->writeAttribute('showRowColHeaders', '1');
- } else {
- $objWriter->writeAttribute('showRowColHeaders', '0');
- }
-
- // Right-to-left
- if ($pSheet->getRightToLeft()) {
- $objWriter->writeAttribute('rightToLeft', 'true');
- }
-
- $activeCell = $pSheet->getActiveCell();
- $sqref = $pSheet->getSelectedCells();
-
- // Pane
- $pane = '';
- if ($pSheet->getFreezePane()) {
- [$xSplit, $ySplit] = Coordinate::coordinateFromString($pSheet->getFreezePane());
- $xSplit = Coordinate::columnIndexFromString($xSplit);
- --$xSplit;
- --$ySplit;
-
- $topLeftCell = $pSheet->getTopLeftCell();
-
- // pane
- $pane = 'topRight';
- $objWriter->startElement('pane');
- if ($xSplit > 0) {
- $objWriter->writeAttribute('xSplit', $xSplit);
- }
- if ($ySplit > 0) {
- $objWriter->writeAttribute('ySplit', $ySplit);
- $pane = ($xSplit > 0) ? 'bottomRight' : 'bottomLeft';
- }
- $objWriter->writeAttribute('topLeftCell', $topLeftCell);
- $objWriter->writeAttribute('activePane', $pane);
- $objWriter->writeAttribute('state', 'frozen');
- $objWriter->endElement();
-
- if (($xSplit > 0) && ($ySplit > 0)) {
- // Write additional selections if more than two panes (ie both an X and a Y split)
- $objWriter->startElement('selection');
- $objWriter->writeAttribute('pane', 'topRight');
- $objWriter->endElement();
- $objWriter->startElement('selection');
- $objWriter->writeAttribute('pane', 'bottomLeft');
- $objWriter->endElement();
- }
- }
-
- // Selection
- // Only need to write selection element if we have a split pane
- // We cheat a little by over-riding the active cell selection, setting it to the split cell
- $objWriter->startElement('selection');
- if ($pane != '') {
- $objWriter->writeAttribute('pane', $pane);
- }
- $objWriter->writeAttribute('activeCell', $activeCell);
- $objWriter->writeAttribute('sqref', $sqref);
- $objWriter->endElement();
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
-
- /**
- * Write SheetFormatPr.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeSheetFormatPr(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // sheetFormatPr
- $objWriter->startElement('sheetFormatPr');
-
- // Default row height
- if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {
- $objWriter->writeAttribute('customHeight', 'true');
- $objWriter->writeAttribute('defaultRowHeight', StringHelper::formatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));
- } else {
- $objWriter->writeAttribute('defaultRowHeight', '14.4');
- }
-
- // Set Zero Height row
- if (
- (string) $pSheet->getDefaultRowDimension()->getZeroHeight() === '1' ||
- strtolower((string) $pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true'
- ) {
- $objWriter->writeAttribute('zeroHeight', '1');
- }
-
- // Default column width
- if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {
- $objWriter->writeAttribute('defaultColWidth', StringHelper::formatNumber($pSheet->getDefaultColumnDimension()->getWidth()));
- }
-
- // Outline level - row
- $outlineLevelRow = 0;
- foreach ($pSheet->getRowDimensions() as $dimension) {
- if ($dimension->getOutlineLevel() > $outlineLevelRow) {
- $outlineLevelRow = $dimension->getOutlineLevel();
- }
- }
- $objWriter->writeAttribute('outlineLevelRow', (int) $outlineLevelRow);
-
- // Outline level - column
- $outlineLevelCol = 0;
- foreach ($pSheet->getColumnDimensions() as $dimension) {
- if ($dimension->getOutlineLevel() > $outlineLevelCol) {
- $outlineLevelCol = $dimension->getOutlineLevel();
- }
- }
- $objWriter->writeAttribute('outlineLevelCol', (int) $outlineLevelCol);
-
- $objWriter->endElement();
- }
-
- /**
- * Write Cols.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeCols(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // cols
- if (count($pSheet->getColumnDimensions()) > 0) {
- $objWriter->startElement('cols');
-
- $pSheet->calculateColumnWidths();
-
- // Loop through column dimensions
- foreach ($pSheet->getColumnDimensions() as $colDimension) {
- // col
- $objWriter->startElement('col');
- $objWriter->writeAttribute('min', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
- $objWriter->writeAttribute('max', Coordinate::columnIndexFromString($colDimension->getColumnIndex()));
-
- if ($colDimension->getWidth() < 0) {
- // No width set, apply default of 10
- $objWriter->writeAttribute('width', '9.10');
- } else {
- // Width set
- $objWriter->writeAttribute('width', StringHelper::formatNumber($colDimension->getWidth()));
- }
-
- // Column visibility
- if ($colDimension->getVisible() === false) {
- $objWriter->writeAttribute('hidden', 'true');
- }
-
- // Auto size?
- if ($colDimension->getAutoSize()) {
- $objWriter->writeAttribute('bestFit', 'true');
- }
-
- // Custom width?
- if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {
- $objWriter->writeAttribute('customWidth', 'true');
- }
-
- // Collapsed
- if ($colDimension->getCollapsed() === true) {
- $objWriter->writeAttribute('collapsed', 'true');
- }
-
- // Outline level
- if ($colDimension->getOutlineLevel() > 0) {
- $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel());
- }
-
- // Style
- $objWriter->writeAttribute('style', $colDimension->getXfIndex());
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write SheetProtection.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeSheetProtection(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // sheetProtection
- $objWriter->startElement('sheetProtection');
-
- $protection = $pSheet->getProtection();
-
- if ($protection->getAlgorithm()) {
- $objWriter->writeAttribute('algorithmName', $protection->getAlgorithm());
- $objWriter->writeAttribute('hashValue', $protection->getPassword());
- $objWriter->writeAttribute('saltValue', $protection->getSalt());
- $objWriter->writeAttribute('spinCount', $protection->getSpinCount());
- } elseif ($protection->getPassword() !== '') {
- $objWriter->writeAttribute('password', $protection->getPassword());
- }
-
- $objWriter->writeAttribute('sheet', ($protection->getSheet() ? 'true' : 'false'));
- $objWriter->writeAttribute('objects', ($protection->getObjects() ? 'true' : 'false'));
- $objWriter->writeAttribute('scenarios', ($protection->getScenarios() ? 'true' : 'false'));
- $objWriter->writeAttribute('formatCells', ($protection->getFormatCells() ? 'true' : 'false'));
- $objWriter->writeAttribute('formatColumns', ($protection->getFormatColumns() ? 'true' : 'false'));
- $objWriter->writeAttribute('formatRows', ($protection->getFormatRows() ? 'true' : 'false'));
- $objWriter->writeAttribute('insertColumns', ($protection->getInsertColumns() ? 'true' : 'false'));
- $objWriter->writeAttribute('insertRows', ($protection->getInsertRows() ? 'true' : 'false'));
- $objWriter->writeAttribute('insertHyperlinks', ($protection->getInsertHyperlinks() ? 'true' : 'false'));
- $objWriter->writeAttribute('deleteColumns', ($protection->getDeleteColumns() ? 'true' : 'false'));
- $objWriter->writeAttribute('deleteRows', ($protection->getDeleteRows() ? 'true' : 'false'));
- $objWriter->writeAttribute('selectLockedCells', ($protection->getSelectLockedCells() ? 'true' : 'false'));
- $objWriter->writeAttribute('sort', ($protection->getSort() ? 'true' : 'false'));
- $objWriter->writeAttribute('autoFilter', ($protection->getAutoFilter() ? 'true' : 'false'));
- $objWriter->writeAttribute('pivotTables', ($protection->getPivotTables() ? 'true' : 'false'));
- $objWriter->writeAttribute('selectUnlockedCells', ($protection->getSelectUnlockedCells() ? 'true' : 'false'));
- $objWriter->endElement();
- }
-
- private static function writeAttributeIf(XMLWriter $objWriter, $condition, string $attr, string $val): void
- {
- if ($condition) {
- $objWriter->writeAttribute($attr, $val);
- }
- }
-
- private static function writeElementIf(XMLWriter $objWriter, $condition, string $attr, string $val): void
- {
- if ($condition) {
- $objWriter->writeElement($attr, $val);
- }
- }
-
- private static function writeOtherCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void
- {
- if (
- $conditional->getConditionType() == Conditional::CONDITION_CELLIS
- || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT
- || $conditional->getConditionType() == Conditional::CONDITION_EXPRESSION
- ) {
- foreach ($conditional->getConditions() as $formula) {
- // Formula
- $objWriter->writeElement('formula', Xlfn::addXlfn($formula));
- }
- } elseif ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSBLANKS) {
- // formula copied from ms xlsx xml source file
- $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))=0');
- } elseif ($conditional->getConditionType() == Conditional::CONDITION_NOTCONTAINSBLANKS) {
- // formula copied from ms xlsx xml source file
- $objWriter->writeElement('formula', 'LEN(TRIM(' . $cellCoordinate . '))>0');
- }
- }
-
- private static function writeTextCondElements(XMLWriter $objWriter, Conditional $conditional, string $cellCoordinate): void
- {
- $txt = $conditional->getText();
- if ($txt !== null) {
- $objWriter->writeAttribute('text', $txt);
- if ($conditional->getOperatorType() == Conditional::OPERATOR_CONTAINSTEXT) {
- $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . ')))');
- } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_BEGINSWITH) {
- $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"');
- } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_ENDSWITH) {
- $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($txt) . ')="' . $txt . '"');
- } elseif ($conditional->getOperatorType() == Conditional::OPERATOR_NOTCONTAINS) {
- $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $txt . '",' . $cellCoordinate . '))');
- }
- }
- }
-
- /**
- * Write ConditionalFormatting.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeConditionalFormatting(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // Conditional id
- $id = 1;
-
- // Loop through styles in the current worksheet
- foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
- foreach ($conditionalStyles as $conditional) {
- // WHY was this again?
- // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()) == '') {
- // continue;
- // }
- if ($conditional->getConditionType() != Conditional::CONDITION_NONE) {
- // conditionalFormatting
- $objWriter->startElement('conditionalFormatting');
- $objWriter->writeAttribute('sqref', $cellCoordinate);
-
- // cfRule
- $objWriter->startElement('cfRule');
- $objWriter->writeAttribute('type', $conditional->getConditionType());
- $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
- $objWriter->writeAttribute('priority', $id++);
-
- self::writeAttributeif(
- $objWriter,
- ($conditional->getConditionType() == Conditional::CONDITION_CELLIS || $conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT)
- && $conditional->getOperatorType() != Conditional::OPERATOR_NONE,
- 'operator',
- $conditional->getOperatorType()
- );
-
- self::writeAttributeIf($objWriter, $conditional->getStopIfTrue(), 'stopIfTrue', '1');
-
- if ($conditional->getConditionType() == Conditional::CONDITION_CONTAINSTEXT) {
- self::writeTextCondElements($objWriter, $conditional, $cellCoordinate);
- } else {
- self::writeOtherCondElements($objWriter, $conditional, $cellCoordinate);
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
- }
- }
-
- /**
- * Write DataValidations.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeDataValidations(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // Datavalidation collection
- $dataValidationCollection = $pSheet->getDataValidationCollection();
-
- // Write data validations?
- if (!empty($dataValidationCollection)) {
- $dataValidationCollection = Coordinate::mergeRangesInCollection($dataValidationCollection);
- $objWriter->startElement('dataValidations');
- $objWriter->writeAttribute('count', count($dataValidationCollection));
-
- foreach ($dataValidationCollection as $coordinate => $dv) {
- $objWriter->startElement('dataValidation');
-
- if ($dv->getType() != '') {
- $objWriter->writeAttribute('type', $dv->getType());
- }
-
- if ($dv->getErrorStyle() != '') {
- $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());
- }
-
- if ($dv->getOperator() != '') {
- $objWriter->writeAttribute('operator', $dv->getOperator());
- }
-
- $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0'));
- $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0'));
- $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0'));
- $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0'));
-
- if ($dv->getErrorTitle() !== '') {
- $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());
- }
- if ($dv->getError() !== '') {
- $objWriter->writeAttribute('error', $dv->getError());
- }
- if ($dv->getPromptTitle() !== '') {
- $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());
- }
- if ($dv->getPrompt() !== '') {
- $objWriter->writeAttribute('prompt', $dv->getPrompt());
- }
-
- $objWriter->writeAttribute('sqref', $coordinate);
-
- if ($dv->getFormula1() !== '') {
- $objWriter->writeElement('formula1', $dv->getFormula1());
- }
- if ($dv->getFormula2() !== '') {
- $objWriter->writeElement('formula2', $dv->getFormula2());
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write Hyperlinks.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeHyperlinks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // Hyperlink collection
- $hyperlinkCollection = $pSheet->getHyperlinkCollection();
-
- // Relation ID
- $relationId = 1;
-
- // Write hyperlinks?
- if (!empty($hyperlinkCollection)) {
- $objWriter->startElement('hyperlinks');
-
- foreach ($hyperlinkCollection as $coordinate => $hyperlink) {
- $objWriter->startElement('hyperlink');
-
- $objWriter->writeAttribute('ref', $coordinate);
- if (!$hyperlink->isInternal()) {
- $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId);
- ++$relationId;
- } else {
- $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl()));
- }
-
- if ($hyperlink->getTooltip() !== '') {
- $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());
- $objWriter->writeAttribute('display', $hyperlink->getTooltip());
- }
-
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write ProtectedRanges.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeProtectedRanges(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- if (count($pSheet->getProtectedCells()) > 0) {
- // protectedRanges
- $objWriter->startElement('protectedRanges');
-
- // Loop protectedRanges
- foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {
- // protectedRange
- $objWriter->startElement('protectedRange');
- $objWriter->writeAttribute('name', 'p' . md5($protectedCell));
- $objWriter->writeAttribute('sqref', $protectedCell);
- if (!empty($passwordHash)) {
- $objWriter->writeAttribute('password', $passwordHash);
- }
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write MergeCells.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeMergeCells(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- if (count($pSheet->getMergeCells()) > 0) {
- // mergeCells
- $objWriter->startElement('mergeCells');
-
- // Loop mergeCells
- foreach ($pSheet->getMergeCells() as $mergeCell) {
- // mergeCell
- $objWriter->startElement('mergeCell');
- $objWriter->writeAttribute('ref', $mergeCell);
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write PrintOptions.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writePrintOptions(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // printOptions
- $objWriter->startElement('printOptions');
-
- $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true' : 'false'));
- $objWriter->writeAttribute('gridLinesSet', 'true');
-
- if ($pSheet->getPageSetup()->getHorizontalCentered()) {
- $objWriter->writeAttribute('horizontalCentered', 'true');
- }
-
- if ($pSheet->getPageSetup()->getVerticalCentered()) {
- $objWriter->writeAttribute('verticalCentered', 'true');
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write PageMargins.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writePageMargins(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // pageMargins
- $objWriter->startElement('pageMargins');
- $objWriter->writeAttribute('left', StringHelper::formatNumber($pSheet->getPageMargins()->getLeft()));
- $objWriter->writeAttribute('right', StringHelper::formatNumber($pSheet->getPageMargins()->getRight()));
- $objWriter->writeAttribute('top', StringHelper::formatNumber($pSheet->getPageMargins()->getTop()));
- $objWriter->writeAttribute('bottom', StringHelper::formatNumber($pSheet->getPageMargins()->getBottom()));
- $objWriter->writeAttribute('header', StringHelper::formatNumber($pSheet->getPageMargins()->getHeader()));
- $objWriter->writeAttribute('footer', StringHelper::formatNumber($pSheet->getPageMargins()->getFooter()));
- $objWriter->endElement();
- }
-
- /**
- * Write AutoFilter.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeAutoFilter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- $autoFilterRange = $pSheet->getAutoFilter()->getRange();
- if (!empty($autoFilterRange)) {
- // autoFilter
- $objWriter->startElement('autoFilter');
-
- // Strip any worksheet reference from the filter coordinates
- $range = Coordinate::splitRange($autoFilterRange);
- $range = $range[0];
- // Strip any worksheet ref
- [$ws, $range[0]] = PhpspreadsheetWorksheet::extractSheetTitle($range[0], true);
- $range = implode(':', $range);
-
- $objWriter->writeAttribute('ref', str_replace('$', '', $range));
-
- $columns = $pSheet->getAutoFilter()->getColumns();
- if (count($columns) > 0) {
- foreach ($columns as $columnID => $column) {
- $rules = $column->getRules();
- if (count($rules) > 0) {
- $objWriter->startElement('filterColumn');
- $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID));
-
- $objWriter->startElement($column->getFilterType());
- if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
- $objWriter->writeAttribute('and', 1);
- }
-
- foreach ($rules as $rule) {
- if (
- ($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER) &&
- ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&
- ($rule->getValue() === '')
- ) {
- // Filter rule for Blanks
- $objWriter->writeAttribute('blank', 1);
- } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
- // Dynamic Filter Rule
- $objWriter->writeAttribute('type', $rule->getGrouping());
- $val = $column->getAttribute('val');
- if ($val !== null) {
- $objWriter->writeAttribute('val', $val);
- }
- $maxVal = $column->getAttribute('maxVal');
- if ($maxVal !== null) {
- $objWriter->writeAttribute('maxVal', $maxVal);
- }
- } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
- // Top 10 Filter Rule
- $objWriter->writeAttribute('val', $rule->getValue());
- $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
- $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
- } else {
- // Filter, DateGroupItem or CustomFilter
- $objWriter->startElement($rule->getRuleType());
-
- if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
- $objWriter->writeAttribute('operator', $rule->getOperator());
- }
- if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
- // Date Group filters
- foreach ($rule->getValue() as $key => $value) {
- if ($value > '') {
- $objWriter->writeAttribute($key, $value);
- }
- }
- $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
- } else {
- $objWriter->writeAttribute('val', $rule->getValue());
- }
-
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
-
- $objWriter->endElement();
- }
- }
- }
- $objWriter->endElement();
- }
- }
-
- /**
- * Write PageSetup.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writePageSetup(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // pageSetup
- $objWriter->startElement('pageSetup');
- $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize());
- $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation());
-
- if ($pSheet->getPageSetup()->getScale() !== null) {
- $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale());
- }
- if ($pSheet->getPageSetup()->getFitToHeight() !== null) {
- $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight());
- } else {
- $objWriter->writeAttribute('fitToHeight', '0');
- }
- if ($pSheet->getPageSetup()->getFitToWidth() !== null) {
- $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth());
- } else {
- $objWriter->writeAttribute('fitToWidth', '0');
- }
- if ($pSheet->getPageSetup()->getFirstPageNumber() !== null) {
- $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
- $objWriter->writeAttribute('useFirstPageNumber', '1');
- }
- $objWriter->writeAttribute('pageOrder', $pSheet->getPageSetup()->getPageOrder());
-
- $getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
- if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) {
- $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId']);
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Header / Footer.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeHeaderFooter(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // headerFooter
- $objWriter->startElement('headerFooter');
- $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));
- $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));
- $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));
- $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));
-
- $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader());
- $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter());
- $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader());
- $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter());
- $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader());
- $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter());
- $objWriter->endElement();
- }
-
- /**
- * Write Breaks.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeBreaks(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // Get row and column breaks
- $aRowBreaks = [];
- $aColumnBreaks = [];
- foreach ($pSheet->getBreaks() as $cell => $breakType) {
- if ($breakType == PhpspreadsheetWorksheet::BREAK_ROW) {
- $aRowBreaks[] = $cell;
- } elseif ($breakType == PhpspreadsheetWorksheet::BREAK_COLUMN) {
- $aColumnBreaks[] = $cell;
- }
- }
-
- // rowBreaks
- if (!empty($aRowBreaks)) {
- $objWriter->startElement('rowBreaks');
- $objWriter->writeAttribute('count', count($aRowBreaks));
- $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks));
-
- foreach ($aRowBreaks as $cell) {
- $coords = Coordinate::coordinateFromString($cell);
-
- $objWriter->startElement('brk');
- $objWriter->writeAttribute('id', $coords[1]);
- $objWriter->writeAttribute('man', '1');
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
-
- // Second, write column breaks
- if (!empty($aColumnBreaks)) {
- $objWriter->startElement('colBreaks');
- $objWriter->writeAttribute('count', count($aColumnBreaks));
- $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks));
-
- foreach ($aColumnBreaks as $cell) {
- $coords = Coordinate::coordinateFromString($cell);
-
- $objWriter->startElement('brk');
- $objWriter->writeAttribute('id', Coordinate::columnIndexFromString($coords[0]) - 1);
- $objWriter->writeAttribute('man', '1');
- $objWriter->endElement();
- }
-
- $objWriter->endElement();
- }
- }
-
- /**
- * Write SheetData.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- * @param string[] $pStringTable String table
- */
- private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable): void
- {
- // Flipped stringtable, for faster index searching
- $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
-
- // sheetData
- $objWriter->startElement('sheetData');
-
- // Get column count
- $colCount = Coordinate::columnIndexFromString($pSheet->getHighestColumn());
-
- // Highest row number
- $highestRow = $pSheet->getHighestRow();
-
- // Loop through cells
- $cellsByRow = [];
- foreach ($pSheet->getCoordinates() as $coordinate) {
- $cellAddress = Coordinate::coordinateFromString($coordinate);
- $cellsByRow[$cellAddress[1]][] = $coordinate;
- }
-
- $currentRow = 0;
- while ($currentRow++ < $highestRow) {
- // Get row dimension
- $rowDimension = $pSheet->getRowDimension($currentRow);
-
- // Write current row?
- $writeCurrentRow = isset($cellsByRow[$currentRow]) || $rowDimension->getRowHeight() >= 0 || $rowDimension->getVisible() == false || $rowDimension->getCollapsed() == true || $rowDimension->getOutlineLevel() > 0 || $rowDimension->getXfIndex() !== null;
-
- if ($writeCurrentRow) {
- // Start a new row
- $objWriter->startElement('row');
- $objWriter->writeAttribute('r', $currentRow);
- $objWriter->writeAttribute('spans', '1:' . $colCount);
-
- // Row dimensions
- if ($rowDimension->getRowHeight() >= 0) {
- $objWriter->writeAttribute('customHeight', '1');
- $objWriter->writeAttribute('ht', StringHelper::formatNumber($rowDimension->getRowHeight()));
- }
-
- // Row visibility
- if (!$rowDimension->getVisible() === true) {
- $objWriter->writeAttribute('hidden', 'true');
- }
-
- // Collapsed
- if ($rowDimension->getCollapsed() === true) {
- $objWriter->writeAttribute('collapsed', 'true');
- }
-
- // Outline level
- if ($rowDimension->getOutlineLevel() > 0) {
- $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel());
- }
-
- // Style
- if ($rowDimension->getXfIndex() !== null) {
- $objWriter->writeAttribute('s', $rowDimension->getXfIndex());
- $objWriter->writeAttribute('customFormat', '1');
- }
-
- // Write cells
- if (isset($cellsByRow[$currentRow])) {
- foreach ($cellsByRow[$currentRow] as $cellAddress) {
- // Write cell
- $this->writeCell($objWriter, $pSheet, $cellAddress, $aFlippedStringTable);
- }
- }
-
- // End row
- $objWriter->endElement();
- }
- }
-
- $objWriter->endElement();
- }
-
- /**
- * @param RichText|string $cellValue
- */
- private function writeCellInlineStr(XMLWriter $objWriter, string $mappedType, $cellValue): void
- {
- $objWriter->writeAttribute('t', $mappedType);
- if (!$cellValue instanceof RichText) {
- $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
- } elseif ($cellValue instanceof RichText) {
- $objWriter->startElement('is');
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
- $objWriter->endElement();
- }
- }
-
- /**
- * @param RichText|string $cellValue
- * @param string[] $pFlippedStringTable
- */
- private function writeCellString(XMLWriter $objWriter, string $mappedType, $cellValue, array $pFlippedStringTable): void
- {
- $objWriter->writeAttribute('t', $mappedType);
- if (!$cellValue instanceof RichText) {
- self::writeElementIf($objWriter, isset($pFlippedStringTable[$cellValue]), 'v', $pFlippedStringTable[$cellValue]);
- } else {
- $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);
- }
- }
-
- /**
- * @param float|int $cellValue
- */
- private function writeCellNumeric(XMLWriter $objWriter, $cellValue): void
- {
- //force a decimal to be written if the type is float
- if (is_float($cellValue)) {
- // force point as decimal separator in case current locale uses comma
- $cellValue = str_replace(',', '.', (string) $cellValue);
- if (strpos($cellValue, '.') === false) {
- $cellValue = $cellValue . '.0';
- }
- }
- $objWriter->writeElement('v', $cellValue);
- }
-
- private function writeCellBoolean(XMLWriter $objWriter, string $mappedType, bool $cellValue): void
- {
- $objWriter->writeAttribute('t', $mappedType);
- $objWriter->writeElement('v', $cellValue ? '1' : '0');
- }
-
- private function writeCellError(XMLWriter $objWriter, string $mappedType, string $cellValue, string $formulaerr = '#NULL!'): void
- {
- $objWriter->writeAttribute('t', $mappedType);
- $cellIsFormula = substr($cellValue, 0, 1) === '=';
- self::writeElementIf($objWriter, $cellIsFormula, 'f', Xlfn::addXlfnStripEquals($cellValue));
- $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue);
- }
-
- private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell): void
- {
- $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue;
- if (is_string($calculatedValue)) {
- if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) {
- $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue);
-
- return;
- }
- $objWriter->writeAttribute('t', 'str');
- } elseif (is_bool($calculatedValue)) {
- $objWriter->writeAttribute('t', 'b');
- }
- // array values are not yet supported
- //$attributes = $pCell->getFormulaAttributes();
- //if (($attributes['t'] ?? null) === 'array') {
- // $objWriter->startElement('f');
- // $objWriter->writeAttribute('t', 'array');
- // $objWriter->writeAttribute('ref', $pCellAddress);
- // $objWriter->writeAttribute('aca', '1');
- // $objWriter->writeAttribute('ca', '1');
- // $objWriter->text(substr($cellValue, 1));
- // $objWriter->endElement();
- //} else {
- // $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
- //}
- $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
- self::writeElementIf(
- $objWriter,
- $this->getParentWriter()->getOffice2003Compatibility() === false,
- 'v',
- ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#')
- ? StringHelper::formatNumber($calculatedValue) : '0'
- );
- }
-
- /**
- * Write Cell.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- * @param string $pCellAddress Cell Address
- * @param string[] $pFlippedStringTable String table (flipped), for faster index searching
- */
- private function writeCell(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, string $pCellAddress, array $pFlippedStringTable): void
- {
- // Cell
- $pCell = $pSheet->getCell($pCellAddress);
- $objWriter->startElement('c');
- $objWriter->writeAttribute('r', $pCellAddress);
-
- // Sheet styles
- $xfi = $pCell->getXfIndex();
- self::writeAttributeIf($objWriter, $xfi, 's', $xfi);
-
- // If cell value is supplied, write cell value
- $cellValue = $pCell->getValue();
- if (is_object($cellValue) || $cellValue !== '') {
- // Map type
- $mappedType = $pCell->getDataType();
-
- // Write data depending on its type
- switch (strtolower($mappedType)) {
- case 'inlinestr': // Inline string
- $this->writeCellInlineStr($objWriter, $mappedType, $cellValue);
-
- break;
- case 's': // String
- $this->writeCellString($objWriter, $mappedType, $cellValue, $pFlippedStringTable);
-
- break;
- case 'f': // Formula
- $this->writeCellFormula($objWriter, $cellValue, $pCell);
-
- break;
- case 'n': // Numeric
- $this->writeCellNumeric($objWriter, $cellValue);
-
- break;
- case 'b': // Boolean
- $this->writeCellBoolean($objWriter, $mappedType, $cellValue);
-
- break;
- case 'e': // Error
- $this->writeCellError($objWriter, $mappedType, $cellValue);
- }
- }
-
- $objWriter->endElement();
- }
-
- /**
- * Write Drawings.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- * @param bool $includeCharts Flag indicating if we should include drawing details for charts
- */
- private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false): void
- {
- $unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
- $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']);
- $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;
- if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) {
- return;
- }
-
- // If sheet contains drawings, add the relationships
- $objWriter->startElement('drawing');
-
- $rId = 'rId1';
- if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) {
- $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'];
- // take first. In future can be overriten
- // (! synchronize with \PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels::writeWorksheetRelationships)
- $rId = reset($drawingOriginalIds);
- }
-
- $objWriter->writeAttribute('r:id', $rId);
- $objWriter->endElement();
- }
-
- /**
- * Write LegacyDrawing.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeLegacyDrawing(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // If sheet contains comments, add the relationships
- if (count($pSheet->getComments()) > 0) {
- $objWriter->startElement('legacyDrawing');
- $objWriter->writeAttribute('r:id', 'rId_comments_vml1');
- $objWriter->endElement();
- }
- }
-
- /**
- * Write LegacyDrawingHF.
- *
- * @param XMLWriter $objWriter XML Writer
- * @param PhpspreadsheetWorksheet $pSheet Worksheet
- */
- private function writeLegacyDrawingHF(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- // If sheet contains images, add the relationships
- if (count($pSheet->getHeaderFooter()->getImages()) > 0) {
- $objWriter->startElement('legacyDrawingHF');
- $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');
- $objWriter->endElement();
- }
- }
-
- private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
- {
- if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) {
- return;
- }
-
- foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) {
- $objWriter->writeRaw($alternateContent);
- }
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/WriterPart.php b/vendor/PhpSpreadsheet/Writer/Xlsx/WriterPart.php
deleted file mode 100644
index a9137df..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/WriterPart.php
+++ /dev/null
@@ -1,33 +0,0 @@
-parentWriter;
- }
-
- /**
- * Set parent Xlsx object.
- */
- public function __construct(Xlsx $pWriter)
- {
- $this->parentWriter = $pWriter;
- }
-}
diff --git a/vendor/PhpSpreadsheet/Writer/Xlsx/Xlfn.php b/vendor/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
deleted file mode 100644
index 8f7c07e..0000000
--- a/vendor/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
+++ /dev/null
@@ -1,159 +0,0 @@
-