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();
|
|
}
|
|
}
|
|
}
|