nur-sery/src/file/csv/SsReader.php

121 lines
4.2 KiB
PHP

<?php
namespace nur\sery\file\csv;
use nur\sery\cl;
use nur\sery\ext\spreadsheet\wsutils;
use nur\sery\file\web\Upload;
use nur\sery\php\time\Date;
use nur\sery\php\time\DateTime;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class SsReader extends AbstractReader {
use TAbstractReader;
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 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;
}
/** @var string|int|null */
protected $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++;
}
}
}