diff --git a/README.md b/README.md index 390d401..90fc4bc 100644 --- a/README.md +++ b/README.md @@ -624,6 +624,76 @@ $validations = $sheet->getDataValidations(); */ ``` +## Column Widths +Retrieve the width of a specific column in a sheet: + +```php +$excel = Excel::open($file); +$sheet = $excel->selectSheet('SheetName'); + +// Get the width of column 1 (column 'A') +$columnWidth = $sheet->getColumnWidth(1); + +echo $columnWidth; // Example: 11.85 +``` + +## Row Heights +Retrieve the height of a specific row in a sheet: + +```php +$excel = Excel::open($file); +$sheet = $excel->selectSheet('SheetName'); + +// Get the height of row 1 +$rowHeight = $sheet->getRowHeight(1); + +echo $rowHeight; // Example: 15 +``` + +## Freeze Pane Configuration +Retrieve the freeze pane configuration for a sheet: + +```php +$excel = Excel::open($file); +$sheet = $excel->selectSheet('SheetName'); + +// Get the freeze pane configuration +$freezePaneConfig = $sheet->getFreezePaneConfig(); + +print_r($freezePaneConfig); +/* +Example Output: +Array +( + [xSplit] => 0 + [ySplit] => 1 + [topLeftCell] => 'A2' +) +*/ +``` + +## Tab Color Configuration +Retrieve the tab color settings for a sheet: + +```php +Copy code +$excel = Excel::open($file); +$sheet = $excel->selectSheet('SheetName'); + +// Get the tab color configuration +$tabColorConfig = $sheet->getTabColorConfiguration(); + +print_r($tabColorConfig); +/* +Example Output: +Array +( + [theme] => '2' + [tint] => '-0.499984740745262' +) +*/ +``` + ## Support merged cells You can use the following methods: @@ -664,6 +734,9 @@ if ($sheet->isMerged('B3')) { * ```firstCol()``` -- The first column letter * ```readFirstRow()``` -- Returns values of cells of 1st row as array * ```readFirstRowWithStyles()``` -- Returns values and styles of cells of 1st row as array +* ```getColumnWidth(int)``` -- Returns the width of a given column number +* ```getFreezePaneConfig()``` -- Returns an array containing freeze pane configuration +* ```getTabColorConfiguration()``` -- Returns an array containing tab color configuration ## Do you want to support FastExcelReader? diff --git a/demo/files/demo-07-size-freeze-tabs.xlsx b/demo/files/demo-07-size-freeze-tabs.xlsx new file mode 100644 index 0000000..5dfcc6a Binary files /dev/null and b/demo/files/demo-07-size-freeze-tabs.xlsx differ diff --git a/src/FastExcelReader/Sheet.php b/src/FastExcelReader/Sheet.php index ba3554b..0817a7a 100644 --- a/src/FastExcelReader/Sheet.php +++ b/src/FastExcelReader/Sheet.php @@ -68,6 +68,14 @@ class Sheet implements InterfaceSheetReader */ protected ?array $validations = null; + protected ?array $rowHeights = null; + + protected ?array $colWidths = null; + + protected float $defaultRowHeight = 15.0; + + protected ?array $tabProperties = null; + public function __construct($sheetName, $sheetId, $file, $path, $excel) { $this->excel = $excel; @@ -1761,4 +1769,166 @@ protected function parseExtendedDataValidation(InterfaceXmlReader $xmlReader): a 'formula2' => $formula2 ]; } -} + + public function setDefaultRowHeight(float $rowHeight): void + { + $this->defaultRowHeight = $rowHeight; + } + + /** + * Parses and retrieves column widths and row heights from the sheet XML. + * + * @return void + */ + protected function extractColumnWidthsAndRowHeights(): void + { + $this->colWidths = []; + $this->rowHeights = []; + + $xmlReader = $this->getReader(); + $xmlReader->openZip($this->pathInZip); + + while ($xmlReader->read()) { + if ($xmlReader->nodeType === \XMLReader::ELEMENT) { + // Extract column width + if ($xmlReader->name === 'col') { + $min = (int)$xmlReader->getAttribute('min'); + $max = (int)$xmlReader->getAttribute('max'); + $width = (float)$xmlReader->getAttribute('width'); + + for ($i = $min; $i <= $max; $i++) { + $this->colWidths[$i] = $width; + } + } + // Extract row height + elseif ($xmlReader->name === 'row') { + $rowIndex = (int)$xmlReader->getAttribute('r'); + $height = $xmlReader->getAttribute('ht') ? (float)$xmlReader->getAttribute('ht') : $this->defaultRowHeight; + $this->rowHeights[$rowIndex] = $height; + } + } + } + + $xmlReader->close(); + } + + /** + * Returns column width for a specific column number. + * + * @param int $colNumber + * @return float|null + */ + public function getColumnWidth(int $colNumber): ?float + { + if ($this->colWidths === null) { + $this->extractColumnWidthsAndRowHeights(); + } + return $this->colWidths[$colNumber] ?? null; + } + + /** + * Returns row height for a specific row number. + * + * @param int $rowNumber + * @return float|null + */ + public function getRowHeight(int $rowNumber): ?float + { + if ($this->rowHeights === null) { + $this->extractColumnWidthsAndRowHeights(); + } + return $this->rowHeights[$rowNumber] ?? null; + } + + /** + * Parses and retrieves frozen pane configuration from the sheet XML. + * + * @return array|null + */ + public function getFreezePaneConfig(): ?array + { + $xmlReader = $this->getReader(); + $xmlReader->openZip($this->pathInZip); + + $freezePane = null; + + while ($xmlReader->read()) { + if ($xmlReader->nodeType === \XMLReader::ELEMENT && $xmlReader->name === 'pane') { + $xSplit = (int)$xmlReader->getAttribute('xSplit'); + $ySplit = (int)$xmlReader->getAttribute('ySplit'); + $topLeftCell = $xmlReader->getAttribute('topLeftCell'); + + $freezePane = [ + 'xSplit' => $xSplit, + 'ySplit' => $ySplit, + 'topLeftCell' => $topLeftCell, + ]; + break; + } + } + + $xmlReader->close(); + return $freezePane; + } + + /** + * Extracts the tab properties from the sheet XML + * + * @return void + */ + protected function _readTabProperties(): void + { + if ($this->tabProperties !== null) { + return; + } + + $this->tabProperties = [ + 'color' => null, + ]; + + $xmlReader = $this->getReader(); + $xmlReader->openZip($this->pathInZip); + + while ($xmlReader->read()) { + if ($xmlReader->nodeType === \XMLReader::ELEMENT && $xmlReader->name === 'sheetPr') { + while ($xmlReader->read()) { + if ($xmlReader->nodeType === \XMLReader::ELEMENT && $xmlReader->name === 'tabColor') { + $this->tabProperties['color'] = [ + 'rgb' => $xmlReader->getAttribute('rgb'), + 'theme' => $xmlReader->getAttribute('theme'), + 'tint' => $xmlReader->getAttribute('tint'), + 'indexed' => $xmlReader->getAttribute('indexed'), + ]; + + $this->tabProperties['color'] = array_filter( + $this->tabProperties['color'], + static fn($value) => $value !== null + ); + break; + } + if ($xmlReader->nodeType === \XMLReader::END_ELEMENT && $xmlReader->name === 'sheetPr') { + break; + } + } + break; + } + } + + $xmlReader->close(); + } + + /** + * Returns the tab color configuration of the sheet + * Contains any of: rgb, theme, tint, indexed + * + * @return array|null + */ + public function getTabColorConfiguration(): ?array + { + if ($this->tabProperties === null) { + $this->_readTabProperties(); + } + + return $this->tabProperties['color']; + } +} \ No newline at end of file diff --git a/tests/FastExcelReaderTest.php b/tests/FastExcelReaderTest.php index 79f6605..b6bcb47 100644 --- a/tests/FastExcelReaderTest.php +++ b/tests/FastExcelReaderTest.php @@ -406,6 +406,52 @@ public function testFillRow() $this->assertEquals(['#' => 1, 'name' => 'James Bond', 'birthday' => -2205187200, 'random_int' => 4573], $rows[2]); } + public function testGetColumnWidth(): void + { + $file = self::DEMO_DIR . 'demo-07-size-freeze-tabs.xlsx'; + $excel = Excel::open($file); + $width_1 = $excel->selectSheet('report')->getColumnWidth(1); + $width_3 = $excel->selectSheet('report')->getColumnWidth(3); + + $this->assertEquals(11.85546875, $width_1); + $this->assertEquals(27.85546875, $width_3); + } + + public function testGetRowHeight(): void + { + $file = self::DEMO_DIR . 'demo-07-size-freeze-tabs.xlsx'; + $excel = Excel::open($file); + $height_1 = $excel->selectSheet('report')->getRowHeight(1); + $height_3 = $excel->selectSheet('report')->getRowHeight(3); + + $this->assertEquals(15, $height_1); + $this->assertEquals(35.25, $height_3); + } + + public function testGetFreezePane(): void + { + $file = self::DEMO_DIR . 'demo-07-size-freeze-tabs.xlsx'; + $excel = Excel::open($file); + $freezePane = $excel->selectSheet('report')->getFreezePaneConfig(); + + $this->assertEquals([ + 'xSplit' => 0, + 'ySplit' => 1, + 'topLeftCell' => 'A2' + ], $freezePane); + } + + public function testGetTabColorConfig(): void + { + $file = self::DEMO_DIR . 'demo-07-size-freeze-tabs.xlsx'; + $excel = Excel::open($file); + $config = $excel->selectSheet('report')->getTabColorConfiguration(); + + $this->assertEquals([ + 'theme' => '2', + 'tint' => '-0.499984740745262' + ], $config); + } public function testRefPath() {