From c852aca66d03ea85aa8f1b073b17f03944082ea3 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sat, 1 Mar 2025 09:08:00 +0400 Subject: [PATCH] migration nulib/spout vers openspout4 --- src/ext/spout/SpoutBuilder.php | 97 ++++++++++++++------------ src/ref/ext/spout/ref_builder.php | 2 + src/ref/ext/spout/ref_builder_xlsx.php | 41 +++++++++-- 3 files changed, 88 insertions(+), 52 deletions(-) diff --git a/src/ext/spout/SpoutBuilder.php b/src/ext/spout/SpoutBuilder.php index 5abdade..e45f1e9 100644 --- a/src/ext/spout/SpoutBuilder.php +++ b/src/ext/spout/SpoutBuilder.php @@ -14,14 +14,22 @@ use nulib\ref\ext\spout\ref_builder_ods; use nulib\ref\ext\spout\ref_builder_xlsx; use nulib\str; use nulib\web\http; -use OpenSpout\Common\Entity\Cell; use OpenSpout\Common\Entity\Style\Border; use OpenSpout\Common\Entity\Style\BorderPart; +use OpenSpout\Common\Entity\Cell\DateTimeCell; +use OpenSpout\Common\Entity\Cell\EmptyCell; +use OpenSpout\Common\Entity\Cell\NumericCell; +use OpenSpout\Common\Entity\Cell\StringCell; +use OpenSpout\Common\Entity\Row; +use OpenSpout\Common\Entity\Style\Color; use OpenSpout\Common\Entity\Style\Style; -use OpenSpout\Common\Helper\CellTypeHelper; -use OpenSpout\Writer\Common\Creator\WriterEntityFactory; -use OpenSpout\Writer\WriterMultiSheetsAbstract; +use OpenSpout\Writer\AbstractWriterMultiSheets; +use OpenSpout\Writer\Common\AbstractOptions; +use OpenSpout\Writer\ODS\Options as ODSOptions; +use OpenSpout\Writer\ODS\Writer as ODSWriter; use OpenSpout\Writer\XLSX\Entity\SheetView; +use OpenSpout\Writer\XLSX\Options as XLSXOptions; +use OpenSpout\Writer\XLSX\Writer as XLSXWriter; class SpoutBuilder extends AbstractBuilder { use TAbstractBuilder; @@ -42,16 +50,16 @@ class SpoutBuilder extends AbstractBuilder { return $object; } - protected static function add_border_part(?Border &$border, string $name, ?array $params): void { + protected static function add_border_part(?array &$parts, string $name, ?array $params): void { if ($params === null) return; - if ($border === null) $border = new Border(); - $part = new BorderPart($name); if (($color = $params["color"] ?? null) !== null) { - $part->setColor(cl::get(ref_builder::COLORS, $color, $color)); + $color = cl::get(ref_builder::COLORS, $color, $color); + } else { + $color = Color::BLACK; } - if (($width = $params["width"] ?? null) !== null) $part->setWidth($width); - if (($style = $params["style"] ?? null) !== null) $part->setStyle($style); - $border->addPart($part); + if (($width = $params["width"] ?? null) === null) $width = Border::WIDTH_MEDIUM; + if (($style = $params["style"] ?? null) === null) $style = Border::STYLE_SOLID; + $parts[] = new BorderPart($name, $color, $width, $style); } protected static function set_defaults(?array &$params, string $key, array $defaults): void { @@ -82,8 +90,9 @@ class SpoutBuilder extends AbstractBuilder { $style->setBackgroundColor(cl::get(ref_builder::COLORS, $color, $color)); } if (($align = $cell["align"] ?? null) !== null) $style->setCellAlignment($align); - //if (($align = $cell["valign"] ?? null) !== null) $style->setCellVerticalAlignment($align); + if (($align = $cell["valign"] ?? null) !== null) $style->setCellVerticalAlignment($align); if (($wrap = $cell["wrap"] ?? null) !== null) $style->setShouldWrapText($wrap); + if (($rotation = $cell["rotation"] ?? null) !== null) $style->setTextRotation($rotation); if (($format = $cell["format"] ?? null) !== null) $style->setFormat($format); if (($border = $cell["border"] ?? null) !== null) { if (is_string($border)) { @@ -114,18 +123,14 @@ class SpoutBuilder extends AbstractBuilder { if ($colorAll !== null) $part["color"] = $colorAll; }; unset($part); } - - $top = $border["top"] ?? null; - $right = $border["right"] ?? null; - $bottom = $border["bottom"] ?? null; - $left = $border["left"] ?? null; - $border = null; - self::add_border_part($border, "top", $top); - self::add_border_part($border, "right", $right); - self::add_border_part($border, "bottom", $bottom); - self::add_border_part($border, "left", $left); - if ($border !== null) $style->setBorder($border); + $parts = null; + self::add_border_part($parts, "top", $border["top"] ?? null); + self::add_border_part($parts, "right", $border["right"] ?? null); + self::add_border_part($parts, "bottom", $border["bottom"] ?? null); + self::add_border_part($parts, "left", $border["left"] ?? null); + if ($parts !== null) $style->setBorder(new Border(...$parts)); } + if (($autofit = $cell["autofit"] ?? null) !== null) $style->setShouldShrinkToFit($autofit); return $style; } @@ -173,26 +178,31 @@ class SpoutBuilder extends AbstractBuilder { case "ods": case self::SS_TYPE_ODS: $ssType = self::SS_TYPE_ODS; - $ssWriter = WriterEntityFactory::createODSWriter(); - self::apply_params($ssWriter, $spoutParams, ref_builder_ods::PARAMS_SPOUT); + $ssOptions = new ODSOptions(); + $ssWriterClass = ODSWriter::class; + $refParams = ref_builder_ods::PARAMS_SPOUT; break; case "xlsx": case self::SS_TYPE_XLSX: default: - $ssType = self::SS_TYPE_XLSX; - $ssWriter = WriterEntityFactory::createXLSXWriter(); - self::apply_params($ssWriter, $spoutParams, ref_builder_xlsx::PARAMS_SPOUT); - break; + $ssType = self::SS_TYPE_XLSX; + $ssOptions = new XLSXOptions(); + $ssWriterClass = XLSXWriter::class; + $refParams = ref_builder_xlsx::PARAMS_SPOUT; + break; } $defaultColumnWidth = $spoutParams["default_column_width"] ?? null; - if ($defaultColumnWidth !== null) $ssWriter->setDefaultColumnWidth($defaultColumnWidth); + if ($defaultColumnWidth !== null) $ssOptions->DEFAULT_COLUMN_WIDTH = $defaultColumnWidth; $defaultRowHeight = $spoutParams["default_row_height"] ?? null; - if ($defaultRowHeight !== null) $ssWriter->setDefaultRowHeight($defaultRowHeight); + if ($defaultRowHeight !== null) $ssOptions->DEFAULT_ROW_HEIGHT = $defaultRowHeight; $defaultRowStyle = $spoutParams["default_row_style"] ?? null; - if ($defaultRowStyle !== null) $ssWriter->setDefaultRowStyle($defaultRowStyle); + if ($defaultRowStyle !== null) $ssOptions->DEFAULT_ROW_STYLE = $defaultRowStyle; + self::apply_params($ssOptions, $spoutParams, $refParams); + $ssWriter = new $ssWriterClass($ssOptions); $ssWriter->writeToStream($this->getResource()); $this->ssType = $ssType; + $this->ssOptions = $ssOptions; $this->ssWriter = $ssWriter; $this->spoutParams = $spoutParams; $this->typeNumeric = boolval($params["type_numeric"] ?? static::TYPE_NUMERIC); @@ -213,7 +223,9 @@ class SpoutBuilder extends AbstractBuilder { /** @var int type de fichier généré */ protected int $ssType; - protected WriterMultiSheetsAbstract $ssWriter; + protected AbstractOptions $ssOptions; + + protected AbstractWriterMultiSheets $ssWriter; protected ?array $spoutParams; @@ -338,7 +350,8 @@ class SpoutBuilder extends AbstractBuilder { * Les lignes sont indexées sur 1 */ function mergeCells(int $topLeftCol, int $topLeftRow, int $bottomRightCol, int $bottomRightRow): void { - $this->ssWriter->mergeCells([$topLeftCol, $topLeftRow], [$bottomRightCol, $bottomRightRow]); + $sheet = $this->ssWriter->getCurrentSheet(); + $this->ssOptions->mergeCells($topLeftCol, $topLeftRow, $bottomRightCol, $bottomRightRow, $sheet->getIndex()); } protected function isNumeric($value): bool { @@ -356,10 +369,6 @@ class SpoutBuilder extends AbstractBuilder { $style ??= new Style(); $style->setFormat(self::DATETIME_FORMAT); return true; - } elseif (CellTypeHelper::isDateTimeOrDateInterval($value)) { - $style ??= new Style(); - $style->setFormat(self::DATE_FORMAT); - return true; } if (!is_string($value) || !$this->typeDate) return false; if (DateTime::isa_datetime($value, true)) { @@ -401,16 +410,14 @@ class SpoutBuilder extends AbstractBuilder { $style = $colStyles[$key] ?? null; self::ensure_style($style); if ($col === null || $col === "") { - $type = Cell::TYPE_EMPTY; + $cell = new EmptyCell(null, $style); } elseif ($this->isNumeric($col)) { - $type = Cell::TYPE_NUMERIC; + $cell = new NumericCell($col, $style); } elseif ($this->isDate($col, $style)) { - $type = Cell::TYPE_DATE; + $cell = new DateTimeCell($col, $style); } else { - $type = Cell::TYPE_STRING; + $cell = new StringCell($col, $style); } - $cell = WriterEntityFactory::createCell($col, $style); - $cell->setType($type); $cells[] = $cell; } @@ -421,7 +428,7 @@ class SpoutBuilder extends AbstractBuilder { } $rowStyle ??= $oddStyle; self::ensure_style($rowStyle); - $row = WriterEntityFactory::createRow($cells, $rowStyle); + $row = new Row($cells, $rowStyle); self::apply_params($row, $rowParams, ref_builder::ROW_PARAMS); $mergeCells = $rowParams["merge_cells"] ?? null; diff --git a/src/ref/ext/spout/ref_builder.php b/src/ref/ext/spout/ref_builder.php index 9bc7701..e84cfaa 100644 --- a/src/ref/ext/spout/ref_builder.php +++ b/src/ref/ext/spout/ref_builder.php @@ -82,6 +82,7 @@ class ref_builder { "align" => "string", "valign" => "string", "wrap" => "bool", + "rotation" => "int", "format" => "string", "border" => [ "top" => ["color" => "string", "width" => "string", "style" => "string"], @@ -89,5 +90,6 @@ class ref_builder { "bottom" => ["color" => "string", "width" => "string", "style" => "string"], "left" => ["color" => "string", "width" => "string", "style" => "string"], ], + "autofit" => "bool", ]; } diff --git a/src/ref/ext/spout/ref_builder_xlsx.php b/src/ref/ext/spout/ref_builder_xlsx.php index 60bd011..fe85dff 100644 --- a/src/ref/ext/spout/ref_builder_xlsx.php +++ b/src/ref/ext/spout/ref_builder_xlsx.php @@ -1,16 +1,43 @@ setPageSetup" => [ + PageSetup::class, + "page_orientation" => "string", + "page_size" => "string", + "fit_to_height" => "bool", + "fit_to_width" => "bool", + "page_order" => "string", + ], + "->setPageMargin" => [ + PageMargin::class, + "top" => "float", + "right" => "float", + "bottom" => "float", + "left" => "float", + "header" => "float", + "footer" => "float", + ], + "->setHeaderFooter" => [ + HeaderFooter::class, + "odd_header" => "string", + "odd_footer" => "string", + "even_header" => "string", + "even_footer" => "string", + "different_odd_even" => "bool", + ], + ]; + const PARAMS_SHEET = [ + ...parent::PARAMS_SHEET, "view" => self::PARAMS_SHEET_VIEW, - # copie de parent::SHEET - "->setName" => ["string"], - "->setIsVisible" => ["bool"], - "header_style" => self::STYLE, - "odd_style" => self::STYLE, - "even_style" => self::STYLE, - "different_odd_even" => "bool", ]; const PARAMS_SHEET_VIEW = [