| 1 |
<?php |
| 2 |
|
| 3 |
namespace TablePress\PhpOffice\PhpSpreadsheet\Reader\Xlsx; |
| 4 |
|
| 5 |
use TablePress\PhpOffice\PhpSpreadsheet\Style\Style; |
| 6 |
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Table; |
| 7 |
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle; |
| 8 |
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle; |
| 9 |
use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; |
| 10 |
use SimpleXMLElement; |
| 11 |
|
| 12 |
class TableReader |
| 13 |
{ |
| 14 |
private Worksheet $worksheet; |
| 15 |
|
| 16 |
private SimpleXMLElement $tableXml; |
| 17 |
|
| 18 |
/** @var mixed[]|SimpleXMLElement */ |
| 19 |
private $tableAttributes; |
| 20 |
|
| 21 |
public function __construct(Worksheet $workSheet, SimpleXMLElement $tableXml) |
| 22 |
{ |
| 23 |
$this->worksheet = $workSheet; |
| 24 |
$this->tableXml = $tableXml; |
| 25 |
} |
| 26 |
|
| 27 |
/** |
| 28 |
* Loads Table into the Worksheet. |
| 29 |
* |
| 30 |
* @param TableDxfsStyle[] $tableStyles |
| 31 |
* @param Style[] $dxfs |
| 32 |
*/ |
| 33 |
public function load(array $tableStyles, array $dxfs): void |
| 34 |
{ |
| 35 |
$this->tableAttributes = $this->tableXml->attributes() ?? []; |
| 36 |
// Remove all "$" in the table range |
| 37 |
$tableRange = (string) preg_replace('/\$/', '', (string) ($this->tableAttributes['ref'] ?? '')); |
| 38 |
if (str_contains($tableRange, ':')) { |
| 39 |
$this->readTable($tableRange, $tableStyles, $dxfs); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
/** |
| 44 |
* Read Table from xml. |
| 45 |
* |
| 46 |
* @param TableDxfsStyle[] $tableStyles |
| 47 |
* @param Style[] $dxfs |
| 48 |
*/ |
| 49 |
private function readTable(string $tableRange, array $tableStyles, array $dxfs): void |
| 50 |
{ |
| 51 |
$table = new Table($tableRange); |
| 52 |
/** @var string[] */ |
| 53 |
$attributes = $this->tableAttributes; |
| 54 |
$table->setName((string) ($attributes['displayName'] ?? '')); |
| 55 |
$table->setShowHeaderRow(((string) ($attributes['headerRowCount'] ?? '')) !== '0'); |
| 56 |
$table->setShowTotalsRow(((string) ($attributes['totalsRowCount'] ?? '')) === '1'); |
| 57 |
|
| 58 |
$this->readTableAutoFilter($table, $this->tableXml->autoFilter); |
| 59 |
$this->readTableColumns($table, $this->tableXml->tableColumns); |
| 60 |
$this->readTableStyle($table, $this->tableXml->tableStyleInfo, $tableStyles, $dxfs); |
| 61 |
|
| 62 |
(new AutoFilter($table, $this->tableXml))->load(); |
| 63 |
$this->worksheet->addTable($table); |
| 64 |
} |
| 65 |
|
| 66 |
/** |
| 67 |
* Reads TableAutoFilter from xml. |
| 68 |
*/ |
| 69 |
private function readTableAutoFilter(Table $table, SimpleXMLElement $autoFilterXml): void |
| 70 |
{ |
| 71 |
if ($autoFilterXml->filterColumn === null) { |
| 72 |
$table->setAllowFilter(false); |
| 73 |
|
| 74 |
return; |
| 75 |
} |
| 76 |
|
| 77 |
foreach ($autoFilterXml->filterColumn as $filterColumn) { |
| 78 |
/** @var SimpleXMLElement */ |
| 79 |
$attributes = $filterColumn->attributes() ?? ['colId' => 0, 'hiddenButton' => 0]; |
| 80 |
$column = $table->getColumnByOffset((int) $attributes['colId']); |
| 81 |
$column->setShowFilterButton(((string) $attributes['hiddenButton']) !== '1'); |
| 82 |
} |
| 83 |
} |
| 84 |
|
| 85 |
/** |
| 86 |
* Reads TableColumns from xml. |
| 87 |
*/ |
| 88 |
private function readTableColumns(Table $table, SimpleXMLElement $tableColumnsXml): void |
| 89 |
{ |
| 90 |
$offset = 0; |
| 91 |
foreach ($tableColumnsXml->tableColumn as $tableColumn) { |
| 92 |
/** @var SimpleXMLElement */ |
| 93 |
$attributes = $tableColumn->attributes() ?? ['totalsRowLabel' => 0, 'totalsRowFunction' => 0]; |
| 94 |
$column = $table->getColumnByOffset($offset++); |
| 95 |
|
| 96 |
if ($table->getShowTotalsRow()) { |
| 97 |
if ($attributes['totalsRowLabel']) { |
| 98 |
$column->setTotalsRowLabel((string) $attributes['totalsRowLabel']); |
| 99 |
} |
| 100 |
|
| 101 |
if ($attributes['totalsRowFunction']) { |
| 102 |
$column->setTotalsRowFunction((string) $attributes['totalsRowFunction']); |
| 103 |
} |
| 104 |
} |
| 105 |
|
| 106 |
if ($tableColumn->calculatedColumnFormula) { |
| 107 |
$column->setColumnFormula((string) $tableColumn->calculatedColumnFormula); |
| 108 |
} |
| 109 |
} |
| 110 |
} |
| 111 |
|
| 112 |
/** |
| 113 |
* Reads TableStyle from xml. |
| 114 |
* |
| 115 |
* @param TableDxfsStyle[] $tableStyles |
| 116 |
* @param Style[] $dxfs |
| 117 |
*/ |
| 118 |
private function readTableStyle(Table $table, SimpleXMLElement $tableStyleInfoXml, array $tableStyles, array $dxfs): void |
| 119 |
{ |
| 120 |
$tableStyle = new TableStyle(); |
| 121 |
$attributes = $tableStyleInfoXml->attributes(); |
| 122 |
if ($attributes !== null) { |
| 123 |
$tableStyle->setTheme((string) $attributes['name']); |
| 124 |
$tableStyle->setShowRowStripes((string) $attributes['showRowStripes'] === '1'); |
| 125 |
$tableStyle->setShowColumnStripes((string) $attributes['showColumnStripes'] === '1'); |
| 126 |
$tableStyle->setShowFirstColumn((string) $attributes['showFirstColumn'] === '1'); |
| 127 |
$tableStyle->setShowLastColumn((string) $attributes['showLastColumn'] === '1'); |
| 128 |
|
| 129 |
foreach ($tableStyles as $style) { |
| 130 |
if ($style->getName() === (string) $attributes['name']) { |
| 131 |
$tableStyle->setTableDxfsStyle($style, $dxfs); |
| 132 |
} |
| 133 |
} |
| 134 |
} |
| 135 |
$table->setStyle($tableStyle); |
| 136 |
} |
| 137 |
} |
| 138 |
|