From 9e89f5736b6fa0aec3d731e9aa21d30ddbe6ac01 Mon Sep 17 00:00:00 2001 From: aVadim Date: Mon, 5 Aug 2024 20:23:29 +0300 Subject: [PATCH] * $sheet->setTabColor($color); * New Excel option - 'auto_convert_number'; * New Excel option - 'shared_string'; * New Excel option - 'locale'; --- CHANGELOG.md | 11 ++++++- README.md | 39 +++++++++++++++++++++++-- docs/01-workbook.md | 9 ++++++ docs/02-sheets.md | 1 + docs/05-charts.md | 2 +- src/FastExcelWriter/Excel.php | 7 +++++ src/FastExcelWriter/Sheet.php | 41 ++++++++++++++++++++++++++ src/FastExcelWriter/Writer/Writer.php | 42 ++++++++++++++++++++++----- 8 files changed, 140 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52152e2..69d9694 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ +## v.5.8 + +* $sheet->setTabColor($color); +* New Excel option - 'auto_convert_number'; +* New Excel option - 'shared_string'; +* New Excel option - 'locale'; + ## v.5.7 + * $sheet->addImage($cell, $path, \['hyperlink' => $url\]); * cell merge optimization ## v.5.6 + * Excel::setActiveSheet($name): Excel -- Set active (default) sheet by case-insensitive name * Sheet::isName($name): bool -- Case-insensitive name checking * Sheet::setPrintArea($range): Sheet @@ -77,7 +86,7 @@ Deprecated ## v.4.5 -* Supports workbook and sheet protection with/without passwords (see [Protection of workbook and sheets](/docs/05-protection.md) ) +* Supports workbook and sheet protection with/without passwords (see [Protection of workbook and sheets](/docs/06-protection.md) ) New methods for cells * Sheet::applyUnlock() diff --git a/README.md b/README.md index 69684cc..2216652 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ This library is designed to be lightweight, super-fast and requires minimal memo Jump To: * [Changes in version 4](#changes-in-version-4) * [Changes in version 5](#changes-in-version-5) +* [Important changes in version 5.8](#important-changes-in-version-58) * [Simple Example](#simple-example) * [Advanced Example](#advanced-example) * [Adding Notes](#adding-notes) @@ -66,7 +67,7 @@ Jump To: * [Group/outline rows and columns](/docs/02-sheets.md#groupoutline-rows-and-columns) * [Define Named Ranges](/docs/02-sheets.md#define-named-ranges) * [Freeze Panes and Autofilter](/docs/02-sheets.md#freeze-panes-and-autofilter) - * [Setting Active Cells](/docs/02-sheets.md#setting-active-cells) + * [Setting Active Sheet and Cells](/docs/02-sheets.md#setting-active-sheet-and-cells) * [Print Settings](/docs/02-sheets.md#print-settings) * [Writing](/docs/03-writing.md) * [Writing Row by Row vs Direct](/docs/03-writing.md#writing-row-by-row-vs-direct) @@ -82,7 +83,7 @@ Jump To: * [Row Styles](/docs/04-styles.md#row-styles) * [Column Styles](/docs/04-styles.md#column-styles) * [Other Columns Options](/docs/04-styles.md#other-columns-options) - * [Apply Styles (The Fluent Interface)](/docs/04-styles.md#apply-styles--the-fluent-interface-) + * [Apply Styles (The Fluent Interface)](/docs/04-styles.md#apply-styles-the-fluent-interface) * [Apply Borders](/docs/04-styles.md#apply-borders) * [Apply Fonts](/docs/04-styles.md#apply-fonts) * [Apply Colors](/docs/04-styles.md#apply-colors) @@ -119,6 +120,31 @@ composer require avadim/fast-excel-writer * The general news is Chart support +## Important changes in version 5.8 + +Before v.5.8 +```php +$sheet->writeCell(12345); // The number 12345 will be written into the cell +$sheet->writeCell('12345'); // The number 12345 will also be written here + +``` + +In version 5.8 and later +```php +$sheet->writeCell(12345); // The number 12345 will be written into the cell +$sheet->writeCell('12345'); // Here the string '12345' will be written into the cell + +``` +If you want to keep the previous behavior for backward compatibility, +you should use option 'auto_convert_number' when creating a workbook. +```php +$excel = Excel::create(['Sheet1'], ['auto_convert_number' => true]); +$sheet = $excel->sheet(); +$sheet->writeCell('12345'); // String '12345' will be automatically converted to a number + +``` + + ## Usage You can find usage examples below or in */demo* folder @@ -301,6 +327,15 @@ $sheet1->addImage('D4', 'path/to/file', ['width' => 150, 'height' => 150, 'hyper ``` +## Shared Strings + +By default, strings are written directly to sheets. This increases the file size a little, +but speeds up data writing and saves memory. If you want strings to be written to the shared string xml, +you need to use the 'shared_string' option. +```php +$excel = Excel::create([], ['shared_string' => true]); +``` + ## **FastExcelWriter** vs **PhpSpreadsheet** **PhpSpreadsheet** is a perfect library with wonderful features for reading and writing many document formats. diff --git a/docs/01-workbook.md b/docs/01-workbook.md index e1507f1..a26c854 100644 --- a/docs/01-workbook.md +++ b/docs/01-workbook.md @@ -20,9 +20,18 @@ $font = [ // Creates workbook with default font style $excel = Excel::create(['Foo', 'Bar'], [Style::FONT => $font]); +// Automatically convert strings containing numbers to numbers +$excel = Excel::create([], ['auto_convert_number' => true]); + +// Saving strings to the shared string xml +$excel = Excel::create([], ['shared_string' => true]); + // Sets locale // In most cases, the locale is automatically set correctly, // but sometimes you need to do it manually +$excel = Excel::create([], ['locale' => 'fr']); +// or other way +$excel = Excel::create(); $excel->setLocale('fr'); // Sets default font diff --git a/docs/02-sheets.md b/docs/02-sheets.md index 2982277..3b96556 100644 --- a/docs/02-sheets.md +++ b/docs/02-sheets.md @@ -37,6 +37,7 @@ $sheet1->setDefaultFontStyleUnderline(true); $sheet1->setDefaultFontStyleStrikethrough(); $sheet1->setDefaultFontColor($font); +$sheet1->setTabColor('#ff0099'); ``` ### Page Settings diff --git a/docs/05-charts.md b/docs/05-charts.md index fa0070f..2bc89c8 100644 --- a/docs/05-charts.md +++ b/docs/05-charts.md @@ -159,7 +159,7 @@ Result of this code: | TYPE_PIE_3D | pie 3D chart | ![img/chart-pie-3d_240.jpg](img/chart-pie-3d_240.jpg) | | TYPE_DONUT | doughnut chart | ![img/chart-donut_240.jpg](img/chart-donut_240.jpg) | -### Useful Chart Methods +### Useful Chart Methods * setTitle(\) - chart title * setChartColors(\) - chart colors diff --git a/src/FastExcelWriter/Excel.php b/src/FastExcelWriter/Excel.php index 2a6f8a4..ef1e5e3 100644 --- a/src/FastExcelWriter/Excel.php +++ b/src/FastExcelWriter/Excel.php @@ -172,6 +172,9 @@ public function __construct(?array $options = []) if (isset($options['temp_prefix']) && $options['temp_prefix']) { $writerOptions['temp_prefix'] = $options['temp_prefix']; } + $writerOptions['auto_convert_number'] = !empty($options['auto_convert_number']); + $writerOptions['shared_string'] = !empty($options['shared_string']); + if (isset($options['writer_class'])) { $this->writer = $this->getObject($options['writer_class'], $writerOptions); $this->writer->setExcel($this); @@ -191,6 +194,10 @@ public function __construct(?array $options = []) } $this->setDefaultLocale(); + if (!empty($options['locale'])) { + $this->setLocale($options['locale']); + } + $this->bookViews = [ [ 'activeTab' => '0', diff --git a/src/FastExcelWriter/Sheet.php b/src/FastExcelWriter/Sheet.php index bd5e41b..245c9c8 100644 --- a/src/FastExcelWriter/Sheet.php +++ b/src/FastExcelWriter/Sheet.php @@ -150,6 +150,8 @@ class Sheet implements InterfaceSheetWriter protected array $sheetFormatPr = []; + protected array $sheetProperties = []; + // bottom sheet nodes protected array $bottomNodesOptions = []; @@ -545,6 +547,22 @@ public function getPageFit(): bool return !empty($this->bottomNodesOptions['pageSetup']['fitToWidth']) || !empty($this->bottomNodesOptions['pageSetup']['fitToHeight']); } + /** + * @return array + */ + public function getSheetProperties(): array + { + $result = $this->sheetProperties; + if ($this->getPageFit()) { + $this->sheetProperties['pageSetUpPr'] = [ + '_tag' => 'pageSetUpPr', + '_attr' => ['fitToPage' => '1'], + ]; + } + + return $result; + } + /** * @return array */ @@ -675,6 +693,29 @@ public function setTopLeftCell($cellAddress): Sheet return $this; } + /** + * @param string|null $color + * + * @return $this + */ + public function setTabColor(?string $color): Sheet + { + if (!$color) { + if (isset($this->sheetProperties['tabColor'])) { + unset($this->sheetProperties['tabColor']); + } + } + else { + $color = Style::normalizeColor($color); + $this->sheetProperties['tabColor'] = [ + '_tag' => 'tabColor', + '_attr' => ['rgb' => $color], + ]; + } + + return $this; + } + /** * @param array $columns * diff --git a/src/FastExcelWriter/Writer/Writer.php b/src/FastExcelWriter/Writer/Writer.php index 93af9c0..4684e39 100644 --- a/src/FastExcelWriter/Writer/Writer.php +++ b/src/FastExcelWriter/Writer/Writer.php @@ -173,7 +173,7 @@ class Writer . '|sort' . ')\s*\(/mui'; - //protected static array $buffers = []; + protected array $buffers = []; /** @var Excel */ @@ -183,12 +183,14 @@ class Writer protected array $tempFiles = []; protected string $tempFilePrefix = ''; - /** @var string */ - protected $tempDir = ''; + /** @var string|null */ + protected ?string $tempDir = ''; /** @var \ZipArchive */ protected \ZipArchive $zip; + protected bool $autoConvertNumber = false; + protected bool $sharedString = false; /** @@ -214,6 +216,8 @@ public function __construct(?array $options = []) if (!empty($options['temp_dir'])) { $this->setTempDir($options['temp_dir']); } + $this->autoConvertNumber = !empty($options['auto_convert_number']); + $this->sharedString = !empty($options['shared_string']); register_shutdown_function([$this, 'removeFiles']); } @@ -1064,11 +1068,16 @@ protected function _writeSheetHead(Sheet $sheet): FileWriter ]; $fileWriter->write(''); - if ($sheet->getPageFit()) { + $sheetPr = $sheet->getSheetProperties(); + if ($sheetPr) { $fileWriter->write(''); + foreach ($sheetPr as $item) { + $fileWriter->write('<' . $item['_tag'] . self::tagAttributes($item['_attr']) . '/>'); + } $fileWriter->write(''); $fileWriter->write(''); } + $minCell = $sheet->minCell(); $maxCell = $sheet->maxCell(); if ($minCell === $maxCell) { @@ -1369,16 +1378,33 @@ public function _writeCell(FileWriter $file, int $rowNumber, int $colNumber, $va } $file->write('' . $value . '');//int,float,currency } - elseif ($numFormatType === 'n_auto' || 1) { //auto-detect unknown column types - if (!is_string($value) || $value === '0' || ($value[0] !== '0' && preg_match('/^\d+$/', $value)) || preg_match("/^-?(0|[1-9]\d*)(\.\d+)?$/", $value)) { + elseif ($numFormatType === 'n_auto') { + if ($this->autoConvertNumber) { + //auto-detect unknown types + if (!is_string($value) || $value === '0' || ($value[0] !== '0' && preg_match('/^\d+$/', $value)) || preg_match("/^-?(0|[1-9]\d*)(\.\d+)?$/", $value)) { + $isStr = false; + } + else { + $isStr = true; + } + } + else { + $isStr = is_string($value); + } + if (!$isStr) { $file->write('' . $value . '');//int,float,currency } else { - //implied: ($cellFormat=='string') if (strpos($value, '\=') === 0 || strpos($value, '\\\\=') === 0) { $value = substr($value, 1); } - $file->write('' . self::xmlSpecialChars($value) . ''); + if ($this->sharedString) { + $sharedStrIndex = $this->excel->addSharedString($value); + $file->write('' . $sharedStrIndex . ''); + } + else { + $file->write('' . self::xmlSpecialChars($value) . ''); + } } } }