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