118 lines
4.1 KiB
PHP
118 lines
4.1 KiB
PHP
<?php
|
|
namespace nur\sery\ext\spreadsheet;
|
|
|
|
use nur\sery\cl;
|
|
use nur\sery\file\csv\AbstractReader;
|
|
use nur\sery\file\csv\TAbstractReader;
|
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
|
|
|
class PhpSpreadsheetReader extends AbstractReader {
|
|
const DATETIME_FORMAT = 'dd/mm/yyyy hh:mm:ss';
|
|
const DATE_FORMAT = 'dd/mm/yyyy';
|
|
const TIME_FORMAT = 'hh:mm:ss';
|
|
const FORMAT_MAPPINGS = [
|
|
'mm/dd hh' => self::DATETIME_FORMAT,
|
|
'dd/mm hh' => self::DATETIME_FORMAT,
|
|
'mm/dd hh:mm' => self::DATETIME_FORMAT,
|
|
'dd/mm hh:mm' => self::DATETIME_FORMAT,
|
|
'mm/dd hh:mm:ss' => self::DATETIME_FORMAT,
|
|
'dd/mm hh:mm:ss' => self::DATETIME_FORMAT,
|
|
'mm/dd/yyyy hh' => self::DATETIME_FORMAT,
|
|
'dd/mm/yyyy hh' => self::DATETIME_FORMAT,
|
|
'mm/dd/yyyy hh:mm' => self::DATETIME_FORMAT,
|
|
'dd/mm/yyyy hh:mm' => self::DATETIME_FORMAT,
|
|
'mm/dd/yyyy hh:mm:ss' => self::DATETIME_FORMAT,
|
|
'dd/mm/yyyy hh:mm:ss' => self::DATETIME_FORMAT,
|
|
'yyyy/mm/dd hh' => self::DATETIME_FORMAT,
|
|
'yyyy/mm/dd hh:mm' => self::DATETIME_FORMAT,
|
|
'yyyy/mm/dd hh:mm:ss' => self::DATETIME_FORMAT,
|
|
|
|
'mm/dd' => self::DATE_FORMAT,
|
|
'dd/mm' => self::DATE_FORMAT,
|
|
'mm/dd/yyyy' => self::DATE_FORMAT,
|
|
'dd/mm/yyyy' => self::DATE_FORMAT,
|
|
'yyyy/mm/dd' => self::DATE_FORMAT,
|
|
'mm/yyyy' => self::DATE_FORMAT,
|
|
|
|
'hh AM/PM' => self::TIME_FORMAT,
|
|
'hh:mm AM/PM' => self::TIME_FORMAT,
|
|
'hh:mm:ss AM/PM' => self::TIME_FORMAT,
|
|
'hh' => self::TIME_FORMAT,
|
|
'hh:mm' => self::TIME_FORMAT,
|
|
'hh:mm:ss' => self::TIME_FORMAT,
|
|
'[hh]:mm:ss' => self::TIME_FORMAT,
|
|
'mm:ss' => self::TIME_FORMAT,
|
|
];
|
|
|
|
/** @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->wsname = $params["wsname"] ?? static::WSNAME;
|
|
}
|
|
|
|
protected $wsname;
|
|
|
|
/**
|
|
* @param string|int|null $wsname
|
|
*/
|
|
function setWsname($wsname): self {
|
|
$this->wsname = $wsname;
|
|
return $this;
|
|
}
|
|
|
|
function getIterator() {
|
|
$ss = IOFactory::load($this->input);
|
|
$ws = wsutils::get_ws($this->wsname, $ss);
|
|
|
|
[$nbCols, $nbRows] = wsutils::compute_max_coords($ws);
|
|
$this->isrc = $this->idest = 0;
|
|
for ($nrow = 1; $nrow <= $nbRows; $nrow++) {
|
|
$row = [];
|
|
for ($ncol = 1; $ncol <= $nbCols; $ncol++) {
|
|
if ($ws->cellExistsByColumnAndRow($ncol, $nrow)) {
|
|
$cell = $ws->getCellByColumnAndRow($ncol, $nrow);
|
|
$col = $cell->getValue();
|
|
if ($col instanceof RichText) {
|
|
$col = $col->getPlainText();
|
|
} else {
|
|
$dataType = $cell->getDataType();
|
|
if ($dataType == DataType::TYPE_NUMERIC || $dataType == DataType::TYPE_FORMULA) {
|
|
# si c'est un format date, le forcer à une valeur standard
|
|
$origFormatCode = $cell->getStyle()->getNumberFormat()->getFormatCode();
|
|
if (strpbrk($origFormatCode, "ymdhs") !== false) {
|
|
$formatCode = $origFormatCode;
|
|
$formatCode = preg_replace('/y+/', "yyyy", $formatCode);
|
|
$formatCode = preg_replace('/m+/', "mm", $formatCode);
|
|
$formatCode = preg_replace('/d+/', "dd", $formatCode);
|
|
$formatCode = preg_replace('/h+/', "hh", $formatCode);
|
|
$formatCode = preg_replace('/s+/', "ss", $formatCode);
|
|
$formatCode = preg_replace('/-+/', "/", $formatCode);
|
|
$formatCode = preg_replace('/\\\\ /', " ", $formatCode);
|
|
$formatCode = preg_replace('/;@$/', "", $formatCode);
|
|
$formatCode = cl::get(self::FORMAT_MAPPINGS, $formatCode, $formatCode);
|
|
if ($formatCode !== $origFormatCode) {
|
|
$cell->getStyle()->getNumberFormat()->setFormatCode($formatCode);
|
|
}
|
|
}
|
|
}
|
|
$col = $cell->getFormattedValue();
|
|
$this->verifixCol($col);
|
|
}
|
|
} else {
|
|
$col = null;
|
|
}
|
|
$row[] = $col;
|
|
}
|
|
if ($this->cook($row)) {
|
|
yield $row;
|
|
$this->idest++;
|
|
}
|
|
$this->isrc++;
|
|
}
|
|
}
|
|
}
|