From 7ac28e0048b270f62ebc4e89daff78c35e5f4bc7 Mon Sep 17 00:00:00 2001 From: "lewa::cpan.org" Date: Mon, 10 Jul 2017 17:08:33 +0300 Subject: [PATCH 01/22] border-style and border-color support --- README.md | 22 ++++++++++++---------- xlsxwriter.class.php | 28 ++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 26de6ae5a..1dee4a110 100644 --- a/README.md +++ b/README.md @@ -83,15 +83,17 @@ Simple cell formats map to more advanced cell formats Basic cell styles have been available since version 0.30 -| style | allowed values | -| ---------- | ---- | -| font | Arial, Times New Roman, Courier New, Comic Sans MS | -| font-size | 8,9,10,11,12 ... | -| font-style | bold, italic, underline, strikethrough or multiple ie: 'bold,italic' | -| border | left, right, top, bottom, or multiple ie: 'top,left' | -| color | #RRGGBB, ie: #ff99cc or #f9c | -| fill | #RRGGBB, ie: #eeffee or #efe | -| halign | general, left, right, justify, center | -| valign | bottom, center, distributed | +| style | allowed values | +| ------------ | ---- | +| font | Arial, Times New Roman, Courier New, Comic Sans MS | +| font-size | 8,9,10,11,12 ... | +| font-style | bold, italic, underline, strikethrough or multiple ie: 'bold,italic' | +| border | left, right, top, bottom, or multiple ie: 'top,left' | +| border-style | thin, medium, thick, dashDot, dashDotDot, dashed, dotted, double, hair, mediumDashDot, mediumDashDotDot, mediumDashed, slantDashDot | +| border-color | #RRGGBB, ie: #ff99cc or #f9c | +| color | #RRGGBB, ie: #ff99cc or #f9c | +| fill | #RRGGBB, ie: #eeffee or #efe | +| halign | general, left, right, justify, center | +| valign | bottom, center, distributed | diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index a3a97cd7d..2a9701d4f 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -312,6 +312,7 @@ protected function writeCell(XLSXWriter_BuffererWriter &$file, $row_number, $col protected function styleFontIndexes() { static $border_allowed = array('left','right','top','bottom'); + static $border_style_allowed = array('thin','medium','thick','dashDot','dashDotDot','dashed','dotted','double','hair','mediumDashDot','mediumDashDotDot','mediumDashed','slantDashDot'); static $horizontal_allowed = array('general','left','right','justify','center'); static $vertical_allowed = array('bottom','center','distributed'); $default_font = array('size'=>'10','name'=>'Arial','family'=>'2'); @@ -332,7 +333,17 @@ protected function styleFontIndexes() $border_input = explode(",", $style['border']); sort($border_input); $border_value = array_intersect($border_input, $border_allowed); - $style_indexes[$i]['border_idx'] = self::add_to_list_get_index($borders, implode(",", $border_value) ); + if (isset($style['border-style']) && in_array($style['border-style'],$border_style_allowed)) + { + $border_value['style'] = $style['border-style']; + } + if (isset($style['border-color']) && is_string($style['border-color']) && $style['border-color'][0]=='#') + { + $v = substr($style['border-color'],1,6); + $v = strlen($v)==3 ? $v[0].$v[0].$v[1].$v[1].$v[2].$v[2] : $v;// expand cf0 => ccff00 + $border_value['color'] = "FF".strtoupper($v); + } + $style_indexes[$i]['border_idx'] = self::add_to_list_get_index($borders, json_encode($border_value)); } if (isset($style['fill']) && is_string($style['fill']) && $style['fill'][0]=='#') { @@ -442,12 +453,17 @@ protected function writeStylesXML() $file->write( ''); foreach($borders as $border) { if (!empty($border)) { //fonts have an empty placeholder in the array to offset the static xml entry above - $pieces = explode(",", $border); + $pieces = json_decode($border,true); + $border_style = !empty($pieces['style']) ? $pieces['style'] : 'hair'; $file->write(''); - $file->write( ''); - $file->write( ''); - $file->write( ''); - $file->write( ''); + foreach (array('left', 'right', 'top', 'bottom') as $side) + { + $file->write('<'.$side.(in_array($side,$pieces) ? ' style="'.$border_style.'"' : '').'>'); + if (!empty($pieces['color'])) { + $file->write(''); + } + $file->write(''); + } $file->write( ''); $file->write(''); } From 27bfba3d4b8fca1f589b94661c2513a79b600386 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:37:44 +0200 Subject: [PATCH 02/22] Added Subject, Company, Keywords, Description Added the company in app.xml. Subject, Description added as string in core.xml Keywords added as array in core.xml All are set in the document properties, on the summary tab. --- xlsxwriter.class.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index b1e8d04d0..cee87e648 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -13,7 +13,11 @@ class XLSXWriter const EXCEL_2007_MAX_COL=16384; //------------------------------------------------------------------ protected $title ='Doc Title'; + protected $subject ='Doc Subject'; protected $author ='Doc Author'; + protected $company ='Doc Company'; + protected $description ='Doc Description'; + protected $keywords = array(); protected $sheets = array(); protected $temp_files = array(); protected $cell_styles = array(); @@ -35,7 +39,11 @@ public function __construct() } public function setTitle($title='') { $this->title=$title; } + public function setSubject($subject='') { $this->subject=$subject; } public function setAuthor($author='') { $this->author=$author; } + public function setCompany($company='') { $this->company=$company; } + public function setKeywords($keywords='') { $this->keywords=$keywords; } + public function setDescription($description='') { $this->description=$description; } public function setTempDir($tempdir='') { $this->tempdir=$tempdir; } public function __destruct() @@ -562,7 +570,10 @@ protected function buildAppXML() { $app_xml=""; $app_xml.=''."\n"; - $app_xml.='0'; + $app_xml.=''; + $app_xml.='0'; + $app_xml.=''.self::xmlspecialchars($this->company).''; + $app_xml.=''; return $app_xml; } @@ -573,7 +584,12 @@ protected function buildCoreXML() $core_xml.=''; $core_xml.=''.date("Y-m-d\TH:i:s.00\Z").'';//$date_time = '2014-10-25T15:54:37.00Z'; $core_xml.=''.self::xmlspecialchars($this->title).''; + $core_xml.=''.self::xmlspecialchars($this->subject).''; $core_xml.=''.self::xmlspecialchars($this->author).''; + if (!empty($this->keywords)) { + $core_xml.=''.self::xmlspecialchars(implode (", ", $this->keywords)).''; + } + $core_xml.=''.self::xmlspecialchars($this->description).''; $core_xml.='0'; $core_xml.=''; return $core_xml; From ee14d1c7d73bac05a2d08ce704c01b00bd02af85 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:46:58 +0200 Subject: [PATCH 03/22] Update example.php for new properties Added title, subject, author, company, keywords and description. --- example.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/example.php b/example.php index 5d315f4df..64692d0c2 100644 --- a/example.php +++ b/example.php @@ -15,8 +15,16 @@ array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'), array('2003','=B2', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'), ); + +$keywords = array('some','interesting','keywords'); + $writer = new XLSXWriter(); +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); foreach($rows as $row) $writer->writeSheetRow('Sheet1', $row); $writer->writeToStdOut(); From 7588f4b57940cf3886a6758e2b41d37c80dcb21b Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:49:08 +0200 Subject: [PATCH 04/22] Update example-cli.php for new properties Added title, subject, author, company, keywords and description. --- example-cli.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/example-cli.php b/example-cli.php index 2df4d0b9e..ce4eb1d66 100644 --- a/example-cli.php +++ b/example-cli.php @@ -19,8 +19,16 @@ array('2003','1','-50.5','2010-01-01 23:00:00','2012-12-31 23:00:00'), array('2003','=B2', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'), ); + +$keywords = array('some','interesting','keywords'); + $writer = new XLSXWriter(); +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); foreach($rows as $row) $writer->writeSheetRow('Sheet1', $row); From 2778f545a4aed6328ca0af642ccf097c2eef4ab9 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:51:40 +0200 Subject: [PATCH 05/22] Update formats.php for new properties Added title, subject, author, company, keywords and description. --- testbench/pairs/formats.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testbench/pairs/formats.php b/testbench/pairs/formats.php index e39e42052..697c7bca6 100644 --- a/testbench/pairs/formats.php +++ b/testbench/pairs/formats.php @@ -2,7 +2,14 @@ include_once("../../xlsxwriter.class.php"); $writer = new XLSXWriter(); +$keywords = array('some','interesting','keywords'); + +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); $header = array( 'General'=>'string', From 72b903fab5d5ca0f12cdf9d8c96482e2f4d61bce Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:52:33 +0200 Subject: [PATCH 06/22] Update test.php for new properties Added title, subject, author, company, keywords and description. --- testbench/pairs/test.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testbench/pairs/test.php b/testbench/pairs/test.php index ab2c494fa..34b7befc4 100644 --- a/testbench/pairs/test.php +++ b/testbench/pairs/test.php @@ -2,7 +2,14 @@ include_once("../../xlsxwriter.class.php"); $writer = new XLSXWriter(); +$keywords = array('some','interesting','keywords'); + +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); $header = array( 'General'=>'string', From 6735c05554bd03edeed5d8ea9ae1bc9f733260b2 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:54:01 +0200 Subject: [PATCH 07/22] Update test.php for new properties Added title, subject, author, company, keywords and description. --- testbench/test.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/testbench/test.php b/testbench/test.php index ba7ca4c4d..088bd20fe 100644 --- a/testbench/test.php +++ b/testbench/test.php @@ -17,7 +17,14 @@ array('2003','02','345.12'), ); $writer = new XLSXWriter(); +$keywords = array('some','interesting','keywords'); + +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); $writer->writeSheet($data1,'Sheet1',$header); $writer->writeSheet($data2,'Sheet2'); $writer->writeToFile('test.xlsx'); From 80ac50dfb53046e0c3147bf116924e54d54cb9e9 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:55:59 +0200 Subject: [PATCH 08/22] Update ex02-formats.php Added title, subject, author, company, keywords and description. --- examples/ex02-formats.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/ex02-formats.php b/examples/ex02-formats.php index e0b0c6632..b5f99d1c4 100644 --- a/examples/ex02-formats.php +++ b/examples/ex02-formats.php @@ -40,8 +40,15 @@ $date = '2018-12-31 23:59:59'; $amount = '5120.5'; +$keywords = array('some','interesting','keywords'); + $writer = new XLSXWriter(); +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); $writer->writeSheetHeader('BasicFormats',$sheet1header); $writer->writeSheetRow('BasicFormats',array($pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi) ); $writer->writeSheetHeader('Dates',$sheet2header); From e7ad0d3bf3eeb3f78f240198bdfefd0badc1cdd7 Mon Sep 17 00:00:00 2001 From: Erich Date: Thu, 24 Aug 2017 21:57:30 +0200 Subject: [PATCH 09/22] Update ex08-advanced.php Added title, subject, author, company, keywords and description. --- examples/ex08-advanced.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/ex08-advanced.php b/examples/ex08-advanced.php index 33ed7c3eb..d7c358cb3 100644 --- a/examples/ex08-advanced.php +++ b/examples/ex08-advanced.php @@ -3,7 +3,14 @@ include_once("xlsxwriter.class.php"); $writer = new XLSXWriter(); +$keywords = array('some','interesting','keywords'); + +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); $writer->setTempDir(sys_get_temp_dir());//set custom tempdir //---- From 8a19b835a218bfeb0d89f3eb68989734e7ac2b93 Mon Sep 17 00:00:00 2001 From: Erich Date: Sat, 26 Aug 2017 09:20:02 +0200 Subject: [PATCH 10/22] Update xlsxwriter.class.php --- xlsxwriter.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index cee87e648..a2d4af378 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -12,19 +12,19 @@ class XLSXWriter const EXCEL_2007_MAX_ROW=1048576; const EXCEL_2007_MAX_COL=16384; //------------------------------------------------------------------ - protected $title ='Doc Title'; - protected $subject ='Doc Subject'; - protected $author ='Doc Author'; - protected $company ='Doc Company'; - protected $description ='Doc Description'; + protected $title; + protected $subject; + protected $author; + protected $company; + protected $description; + + protected $current_sheet; protected $keywords = array(); protected $sheets = array(); protected $temp_files = array(); protected $cell_styles = array(); protected $number_formats = array(); - protected $current_sheet = ''; - public function __construct() { if(!ini_get('date.timezone')) From f64c514d06cd0852e64be3934a61dd7e67e87ff2 Mon Sep 17 00:00:00 2001 From: Erich Date: Sat, 26 Aug 2017 09:26:15 +0200 Subject: [PATCH 11/22] Update xlsxwriter.class.php --- xlsxwriter.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index a2d4af378..8c46a46bc 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -17,9 +17,9 @@ class XLSXWriter protected $author; protected $company; protected $description; - - protected $current_sheet; protected $keywords = array(); + + protected $current_sheet; protected $sheets = array(); protected $temp_files = array(); protected $cell_styles = array(); From e7bb7b120a9acab51afaabe58686dbc408cc23c9 Mon Sep 17 00:00:00 2001 From: Erich Date: Sat, 26 Aug 2017 09:42:56 +0200 Subject: [PATCH 12/22] Added properties example to readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 26de6ae5a..115444ffd 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,20 @@ foreach($data as $row) $writer->writeToFile('example.xlsx'); ``` +Set document properties: +```php +$keywords = $keywords = array('some','interesting','keywords'); + +$writer = new XLSXWriter(); + +$writer->setTitle('Some Title'); +$writer->setSubject('Some Subject'); +$writer->setAuthor('Some Author'); +$writer->setCompany('Some Company'); +$writer->setKeywords($keywords); +$writer->setDescription('Some interesting description'); +``` + 50000 rows: (1.4s, 0MB memory usage) ```php include_once("xlsxwriter.class.php"); From 8feea1e52e2115f1eec5a3eab8b80cd7fe5c1316 Mon Sep 17 00:00:00 2001 From: Erich Date: Sat, 26 Aug 2017 16:23:04 +0200 Subject: [PATCH 13/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 115444ffd..2b3122d70 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ $writer->writeToFile('example.xlsx'); Set document properties: ```php -$keywords = $keywords = array('some','interesting','keywords'); +$keywords = array('some','interesting','keywords'); $writer = new XLSXWriter(); From 27e9db34efe56fe5dc7e5902e26ef366301d8cd8 Mon Sep 17 00:00:00 2001 From: Andrew Kesper Date: Wed, 3 Jan 2018 08:56:19 +1100 Subject: [PATCH 14/22] Allow top vertical align --- xlsxwriter.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index b1e8d04d0..8dc638e10 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -350,7 +350,7 @@ protected function styleFontIndexes() { static $border_allowed = array('left','right','top','bottom'); static $horizontal_allowed = array('general','left','right','justify','center'); - static $vertical_allowed = array('bottom','center','distributed'); + static $vertical_allowed = array('bottom','center','distributed','top'); $default_font = array('size'=>'10','name'=>'Arial','family'=>'2'); $fills = array('','');//2 placeholders for static xml later $fonts = array('','','','');//4 placeholders for static xml later From 37f28efd790595b5b74293fcdfd30e3536e112c5 Mon Sep 17 00:00:00 2001 From: Andrew Kesper Date: Wed, 3 Jan 2018 09:01:40 +1100 Subject: [PATCH 15/22] Date/time format detection now accepts lowercase letters --- xlsxwriter.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index b1e8d04d0..4901d86ab 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -705,11 +705,11 @@ private static function determineNumberFormatType($num_format) if ($num_format=='GENERAL') return 'n_auto'; if ($num_format=='@') return 'n_string'; if ($num_format=='0') return 'n_numeric'; - if (preg_match("/[H]{1,2}:[M]{1,2}/", $num_format)) return 'n_datetime'; - if (preg_match("/[M]{1,2}:[S]{1,2}/", $num_format)) return 'n_datetime'; - if (preg_match("/[YY]{2,4}/", $num_format)) return 'n_date'; - if (preg_match("/[D]{1,2}/", $num_format)) return 'n_date'; - if (preg_match("/[M]{1,2}/", $num_format)) return 'n_date'; + if (preg_match("/[H]{1,2}:[M]{1,2}/i", $num_format)) return 'n_datetime'; + if (preg_match("/[M]{1,2}:[S]{1,2}/i", $num_format)) return 'n_datetime'; + if (preg_match("/[Y]{2,4}/i", $num_format)) return 'n_date'; + if (preg_match("/[D]{1,2}/i", $num_format)) return 'n_date'; + if (preg_match("/[M]{1,2}/i", $num_format)) return 'n_date'; if (preg_match("/$/", $num_format)) return 'n_numeric'; if (preg_match("/%/", $num_format)) return 'n_numeric'; if (preg_match("/0/", $num_format)) return 'n_numeric'; From 9098ca64a2f54128c9f1900ca86b4e4f9bd6e034 Mon Sep 17 00:00:00 2001 From: Andrew Kesper Date: Wed, 3 Jan 2018 09:15:43 +1100 Subject: [PATCH 16/22] Column widths compatible with Excel for Mac --- xlsxwriter.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index b1e8d04d0..b2dbd83df 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -148,11 +148,11 @@ protected function initializeSheet($sheet_name, $col_widths=array() ) $i=0; if (!empty($col_widths)) { foreach($col_widths as $column_width) { - $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); $i++; } } - $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); } From 97e402638d922b1fad375d0886e57a9756b9beb5 Mon Sep 17 00:00:00 2001 From: Andrew Kesper Date: Wed, 3 Jan 2018 10:16:34 +1100 Subject: [PATCH 17/22] AutoFilter support --- examples/ex09-autofilter.php | 18 ++++++++++++++++++ xlsxwriter.class.php | 30 +++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 examples/ex09-autofilter.php diff --git a/examples/ex09-autofilter.php b/examples/ex09-autofilter.php new file mode 100644 index 000000000..c415e05a9 --- /dev/null +++ b/examples/ex09-autofilter.php @@ -0,0 +1,18 @@ +writeSheetHeader('Sheet1', array('col-string'=>'string','col-numbers'=>'integer','col-timestamps'=>'datetime'), ['auto_filter'=>true, 'widths'=>[15,15,30]] ); +for($i=0; $i<1000; $i++) +{ + $writer->writeSheetRow('Sheet1', array( + str_shuffle($chars), + rand()%10000, + date('Y-m-d H:i:s',time()-(rand()%31536000)) + )); +} +$writer->writeToFile('xlsx-autofilter.xlsx'); +echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n"; diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index b1e8d04d0..4b99b352c 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -108,7 +108,7 @@ public function writeToFile($filename) $zip->close(); } - protected function initializeSheet($sheet_name, $col_widths=array() ) + protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filter=false) { //if already initialized if ($this->current_sheet==$sheet_name || isset($this->sheets[$sheet_name])) @@ -126,6 +126,7 @@ protected function initializeSheet($sheet_name, $col_widths=array() ) 'merge_cells' => array(), 'max_cell_tag_start' => 0, 'max_cell_tag_end' => 0, + 'auto_filter' => $auto_filter, 'finalized' => false, ); $sheet = &$this->sheets[$sheet_name]; @@ -195,7 +196,8 @@ public function writeSheetHeader($sheet_name, array $header_types, $col_options $style = &$col_options; $col_widths = isset($col_options['widths']) ? (array)$col_options['widths'] : array(); - self::initializeSheet($sheet_name, $col_widths); + $auto_filter = isset($col_options['auto_filter']) ? intval($col_options['auto_filter']) : false; + self::initializeSheet($sheet_name, $col_widths, $auto_filter); $sheet = &$this->sheets[$sheet_name]; $sheet->columns = $this->initializeColumnTypes($header_types); if (!$suppress_row) @@ -275,6 +277,12 @@ protected function finalizeSheet($sheet_name) $sheet->file_writer->write( ''); } + $max_cell = self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1); + + if ($sheet->auto_filter) { + $sheet->file_writer->write( ''); + } + $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); @@ -284,7 +292,6 @@ protected function finalizeSheet($sheet_name) $sheet->file_writer->write( ''); $sheet->file_writer->write(''); - $max_cell = self::xlsCell($sheet->row_count - 1, count($sheet->columns) - 1); $max_cell_tag = ''; $padding_length = $sheet->max_cell_tag_end - $sheet->max_cell_tag_start - strlen($max_cell_tag); $sheet->file_writer->fseek($sheet->max_cell_tag_start); @@ -607,6 +614,15 @@ protected function buildWorkbookXML() $i++; } $workbook_xml.=''; + $workbook_xml.=''; + foreach($this->sheets as $sheet_name=>$sheet) { + if ($sheet->auto_filter) { + $sheetname = self::sanitize_sheetname($sheet->sheetname); + $workbook_xml.=''; + $i++; + } + } + $workbook_xml.=''; $workbook_xml.=''; return $workbook_xml; } @@ -650,14 +666,18 @@ protected function buildContentTypesXML() /* * @param $row_number int, zero based * @param $column_number int, zero based - * @return Cell label/coordinates, ex: A1, C3, AA42 + * @param $absolute bool + * @return Cell label/coordinates, ex: A1, C3, AA42 (or if $absolute==true: $A$1, $C$3, $AA$42) * */ - public static function xlsCell($row_number, $column_number) + public static function xlsCell($row_number, $column_number, $absolute=false) { $n = $column_number; for($r = ""; $n >= 0; $n = intval($n / 26) - 1) { $r = chr($n%26 + 0x41) . $r; } + if ($absolute) { + return '$' . $r . '$' . ($row_number+1); + } return $r . ($row_number+1); } //------------------------------------------------------------------ From 52f2d3d6d76f2c17d9ce8874e2a511d3a37bdc2a Mon Sep 17 00:00:00 2001 From: Andrew Kesper Date: Wed, 3 Jan 2018 10:30:21 +1100 Subject: [PATCH 18/22] Freeze rows/columns support --- examples/ex10-freeze-rows-columns.php | 20 ++++++++++++++++++++ xlsxwriter.class.php | 26 +++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 examples/ex10-freeze-rows-columns.php diff --git a/examples/ex10-freeze-rows-columns.php b/examples/ex10-freeze-rows-columns.php new file mode 100644 index 000000000..196c78091 --- /dev/null +++ b/examples/ex10-freeze-rows-columns.php @@ -0,0 +1,20 @@ +writeSheetHeader('Sheet1', array('c1'=>'string','c2'=>'integer','c3'=>'integer','c4'=>'integer','c5'=>'integer'), ['freeze_rows'=>1, 'freeze_columns'=>1] ); +for($i=0; $i<250; $i++) +{ + $writer->writeSheetRow('Sheet1', array( + str_shuffle($chars), + rand()%10000, + rand()%10000, + rand()%10000, + rand()%10000 + )); +} +$writer->writeToFile('xlsx-freeze-rows-columns.xlsx'); +echo '#'.floor((memory_get_peak_usage())/1024/1024)."MB"."\n"; diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index 4b99b352c..f389427bb 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -108,7 +108,7 @@ public function writeToFile($filename) $zip->close(); } - protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filter=false) + protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filter=false, $freeze_rows=false, $freeze_columns=false ) { //if already initialized if ($this->current_sheet==$sheet_name || isset($this->sheets[$sheet_name])) @@ -127,6 +127,8 @@ protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filte 'max_cell_tag_start' => 0, 'max_cell_tag_end' => 0, 'auto_filter' => $auto_filter, + 'freeze_rows' => $freeze_rows, + 'freeze_columns' => $freeze_columns, 'finalized' => false, ); $sheet = &$this->sheets[$sheet_name]; @@ -142,7 +144,23 @@ protected function initializeSheet($sheet_name, $col_widths=array(), $auto_filte $sheet->max_cell_tag_end = $sheet->file_writer->ftell(); $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); - $sheet->file_writer->write( ''); + if ($sheet->freeze_rows && $sheet->freeze_columns) { + $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); + } + elseif ($sheet->freeze_rows) { + $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); + } + elseif ($sheet->freeze_columns) { + $sheet->file_writer->write( ''); + $sheet->file_writer->write( ''); + } + else { // not frozen + $sheet->file_writer->write( ''); + } $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); $sheet->file_writer->write( ''); @@ -197,7 +215,9 @@ public function writeSheetHeader($sheet_name, array $header_types, $col_options $col_widths = isset($col_options['widths']) ? (array)$col_options['widths'] : array(); $auto_filter = isset($col_options['auto_filter']) ? intval($col_options['auto_filter']) : false; - self::initializeSheet($sheet_name, $col_widths, $auto_filter); + $freeze_rows = isset($col_options['freeze_rows']) ? intval($col_options['freeze_rows']) : false; + $freeze_columns = isset($col_options['freeze_columns']) ? intval($col_options['freeze_columns']) : false; + self::initializeSheet($sheet_name, $col_widths, $auto_filter, $freeze_rows, $freeze_columns); $sheet = &$this->sheets[$sheet_name]; $sheet->columns = $this->initializeColumnTypes($header_types); if (!$suppress_row) From 2698395873f083ceed53580eed7b2b4f789cd6f1 Mon Sep 17 00:00:00 2001 From: mk-j Date: Wed, 10 Jan 2018 23:15:54 -0700 Subject: [PATCH 19/22] cleaning up examples --- README.md | 14 -------------- example-cli.php | 9 +-------- example.php | 9 +-------- examples/ex02-formats.php | 7 ------- xlsxwriter.class.php | 2 +- 5 files changed, 3 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 2b3122d70..26de6ae5a 100644 --- a/README.md +++ b/README.md @@ -48,20 +48,6 @@ foreach($data as $row) $writer->writeToFile('example.xlsx'); ``` -Set document properties: -```php -$keywords = array('some','interesting','keywords'); - -$writer = new XLSXWriter(); - -$writer->setTitle('Some Title'); -$writer->setSubject('Some Subject'); -$writer->setAuthor('Some Author'); -$writer->setCompany('Some Company'); -$writer->setKeywords($keywords); -$writer->setDescription('Some interesting description'); -``` - 50000 rows: (1.4s, 0MB memory usage) ```php include_once("xlsxwriter.class.php"); diff --git a/example-cli.php b/example-cli.php index fa177239e..e3245422e 100644 --- a/example-cli.php +++ b/example-cli.php @@ -11,15 +11,8 @@ array('2003','=B1', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'), ); -$keywords = array('some','interesting','keywords'); - $writer = new XLSXWriter(); -$writer->setTitle('Some Title'); -$writer->setSubject('Some Subject'); -$writer->setAuthor('Some Author'); -$writer->setCompany('Some Company'); -$writer->setKeywords($keywords); -$writer->setDescription('Some interesting description'); +$writer->setAuthor('Some Author'); foreach($rows as $row) $writer->writeSheetRow('Sheet1', $row); diff --git a/example.php b/example.php index 6857e69eb..38831aea7 100644 --- a/example.php +++ b/example.php @@ -16,15 +16,8 @@ array('2003','=B1', '23.5','2010-01-01 00:00:00','2012-12-31 00:00:00'), ); -$keywords = array('some','interesting','keywords'); - $writer = new XLSXWriter(); -$writer->setTitle('Some Title'); -$writer->setSubject('Some Subject'); -$writer->setAuthor('Some Author'); -$writer->setCompany('Some Company'); -$writer->setKeywords($keywords); -$writer->setDescription('Some interesting description'); +$writer->setAuthor('Some Author'); foreach($rows as $row) $writer->writeSheetRow('Sheet1', $row); $writer->writeToStdOut(); diff --git a/examples/ex02-formats.php b/examples/ex02-formats.php index b5f99d1c4..e0b0c6632 100644 --- a/examples/ex02-formats.php +++ b/examples/ex02-formats.php @@ -40,15 +40,8 @@ $date = '2018-12-31 23:59:59'; $amount = '5120.5'; -$keywords = array('some','interesting','keywords'); - $writer = new XLSXWriter(); -$writer->setTitle('Some Title'); -$writer->setSubject('Some Subject'); $writer->setAuthor('Some Author'); -$writer->setCompany('Some Company'); -$writer->setKeywords($keywords); -$writer->setDescription('Some interesting description'); $writer->writeSheetHeader('BasicFormats',$sheet1header); $writer->writeSheetRow('BasicFormats',array($pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi,$pi) ); $writer->writeSheetHeader('Dates',$sheet2header); diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index f104d00ea..0c533fe35 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -587,7 +587,7 @@ protected function buildCoreXML() $core_xml.=''.self::xmlspecialchars($this->subject).''; $core_xml.=''.self::xmlspecialchars($this->author).''; if (!empty($this->keywords)) { - $core_xml.=''.self::xmlspecialchars(implode (", ", $this->keywords)).''; + $core_xml.=''.self::xmlspecialchars(implode (", ", (array)$this->keywords)).''; } $core_xml.=''.self::xmlspecialchars($this->description).''; $core_xml.='0'; From 78459e1115f48e3439be27b8050fce018ddce3b4 Mon Sep 17 00:00:00 2001 From: mk-j Date: Wed, 10 Jan 2018 23:36:53 -0700 Subject: [PATCH 20/22] fix for php 5.3 compatibility --- xlsxwriter.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xlsxwriter.class.php b/xlsxwriter.class.php index 0c533fe35..afa9228ec 100644 --- a/xlsxwriter.class.php +++ b/xlsxwriter.class.php @@ -17,9 +17,9 @@ class XLSXWriter protected $author; protected $company; protected $description; - protected $keywords = array(); + protected $keywords = array(); - protected $current_sheet; + protected $current_sheet; protected $sheets = array(); protected $temp_files = array(); protected $cell_styles = array(); @@ -237,8 +237,8 @@ public function writeSheetRow($sheet_name, array $row, $row_options=null) { $ht = isset($row_options['height']) ? floatval($row_options['height']) : 12.1; $customHt = isset($row_options['height']) ? true : false; - $hidden = isset($row_options['hidden']) ? boolval($row_options['hidden']) : false; - $collapsed = isset($row_options['collapsed']) ? boolval($row_options['collapsed']) : false; + $hidden = isset($row_options['hidden']) ? (bool)($row_options['hidden']) : false; + $collapsed = isset($row_options['collapsed']) ? (bool)($row_options['collapsed']) : false; $sheet->file_writer->write('