output)) { case ".ods": $ssType = "ods"; break; case ".xlsx": default: $ssType = "xlsx"; break; } } switch ($ssType) { case "ods": $ss = WriterEntityFactory::createODSWriter(); break; case "xlsx": default: $ss = WriterEntityFactory::createXLSXWriter(); break; } $ss->setDefaultColumnWidth(10.5); $ss->writeToStream($this->getResource()); $this->ss = $ss; $this->parseNumeric = boolval($params["parse_numeric"] ?? false); $this->parseDate = boolval($params["parse_date"] ?? true); $this->firstSheet = true; $this->setWsname($params["wsname"] ?? static::WSNAME); } protected WriterMultiSheetsAbstract $ss; protected bool $parseNumeric; protected bool $parseDate; const STYLE_ROW = 0, STYLE_HEADER = 1; protected int $rowStyle; protected bool $firstSheet; /** * @param string|int|null $wsname */ function setWsname($wsname): self { $ss = $this->ss; $this->rowStyle = self::STYLE_ROW; if ($this->firstSheet) { $this->firstSheet = false; $ws = $ss->getCurrentSheet(); } else { $ws = $ss->addNewSheetAndMakeItCurrent(); } if ($wsname !== null) $ws->setName($wsname); $ws->setSheetView((new SheetView()) ->setFreezeRow(2) ); return $this; } protected function isNumeric($value): bool { if ($this->parseNumeric && is_numeric($value)) return true; if (!is_string($value) && is_numeric($value)) return true; return false; } protected function isDate(&$value, &$style): bool { if (CellTypeHelper::isDateTimeOrDateInterval($value)) { $style = (new Style())->setFormat(self::DATE_FORMAT); return true; } if (!is_string($value)) return false; if (DateTime::isa_datetime($value, true)) { $value = new DateTime($value); $style = (new Style())->setFormat(self::DATETIME_FORMAT); return true; } if (DateTime::isa_date($value, true)) { $value = new Date($value); $style = (new Style())->setFormat(self::DATE_FORMAT); return true; } return false; } function _write(array $row): void { $cells = []; $rowStyle = null; foreach ($row as $col) { $style = null; if ($col === null || $col === "") { $type = Cell::TYPE_EMPTY; } elseif ($this->isNumeric($col)) { $type = Cell::TYPE_NUMERIC; } elseif ($this->isDate($col, $style)) { $type = Cell::TYPE_DATE; } else { $type = Cell::TYPE_STRING; } $cell = WriterEntityFactory::createCell($col, $style); $cell->setType($type); $cells[] = $cell; } if ($this->rowStyle === self::STYLE_HEADER) { $rowStyle = (new Style())->setFontBold(); } $this->ss->addRow(WriterEntityFactory::createRow($cells, $rowStyle)); } function writeHeaders(?array $headers=null): void { $this->rowStyle = self::STYLE_HEADER; parent::writeHeaders($headers); $this->rowStyle = self::STYLE_ROW; } function _sendContentType(): void { switch (path::ext($this->output)) { case ".ods": $contentType = "application/vnd.oasis.opendocument.spreadsheet"; break; case ".xlsx": default: $contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break; } http::content_type($contentType); } function _sendFile(): int { $this->ss->close(); $this->rewind(); $this->sendHeaders(); return $this->fpassthru(); } }