113 lines
2.9 KiB
PHP
113 lines
2.9 KiB
PHP
<?php
|
|
namespace nur\sery\ext\spreadsheet;
|
|
|
|
use nur\sery\file\csv\AbstractBuilder;
|
|
use nur\sery\file\csv\TAbstractBuilder;
|
|
use nur\sery\os\path;
|
|
use nur\sery\web\http;
|
|
use PhpOffice\PhpSpreadsheet\Cell\IValueBinder;
|
|
use PhpOffice\PhpSpreadsheet\Cell\StringValueBinder;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Ods;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
|
|
class PhpSpreadsheetBuilder extends AbstractBuilder {
|
|
use TAbstractBuilder;
|
|
|
|
/** @var string|int|null nom de la feuille dans laquelle écrire */
|
|
const WSNAME = null;
|
|
|
|
function __construct(?string $output, ?array $params=null) {
|
|
parent::__construct($output, $params);
|
|
$this->ss = new Spreadsheet();
|
|
$this->valueBinder = new StringValueBinder();
|
|
$this->setWsname($params["wsname"] ?? static::WSNAME);
|
|
}
|
|
|
|
protected Spreadsheet $ss;
|
|
|
|
protected IValueBinder $valueBinder;
|
|
|
|
protected ?Worksheet $ws;
|
|
|
|
protected int $nrow;
|
|
|
|
const STYLE_ROW = 0, STYLE_HEADER = 1;
|
|
|
|
protected int $rowStyle;
|
|
|
|
/**
|
|
* @param string|int|null $wsname
|
|
*/
|
|
function setWsname($wsname): self {
|
|
$ss = $this->ss;
|
|
$this->ws = null;
|
|
$this->nrow = 0;
|
|
$this->rowStyle = self::STYLE_ROW;
|
|
|
|
$ws = wsutils::get_ws($wsname, $ss);
|
|
if ($ws === null) {
|
|
$ws = $ss->createSheet()->setTitle($wsname);
|
|
$this->wroteHeaders = false;
|
|
} else {
|
|
$maxRow = wsutils::compute_max_coords($ws)[1];
|
|
$this->nrow = $maxRow - 1;
|
|
$this->wroteHeaders = $maxRow > 1;
|
|
}
|
|
$this->ws = $ws;
|
|
return $this;
|
|
}
|
|
|
|
function _write(array $row): void {
|
|
$ws = $this->ws;
|
|
$styleHeader = $this->rowStyle === self::STYLE_HEADER;
|
|
$nrow = ++$this->nrow;
|
|
$ncol = 1;
|
|
foreach ($row as $col) {
|
|
$ws->getCellByColumnAndRow($ncol++, $nrow)->setValue($col, $this->valueBinder);
|
|
}
|
|
if ($styleHeader) {
|
|
$ws->getStyle("$nrow:$nrow")->getFont()->setBold(true);
|
|
$maxcol = count($row);
|
|
for ($ncol = 1; $ncol <= $maxcol; $ncol++) {
|
|
$ws->getColumnDimensionByColumn($ncol)->setAutoSize(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
function writeHeaders(?array $headers=null): void {
|
|
$this->rowStyle = self::STYLE_HEADER;
|
|
parent::writeHeaders($headers);
|
|
$this->rowStyle = self::STYLE_ROW;
|
|
}
|
|
|
|
function _sendContentType(): void {
|
|
switch (path::ext($this->output)) {
|
|
case ".ods":
|
|
$contentType = "application/vnd.oasis.opendocument.spreadsheet";
|
|
break;
|
|
case ".xlsx":
|
|
default:
|
|
$contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
break;
|
|
}
|
|
http::content_type($contentType);
|
|
}
|
|
|
|
protected function _checkOk(): bool {
|
|
switch (path::ext($this->output)) {
|
|
case ".ods":
|
|
$writer = new Ods($this->ss);
|
|
break;
|
|
case ".xlsx":
|
|
default:
|
|
$writer = new Xlsx($this->ss);
|
|
break;
|
|
}
|
|
$writer->save($this->getResource());
|
|
$this->rewind();
|
|
return true;
|
|
}
|
|
}
|