120 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			4.2 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 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|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++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |