122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nur\sery\ext\spreadsheet;
 | 
						|
 | 
						|
use nur\sery\cl;
 | 
						|
use nur\sery\file\csv\AbstractReader;
 | 
						|
use OpenSpout\Reader\Common\Creator\ReaderEntityFactory;
 | 
						|
 | 
						|
class SpoutReader extends AbstractReader {
 | 
						|
  /** @var string|int|null nom de la feuille depuis laquelle lire */
 | 
						|
  const WSNAME = null;
 | 
						|
 | 
						|
  function __construct($input, ?array $params=null) {
 | 
						|
    parent::__construct($input, $params);
 | 
						|
    $this->ssType = $params["ss_type"] ?? null;
 | 
						|
    $this->allSheets = $params["all_sheets"] ?? true;
 | 
						|
    $wsname = static::WSNAME;
 | 
						|
    if ($params !== null && array_key_exists("wsname", $params)) {
 | 
						|
      # spécifié par l'utilisateur: $allSheets = false
 | 
						|
      $this->setWsname($params["wsname"]);
 | 
						|
    } elseif ($wsname !== null) {
 | 
						|
      # valeur non nulle de la classe: $allSheets = false
 | 
						|
      $this->setWsname($wsname);
 | 
						|
    } else {
 | 
						|
      # pas de valeur définie dans la classe, laisser $allSheets à sa valeur
 | 
						|
      # actuelle
 | 
						|
      $this->wsname = null;
 | 
						|
    }
 | 
						|
    $this->includeWsnames = cl::withn($params["include_wsnames"] ?? null);
 | 
						|
    $this->excludeWsnames = cl::withn($params["exclude_wsnames"] ?? null);
 | 
						|
  }
 | 
						|
 | 
						|
  protected ?string $ssType;
 | 
						|
 | 
						|
  /** @var bool faut-il retourner les lignes de toutes les feuilles? */
 | 
						|
  protected bool $allSheets;
 | 
						|
 | 
						|
  function setAllSheets(bool $allSheets=true): self {
 | 
						|
    $this->allSheets = $allSheets;
 | 
						|
    return $this;
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * @var array|null si non null, liste de feuilles à inclure. n'est pris en
 | 
						|
   * compte que si $allSheets===true
 | 
						|
   */
 | 
						|
  protected ?array $includeWsnames;
 | 
						|
 | 
						|
  /**
 | 
						|
   * @var array|null si non null, liste de feuilles à exclure. n'est pris en
 | 
						|
   *  compte que si $allSheets===true
 | 
						|
   */
 | 
						|
  protected ?array $excludeWsnames;
 | 
						|
 | 
						|
  protected $wsname;
 | 
						|
 | 
						|
  /**
 | 
						|
   * @param string|int|null $wsname l'unique feuille à sélectionner
 | 
						|
   *
 | 
						|
   * NB: appeler cette méthode réinitialise $allSheets à false
 | 
						|
   */
 | 
						|
  function setWsname($wsname): self {
 | 
						|
    $this->wsname = $wsname;
 | 
						|
    $this->allSheets = true;
 | 
						|
    return $this;
 | 
						|
  }
 | 
						|
 | 
						|
  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 {
 | 
						|
      $allSheets = $this->allSheets;
 | 
						|
      $includeWsnames = $this->includeWsnames;
 | 
						|
      $excludeWsnames = $this->excludeWsnames;
 | 
						|
      $wsname = $this->wsname;
 | 
						|
      $first = true;
 | 
						|
      foreach ($ss->getSheetIterator() as $ws) {
 | 
						|
        if ($allSheets) {
 | 
						|
          $wsname = $ws->getName();
 | 
						|
          $found = ($includeWsnames === null || in_array($wsname, $includeWsnames))
 | 
						|
            && ($excludeWsnames === null || !in_array($wsname, $excludeWsnames));
 | 
						|
        } else {
 | 
						|
          $found = $wsname === null || $wsname === $ws->getName();
 | 
						|
        }
 | 
						|
        if ($found) {
 | 
						|
          if ($first) {
 | 
						|
            $first = false;
 | 
						|
          } else {
 | 
						|
            yield null;
 | 
						|
            # on garde le même schéma le cas échéant, mais supprimer headers
 | 
						|
            # pour permettre son recalcul
 | 
						|
            $this->headers = null;
 | 
						|
          }
 | 
						|
          $this->isrc = $this->idest = 0;
 | 
						|
          foreach ($ws->getRowIterator() as $row) {
 | 
						|
            $row = $row->toArray();
 | 
						|
            foreach ($row as &$col) {
 | 
						|
              $this->verifixCol($col);
 | 
						|
            }; unset($col);
 | 
						|
            if ($this->cook($row)) {
 | 
						|
              yield $row;
 | 
						|
              $this->idest++;
 | 
						|
            }
 | 
						|
            $this->isrc++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } finally {
 | 
						|
      $ss->close();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |