modifs.mineures sans commentaires
This commit is contained in:
parent
db79a94b1d
commit
0e7c33f22d
|
@ -4,8 +4,12 @@ namespace nur\sery\ext\spreadsheet;
|
|||
use nur\sery\file\csv\AbstractBuilder;
|
||||
use nur\sery\file\csv\TAbstractBuilder;
|
||||
use nur\sery\os\path;
|
||||
use nur\sery\php\time\Date;
|
||||
use nur\sery\php\time\DateTime;
|
||||
use nur\sery\web\http;
|
||||
use OpenSpout\Common\Entity\Cell;
|
||||
use OpenSpout\Common\Entity\Style\Style;
|
||||
use OpenSpout\Common\Helper\CellTypeHelper;
|
||||
use OpenSpout\Writer\Common\Creator\WriterEntityFactory;
|
||||
use OpenSpout\Writer\WriterMultiSheetsAbstract;
|
||||
use OpenSpout\Writer\XLSX\Entity\SheetView;
|
||||
|
@ -13,28 +17,51 @@ use OpenSpout\Writer\XLSX\Entity\SheetView;
|
|||
class SpoutBuilder extends AbstractBuilder {
|
||||
use TAbstractBuilder;
|
||||
|
||||
const DATE_FORMAT = "mm/dd/yyyy";
|
||||
|
||||
const DATETIME_FORMAT = "mm/dd/yyyy hh:mm:ss";
|
||||
|
||||
/** @var string|int|null nom de la feuille dans laquelle écrire */
|
||||
const WSNAME = null;
|
||||
|
||||
function __construct(?string $output, ?array $params=null) {
|
||||
parent::__construct($output, $params);
|
||||
$ssType = $params["ss_type"] ?? null;
|
||||
if ($ssType === null) {
|
||||
switch (path::ext($this->output)) {
|
||||
case ".ods":
|
||||
$ss = WriterEntityFactory::createODSWriter();
|
||||
$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;
|
||||
|
@ -60,14 +87,53 @@ class SpoutBuilder extends AbstractBuilder {
|
|||
return $this;
|
||||
}
|
||||
|
||||
function _write(array $row): void {
|
||||
$row = WriterEntityFactory::createRowFromArray($row);
|
||||
if ($this->rowStyle === self::STYLE_HEADER) {
|
||||
$row->setStyle((new Style())
|
||||
->setFontBold()
|
||||
);
|
||||
protected function isNumeric($value): bool {
|
||||
if ($this->parseNumeric && is_numeric($value)) return true;
|
||||
if (!is_string($value) && is_numeric($value)) return true;
|
||||
return false;
|
||||
}
|
||||
$this->ss->addRow($row);
|
||||
|
||||
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 {
|
||||
|
@ -90,6 +156,7 @@ class SpoutBuilder extends AbstractBuilder {
|
|||
}
|
||||
|
||||
function _sendFile(): int {
|
||||
$this->ss->close();
|
||||
$this->rewind();
|
||||
$this->sendHeaders();
|
||||
return $this->fpassthru();
|
||||
|
|
|
@ -11,9 +11,12 @@ class SpoutReader extends AbstractReader {
|
|||
|
||||
function __construct($input, ?array $params=null) {
|
||||
parent::__construct($input, $params);
|
||||
$this->ssType = $params["ss_type"] ?? null;
|
||||
$this->wsname = $params["wsname"] ?? static::WSNAME;
|
||||
}
|
||||
|
||||
protected ?string $ssType;
|
||||
|
||||
protected $wsname;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +28,18 @@ class SpoutReader extends AbstractReader {
|
|||
}
|
||||
|
||||
function getIterator() {
|
||||
switch ($this->ssType) {
|
||||
case "ods":
|
||||
$ss = ReaderEntityFactory::createODSReader();
|
||||
break;
|
||||
case "xlsx":
|
||||
$ss = ReaderEntityFactory::createXLSXReader();
|
||||
break;
|
||||
default:
|
||||
$ss = ReaderEntityFactory::createReaderFromFile($this->input);
|
||||
break;
|
||||
}
|
||||
$ss->open($this->input);
|
||||
try {
|
||||
$found = false;
|
||||
foreach ($ss->getSheetIterator() as $ws) {
|
||||
|
|
|
@ -1,30 +1,57 @@
|
|||
<?php
|
||||
namespace nur\sery\file\csv;
|
||||
|
||||
use nur\sery\cl;
|
||||
use nur\sery\file\web\Upload;
|
||||
use nur\sery\os\path;
|
||||
use nur\sery\ValueException;
|
||||
|
||||
trait TAbstractBuilder {
|
||||
/** @param Upload|string|array $builder */
|
||||
static function with($builder): IBuilder {
|
||||
static function with($builder, ?array $params=null): IBuilder {
|
||||
if ($builder instanceof self) return $builder;
|
||||
$class = null;
|
||||
if ($builder instanceof Upload) {
|
||||
# faire un builder dans le même format que le fichier uploadé
|
||||
if ($builder->isExt(".csv")) $class = CsvBuilder::class;
|
||||
else $class = static::class;
|
||||
return new $class($builder->name);
|
||||
if ($builder->isExt(".csv")) {
|
||||
$class = CsvBuilder::class;
|
||||
} else {
|
||||
$class = static::class;
|
||||
if ($builder->isExt(".ods")) {
|
||||
$params["ss_type"] = "ods";
|
||||
} else {
|
||||
$params["ss_type"] = "xlsx";
|
||||
}
|
||||
if (is_string($builder)) $builder = ["output" => $builder];
|
||||
if (!is_array($builder)) {
|
||||
}
|
||||
return new $class($builder->name, $params);
|
||||
}
|
||||
|
||||
if (is_string($builder)) {
|
||||
$params["output"] = $builder;
|
||||
} elseif (is_array($builder)) {
|
||||
$params = cl::merge($builder, $params);
|
||||
} elseif ($builder !== null) {
|
||||
throw ValueException::invalid_type($builder, self::class);
|
||||
}
|
||||
$input = $builder["output"] ?? null;
|
||||
if (is_string($input) && path::ext($input) === ".csv") {
|
||||
|
||||
$output = $params["output"] ?? null;
|
||||
$ssType = null;
|
||||
if (is_string($output)) {
|
||||
switch (path::ext($output)) {
|
||||
case ".csv":
|
||||
$class = CsvBuilder::class;
|
||||
break;
|
||||
case ".ods":
|
||||
$ssType = "ods";
|
||||
break;
|
||||
case ".xlsx":
|
||||
default:
|
||||
$ssType = "xlsx";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$params["ss_type"] = $ssType;
|
||||
if ($class === null) $class = static::class;
|
||||
return new $class(null, $builder);
|
||||
return new $class(null, $params);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,16 @@ trait TAbstractReader {
|
|||
if ($reader instanceof self) return $reader;
|
||||
$class = null;
|
||||
if ($reader instanceof Upload) {
|
||||
if ($reader->isExt(".csv")) $class = CsvReader::class;
|
||||
else $class = static::class;
|
||||
if ($reader->isExt(".csv")) {
|
||||
$class = CsvReader::class;
|
||||
} else {
|
||||
$class = static::class;
|
||||
if ($reader->isExt(".ods")) {
|
||||
$params["ss_type"] = "ods";
|
||||
} else {
|
||||
$params["ss_type"] = "xlsx";
|
||||
}
|
||||
}
|
||||
return new $class($reader->tmpName, $params);
|
||||
}
|
||||
|
||||
|
@ -26,9 +34,22 @@ trait TAbstractReader {
|
|||
}
|
||||
|
||||
$input = $params["input"] ?? null;
|
||||
if (is_string($input) && path::ext($input) === ".csv") {
|
||||
$ssType = null;
|
||||
if (is_string($input)) {
|
||||
switch (path::ext($input)) {
|
||||
case ".csv":
|
||||
$class = CsvReader::class;
|
||||
break;
|
||||
case ".ods":
|
||||
$ssType = "ods";
|
||||
break;
|
||||
case ".xlsx":
|
||||
default:
|
||||
$ssType = "xlsx";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$params["ss_type"] = $ssType;
|
||||
if ($class === null) $class = static::class;
|
||||
return new $class(null, $params);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue