See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 3 namespace Box\Spout\Writer\XLSX\Manager; 4 5 use Box\Spout\Common\Exception\IOException; 6 use Box\Spout\Common\Helper\Escaper; 7 8 /** 9 * Class SharedStringsManager 10 * This class provides functions to write shared strings 11 */ 12 class SharedStringsManager 13 { 14 const SHARED_STRINGS_FILE_NAME = 'sharedStrings.xml'; 15 16 const SHARED_STRINGS_XML_FILE_FIRST_PART_HEADER = <<<'EOD' 17 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 18 <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" 19 EOD; 20 21 /** 22 * This number must be really big so that the no generated file will have more strings than that. 23 * If the strings number goes above, characters will be overwritten in an unwanted way and will corrupt the file. 24 */ 25 const DEFAULT_STRINGS_COUNT_PART = 'count="9999999999999" uniqueCount="9999999999999"'; 26 27 /** @var resource Pointer to the sharedStrings.xml file */ 28 protected $sharedStringsFilePointer; 29 30 /** @var int Number of shared strings already written */ 31 protected $numSharedStrings = 0; 32 33 /** @var Escaper\XLSX Strings escaper */ 34 protected $stringsEscaper; 35 36 /** 37 * @param string $xlFolder Path to the "xl" folder 38 * @param Escaper\XLSX $stringsEscaper Strings escaper 39 */ 40 public function __construct($xlFolder, $stringsEscaper) 41 { 42 $sharedStringsFilePath = $xlFolder . '/' . self::SHARED_STRINGS_FILE_NAME; 43 $this->sharedStringsFilePointer = \fopen($sharedStringsFilePath, 'w'); 44 45 $this->throwIfSharedStringsFilePointerIsNotAvailable(); 46 47 // the headers is split into different parts so that we can fseek and put in the correct count and uniqueCount later 48 $header = self::SHARED_STRINGS_XML_FILE_FIRST_PART_HEADER . ' ' . self::DEFAULT_STRINGS_COUNT_PART . '>'; 49 \fwrite($this->sharedStringsFilePointer, $header); 50 51 $this->stringsEscaper = $stringsEscaper; 52 } 53 54 /** 55 * Checks if the book has been created. Throws an exception if not created yet. 56 * 57 * @throws \Box\Spout\Common\Exception\IOException If the sheet data file cannot be opened for writing 58 * @return void 59 */ 60 protected function throwIfSharedStringsFilePointerIsNotAvailable() 61 { 62 if (!$this->sharedStringsFilePointer) { 63 throw new IOException('Unable to open shared strings file for writing.'); 64 } 65 } 66 67 /** 68 * Writes the given string into the sharedStrings.xml file. 69 * Starting and ending whitespaces are preserved. 70 * 71 * @param string $string 72 * @return int ID of the written shared string 73 */ 74 public function writeString($string) 75 { 76 \fwrite($this->sharedStringsFilePointer, '<si><t xml:space="preserve">' . $this->stringsEscaper->escape($string) . '</t></si>'); 77 $this->numSharedStrings++; 78 79 // Shared string ID is zero-based 80 return ($this->numSharedStrings - 1); 81 } 82 83 /** 84 * Finishes writing the data in the sharedStrings.xml file and closes the file. 85 * 86 * @return void 87 */ 88 public function close() 89 { 90 if (!\is_resource($this->sharedStringsFilePointer)) { 91 return; 92 } 93 94 \fwrite($this->sharedStringsFilePointer, '</sst>'); 95 96 // Replace the default strings count with the actual number of shared strings in the file header 97 $firstPartHeaderLength = \strlen(self::SHARED_STRINGS_XML_FILE_FIRST_PART_HEADER); 98 $defaultStringsCountPartLength = \strlen(self::DEFAULT_STRINGS_COUNT_PART); 99 100 // Adding 1 to take into account the space between the last xml attribute and "count" 101 \fseek($this->sharedStringsFilePointer, $firstPartHeaderLength + 1); 102 \fwrite($this->sharedStringsFilePointer, \sprintf("%-{$defaultStringsCountPartLength}s", 'count="' . $this->numSharedStrings . '" uniqueCount="' . $this->numSharedStrings . '"')); 103 104 \fclose($this->sharedStringsFilePointer); 105 } 106 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body