From 4f4ac11dae369856e60a3112794ef056fd5c08f6 Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Wed, 19 Apr 2023 01:00:22 -0500 Subject: [PATCH 1/4] add set meta data file --- README.md | 11 ++++ src/SimpleXLSXGen.php | 132 +++++++++++++++++++++++++++++++++++------- 2 files changed, 122 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 9ae1f19..11e0d82 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,17 @@ $xlsx->freezePanes('C3'); // Column A is on the far right, Column B is one column left of Column A, and so on. Also, information in cells is displayed in the Right to Left format. $xlsx->rightToLeft(); +// Set Meta Data Files +// this data in propertis Files and Info file in Office +$xlsx->setAuthor("Sergey Shuchkin") +$xlsx->setCompany("Sergey Shuchkin Company") +$xlsx->setManager("Sergey Shuchkin Manager") +$xlsx->setTitle("This is Title") +$xlsx->setSubject("This is Subject") +$xlsx->setKeywords("Keywords1, Keywords2, Keywords3, KeywordsN") +$xlsx->setDescription("This is Description") +$xlsx->setCategory("This is Сategory") +$xlsx->setApplication("This Is Best Application For Generate") ``` ### JS array to Excel (AJAX) ```php diff --git a/src/SimpleXLSXGen.php b/src/SimpleXLSXGen.php index ed35ae6..07e96ab 100644 --- a/src/SimpleXLSXGen.php +++ b/src/SimpleXLSXGen.php @@ -1,4 +1,6 @@ -subject = ''; + $this->title = ''; + $this->author = 'Sergey Shuchkin'; + $this->company = 'Sergey Shuchkin'; + $this->manager = 'Sergey Shuchkin'; + $this->description = ''; + $this->keywords = ''; + $this->category = ''; + $this->application = __CLASS__; + $this->curSheet = -1; $this->defaultFont = 'Calibri'; $this->defaultFontSize = 10; @@ -118,7 +140,6 @@ class SimpleXLSXGen ]; $this->XF_KEYS[implode('-', $this->XF[0])] = 0; // & keys $this->XF_KEYS[implode('-', $this->XF[1])] = 1; - $this->template = [ '_rels/.rels' => ' @@ -129,12 +150,20 @@ class SimpleXLSXGen 'docProps/app.xml' => ' 0 -' . __CLASS__ . ' +{APP} +{COMPANY} +{MANAGER} ', 'docProps/core.xml' => ' {DATE} -en-US + {TITLE} + {SUBJECT} + {AUTHOR} + {KEYWORD} + {DESCRIPTION} + {CATEGORY} + en-US {DATE} 1 ', @@ -166,7 +195,7 @@ class SimpleXLSXGen ', 'xl/workbook.xml' => ' - + {SHEETS} @@ -301,7 +330,7 @@ class SimpleXLSXGen $s .= '\r\n"; } - $s .= ''."\r\n"; + $s .= '' . "\r\n"; $s .= ''; $template = str_replace('{RELS}', $s, $template); @@ -312,11 +341,21 @@ class SimpleXLSXGen foreach ($this->sheets as $k => $v) { $s .= ''; } - $template = str_replace('{SHEETS}', $s, $template); + $search = ['{SHEETS}', '{APP}']; + $replace = [$s, $this->template]; + $template = str_replace($search, $replace, $template); + $this->_writeEntry($fh, $cdrec, $cfilename, $template); + $entries++; + } elseif ($cfilename === 'docProps/app.xml') { + $search = ['{APP}', '{COMPANY}', '{MANAGER}']; + $replace = [$this->application, $this->company, $this->manager]; + $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'docProps/core.xml') { - $template = str_replace('{DATE}', gmdate('Y-m-d\TH:i:s\Z'), $template); + $search = ['{DATE}', '{AUTHOR}', '{TITLE}', '{SUBJECT}', '{KEYWORD}', '{DESCRIPTION}', '{CATEGORY}']; + $replace = [gmdate('Y-m-d\TH:i:s\Z'), $this->author, $this->title, $this->subject, $this->keywords, $this->description, $this->category]; + $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'xl/sharedStrings.xml') { @@ -441,9 +480,9 @@ class SimpleXLSXGen $ba[] = $ba[0]; } if (!isset($ba[4])) { // diagonal - $ba[] = 'none'; + $ba[] = 'none'; } - $sides = [ 'left' => 3, 'right' => 1, 'top' => 0, 'bottom' => 2, 'diagonal' => 4]; + $sides = ['left' => 3, 'right' => 1, 'top' => 0, 'bottom' => 2, 'diagonal' => 4]; foreach ($sides as $side => $idx) { $s = 'thin'; $c = ''; @@ -514,6 +553,7 @@ class SimpleXLSXGen fwrite($fh, pack('V', $before_cd)); // offset to start of central dir fwrite($fh, pack('v', mb_strlen($zipComments, '8bit'))); // .zip file comment length fwrite($fh, $zipComments); + return true; } @@ -599,12 +639,12 @@ class SimpleXLSXGen setlocale(LC_NUMERIC, 'C'); $COLS = []; $ROWS = []; -// $SHEETVIEWS = 'rtl ? ' rightToLeft="1"' : '').'>'; + // $SHEETVIEWS = 'rtl ? ' rightToLeft="1"' : '').'>'; $SHEETVIEWS = ''; $PANE = ''; if (count($this->sheets[$idx]['rows'])) { if ($this->sheets[$idx]['frozen'] !== '' || isset($this->sheets[$idx]['frozen'][0]) || isset($this->sheets[$idx]['frozen'][1])) { -// $AC = 'A1'; // Active Cell + // $AC = 'A1'; // Active Cell $x = $y = 0; if (is_string($this->sheets[$idx]['frozen'])) { $AC = $this->sheets[$idx]['frozen']; @@ -709,8 +749,8 @@ class SimpleXLSXGen if (preg_match('/ font-size="([^"]+)"/', $m[1], $m2)) { $FS = (int)$m2[1]; if ($RH === 0) { // fix row height - $RH = ($FS > $this->defaultFontSize) ? round($FS * 1.50,1) : 0; - } + $RH = ($FS > $this->defaultFontSize) ? round($FS * 1.50, 1) : 0; + } } } if (strpos($v, '') !== false) { @@ -919,7 +959,8 @@ class SimpleXLSXGen //restore locale setlocale(LC_NUMERIC, $_loc); - return str_replace(['{REF}', '{COLS}', '{ROWS}', '{AUTOFILTER}', '{MERGECELLS}', '{HYPERLINKS}', '{SHEETVIEWS}'], + return str_replace( + ['{REF}', '{COLS}', '{ROWS}', '{AUTOFILTER}', '{MERGECELLS}', '{HYPERLINKS}', '{SHEETVIEWS}'], [ $REF, implode("\r\n", $COLS), @@ -929,7 +970,8 @@ class SimpleXLSXGen implode("\r\n", $HYPERLINKS), $SHEETVIEWS ], - $template); + $template + ); } public function num2name($num) @@ -981,6 +1023,53 @@ class SimpleXLSXGen return $this; } + public function setTitle($title) + { + $this->title = $title; + return $this; + } + public function setSubject($subject) + { + $this->subject = $subject; + return $this; + } + public function setAuthor($author) + { + $this->author = $author; + return $this; + } + public function setCompany($company) + { + $this->company = $company; + return $this; + } + public function setManager($manager) + { + $this->manager = $manager; + return $this; + } + public function setKeywords($keywords) + { + $this->keywords = $keywords; + return $this; + } + public function setDescription($description) + { + $this->description = $description; + return $this; + } + public function setCategory($category) + { + $this->category = $category; + return $this; + } + + public function setApplication($application) + { + $this->application = $application; + return $this; + } + public function autoFilter($range) { $this->sheets[$this->curSheet]['autofilter'] = $range; @@ -998,7 +1087,8 @@ class SimpleXLSXGen $this->sheets[$this->curSheet]['colwidth'][$col] = $width; return $this; } - public function rightToLeft($value = true) { + public function rightToLeft($value = true) + { $this->rtl = $value; return $this; } @@ -1047,8 +1137,8 @@ class SimpleXLSXGen if ($lettercount > 0) { $x = ord($cell[$lettercount - 1]) - ord('A'); $e = 1; - for ($i = $lettercount - 2 ; $i >= 0 ; $i--) { - $x += (ord($cell[$i]) - ord('A') + 1) * (26**$e); + for ($i = $lettercount - 2; $i >= 0; $i--) { + $x += (ord($cell[$i]) - ord('A') + 1) * (26 ** $e); $e++; } } @@ -1063,7 +1153,7 @@ class SimpleXLSXGen for ($i = $x; $i >= 0; $i = ((int)($i / 26)) - 1) { $c = chr(ord('A') + $i % 26) . $c; } - return $c . ($y+1); + return $c . ($y + 1); } public function freezePanes($cell) @@ -1071,4 +1161,4 @@ class SimpleXLSXGen $this->sheets[$this->curSheet]['frozen'] = $cell; return $this; } -} \ No newline at end of file +} From c449813bb150adf07ce4055eec1557017b44eb9a Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Wed, 19 Apr 2023 01:57:19 -0500 Subject: [PATCH 2/4] Update SimpleXLSXGen.php Fix 345 line $this->application --- src/SimpleXLSXGen.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SimpleXLSXGen.php b/src/SimpleXLSXGen.php index 07e96ab..1233d26 100644 --- a/src/SimpleXLSXGen.php +++ b/src/SimpleXLSXGen.php @@ -342,7 +342,7 @@ class SimpleXLSXGen $s .= ''; } $search = ['{SHEETS}', '{APP}']; - $replace = [$s, $this->template]; + $replace = [$s, $this->application]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; From 81120e6f720f94af693350822f91c60e8ba16baf Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Wed, 19 Apr 2023 02:31:58 -0500 Subject: [PATCH 3/4] * escape strings * use fluid interface and ' + Add LastModifiedBy + author, company, manager, LastModifiedBy set email --- README.md | 19 ++++++++++--------- src/SimpleXLSXGen.php | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 11e0d82..6d8fdb8 100644 --- a/README.md +++ b/README.md @@ -144,15 +144,16 @@ $xlsx->rightToLeft(); // Set Meta Data Files // this data in propertis Files and Info file in Office -$xlsx->setAuthor("Sergey Shuchkin") -$xlsx->setCompany("Sergey Shuchkin Company") -$xlsx->setManager("Sergey Shuchkin Manager") -$xlsx->setTitle("This is Title") -$xlsx->setSubject("This is Subject") -$xlsx->setKeywords("Keywords1, Keywords2, Keywords3, KeywordsN") -$xlsx->setDescription("This is Description") -$xlsx->setCategory("This is Сategory") -$xlsx->setApplication("This Is Best Application For Generate") +$xlsx->setAuthor('Sergey Shuchkin ') + ->setCompany('Microsoft ') + ->setManager('Bill Gates ') + ->setLastModifiedBy("Sergey Shuchkin ") + ->setTitle('This is Title') + ->setSubject('This is Subject') + ->setKeywords('Keywords1, Keywords2, Keywords3, KeywordsN') + ->setDescription('This is Description') + ->setCategory('This is Сategory') + ->setApplication('Shuchkin\SimpleXLSXGen') ``` ### JS array to Excel (AJAX) ```php diff --git a/src/SimpleXLSXGen.php b/src/SimpleXLSXGen.php index 1233d26..89c2b8f 100644 --- a/src/SimpleXLSXGen.php +++ b/src/SimpleXLSXGen.php @@ -39,6 +39,7 @@ class SimpleXLSXGen protected $application; protected $keywords; protected $category; + protected $lastModifiedBy; const N_NORMAL = 0; // General const N_INT = 1; // 0 const N_DEC = 2; // 0.00 @@ -92,12 +93,13 @@ class SimpleXLSXGen { $this->subject = ''; $this->title = ''; - $this->author = 'Sergey Shuchkin'; - $this->company = 'Sergey Shuchkin'; - $this->manager = 'Sergey Shuchkin'; + $this->author = 'Sergey Shuchkin '; + $this->company = 'Sergey Shuchkin '; + $this->manager = 'Sergey Shuchkin '; $this->description = ''; $this->keywords = ''; $this->category = ''; + $this->lastModifiedBy = 'Sergey Shuchkin '; $this->application = __CLASS__; $this->curSheet = -1; @@ -160,6 +162,7 @@ class SimpleXLSXGen {TITLE} {SUBJECT} {AUTHOR} + {LAST_MODIFY_BY} {KEYWORD} {DESCRIPTION} {CATEGORY} @@ -342,19 +345,19 @@ class SimpleXLSXGen $s .= ''; } $search = ['{SHEETS}', '{APP}']; - $replace = [$s, $this->application]; + $replace = [$s, $this->esc($this->application)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'docProps/app.xml') { $search = ['{APP}', '{COMPANY}', '{MANAGER}']; - $replace = [$this->application, $this->company, $this->manager]; + $replace = [$this->esc($this->application), $this->esc($this->company), $this->esc($this->manager)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'docProps/core.xml') { - $search = ['{DATE}', '{AUTHOR}', '{TITLE}', '{SUBJECT}', '{KEYWORD}', '{DESCRIPTION}', '{CATEGORY}']; - $replace = [gmdate('Y-m-d\TH:i:s\Z'), $this->author, $this->title, $this->subject, $this->keywords, $this->description, $this->category]; + $search = ['{DATE}', '{AUTHOR}', '{TITLE}', '{SUBJECT}', '{KEYWORD}', '{DESCRIPTION}', '{CATEGORY}', '{LAST_MODIFY_BY}']; + $replace = [gmdate('Y-m-d\TH:i:s\Z'), $this->esc($this->author), $this->esc($this->title), $this->esc($this->subject), $this->esc($this->keywords), $this->esc($this->description), $this->esc($this->category), $this->esc($this->lastModifiedBy)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; @@ -1069,6 +1072,11 @@ class SimpleXLSXGen $this->application = $application; return $this; } + public function setLastModifiedBy($lastModifiedBy) + { + $this->lastModifiedBy = $lastModifiedBy; + return $this; + } public function autoFilter($range) { From 3646e702ae471d3ea256f51bc8afe02c9c24c24b Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Wed, 19 Apr 2023 02:38:08 -0500 Subject: [PATCH 4/4] * escape strings * use fluid interface and ' + Add LastModifiedBy + author, company, manager, LastModifiedBy set email --- README.md | 19 ++++++++++--------- src/SimpleXLSXGen.php | 23 ++++++++++++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 11e0d82..6d8fdb8 100644 --- a/README.md +++ b/README.md @@ -144,15 +144,16 @@ $xlsx->rightToLeft(); // Set Meta Data Files // this data in propertis Files and Info file in Office -$xlsx->setAuthor("Sergey Shuchkin") -$xlsx->setCompany("Sergey Shuchkin Company") -$xlsx->setManager("Sergey Shuchkin Manager") -$xlsx->setTitle("This is Title") -$xlsx->setSubject("This is Subject") -$xlsx->setKeywords("Keywords1, Keywords2, Keywords3, KeywordsN") -$xlsx->setDescription("This is Description") -$xlsx->setCategory("This is Сategory") -$xlsx->setApplication("This Is Best Application For Generate") +$xlsx->setAuthor('Sergey Shuchkin ') + ->setCompany('Microsoft ') + ->setManager('Bill Gates ') + ->setLastModifiedBy("Sergey Shuchkin ") + ->setTitle('This is Title') + ->setSubject('This is Subject') + ->setKeywords('Keywords1, Keywords2, Keywords3, KeywordsN') + ->setDescription('This is Description') + ->setCategory('This is Сategory') + ->setApplication('Shuchkin\SimpleXLSXGen') ``` ### JS array to Excel (AJAX) ```php diff --git a/src/SimpleXLSXGen.php b/src/SimpleXLSXGen.php index 1233d26..2ee9e0f 100644 --- a/src/SimpleXLSXGen.php +++ b/src/SimpleXLSXGen.php @@ -39,6 +39,7 @@ class SimpleXLSXGen protected $application; protected $keywords; protected $category; + protected $lastModifiedBy; const N_NORMAL = 0; // General const N_INT = 1; // 0 const N_DEC = 2; // 0.00 @@ -92,12 +93,13 @@ class SimpleXLSXGen { $this->subject = ''; $this->title = ''; - $this->author = 'Sergey Shuchkin'; - $this->company = 'Sergey Shuchkin'; - $this->manager = 'Sergey Shuchkin'; + $this->author = 'Sergey Shuchkin '; + $this->company = 'Sergey Shuchkin '; + $this->manager = 'Sergey Shuchkin '; $this->description = ''; $this->keywords = ''; $this->category = ''; + $this->lastModifiedBy = 'Sergey Shuchkin '; $this->application = __CLASS__; $this->curSheet = -1; @@ -160,6 +162,7 @@ class SimpleXLSXGen {TITLE} {SUBJECT} {AUTHOR} + {LAST_MODIFY_BY} {KEYWORD} {DESCRIPTION} {CATEGORY} @@ -342,19 +345,19 @@ class SimpleXLSXGen $s .= ''; } $search = ['{SHEETS}', '{APP}']; - $replace = [$s, $this->application]; + $replace = [$s, $this->esc($this->application)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'docProps/app.xml') { $search = ['{APP}', '{COMPANY}', '{MANAGER}']; - $replace = [$this->application, $this->company, $this->manager]; + $replace = [$this->esc($this->application), $this->esc($this->company), $this->esc($this->manager)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; } elseif ($cfilename === 'docProps/core.xml') { - $search = ['{DATE}', '{AUTHOR}', '{TITLE}', '{SUBJECT}', '{KEYWORD}', '{DESCRIPTION}', '{CATEGORY}']; - $replace = [gmdate('Y-m-d\TH:i:s\Z'), $this->author, $this->title, $this->subject, $this->keywords, $this->description, $this->category]; + $search = ['{DATE}', '{AUTHOR}', '{TITLE}', '{SUBJECT}', '{KEYWORD}', '{DESCRIPTION}', '{CATEGORY}', '{LAST_MODIFY_BY}']; + $replace = [gmdate('Y-m-d\TH:i:s\Z'), $this->esc($this->author), $this->esc($this->title), $this->esc($this->subject), $this->esc($this->keywords), $this->esc($this->description), $this->esc($this->category), $this->esc($this->lastModifiedBy)]; $template = str_replace($search, $replace, $template); $this->_writeEntry($fh, $cdrec, $cfilename, $template); $entries++; @@ -1070,6 +1073,12 @@ class SimpleXLSXGen return $this; } + public function setLastModifiedBy($lastModifiedBy) + { + $this->lastModifiedBy = $lastModifiedBy; + return $this; + } + public function autoFilter($range) { $this->sheets[$this->curSheet]['autofilter'] = $range;