Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; 4 5 use PhpOffice\PhpSpreadsheet\Cell\DataType; 6 use PhpOffice\PhpSpreadsheet\RichText\RichText; 7 use PhpOffice\PhpSpreadsheet\RichText\Run; 8 use PhpOffice\PhpSpreadsheet\Shared\StringHelper; 9 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; 10 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; 11 12 class StringTable extends WriterPart 13 { 14 /** 15 * Create worksheet stringtable. 16 * 17 * @param Worksheet $worksheet Worksheet 18 * @param string[] $existingTable Existing table to eventually merge with 19 * 20 * @return string[] String table for worksheet 21 */ 22 public function createStringTable(Worksheet $worksheet, $existingTable = null) 23 { 24 // Create string lookup table 25 $aStringTable = []; 26 $cellCollection = null; 27 $aFlippedStringTable = null; // For faster lookup 28 29 // Is an existing table given? 30 if (($existingTable !== null) && is_array($existingTable)) { 31 $aStringTable = $existingTable; 32 } 33 34 // Fill index array 35 $aFlippedStringTable = $this->flipStringTable($aStringTable); 36 37 // Loop through cells 38 foreach ($worksheet->getCoordinates() as $coordinate) { 39 $cell = $worksheet->getCell($coordinate); 40 $cellValue = $cell->getValue(); 41 if ( 42 !is_object($cellValue) && 43 ($cellValue !== null) && 44 $cellValue !== '' && 45 ($cell->getDataType() == DataType::TYPE_STRING || $cell->getDataType() == DataType::TYPE_STRING2 || $cell->getDataType() == DataType::TYPE_NULL) && 46 !isset($aFlippedStringTable[$cellValue]) 47 ) { 48 $aStringTable[] = $cellValue; 49 $aFlippedStringTable[$cellValue] = true; 50 } elseif ( 51 $cellValue instanceof RichText && 52 ($cellValue !== null) && 53 !isset($aFlippedStringTable[$cellValue->getHashCode()]) 54 ) { 55 $aStringTable[] = $cellValue; 56 $aFlippedStringTable[$cellValue->getHashCode()] = true; 57 } 58 } 59 60 return $aStringTable; 61 } 62 63 /** 64 * Write string table to XML format. 65 * 66 * @param string[] $stringTable 67 * 68 * @return string XML Output 69 */ 70 public function writeStringTable(array $stringTable) 71 { 72 // Create XML writer 73 $objWriter = null; 74 if ($this->getParentWriter()->getUseDiskCaching()) { 75 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 76 } else { 77 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 78 } 79 80 // XML header 81 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 82 83 // String table 84 $objWriter->startElement('sst'); 85 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); 86 $objWriter->writeAttribute('uniqueCount', count($stringTable)); 87 88 // Loop through string table 89 foreach ($stringTable as $textElement) { 90 $objWriter->startElement('si'); 91 92 if (!$textElement instanceof RichText) { 93 $textToWrite = StringHelper::controlCharacterPHP2OOXML($textElement); 94 $objWriter->startElement('t'); 95 if ($textToWrite !== trim($textToWrite)) { 96 $objWriter->writeAttribute('xml:space', 'preserve'); 97 } 98 $objWriter->writeRawData($textToWrite); 99 $objWriter->endElement(); 100 } elseif ($textElement instanceof RichText) { 101 $this->writeRichText($objWriter, $textElement); 102 } 103 104 $objWriter->endElement(); 105 } 106 107 $objWriter->endElement(); 108 109 return $objWriter->getData(); 110 } 111 112 /** 113 * Write Rich Text. 114 * 115 * @param string $prefix Optional Namespace prefix 116 */ 117 public function writeRichText(XMLWriter $objWriter, RichText $richText, $prefix = null): void 118 { 119 if ($prefix !== null) { 120 $prefix .= ':'; 121 } 122 123 // Loop through rich text elements 124 $elements = $richText->getRichTextElements(); 125 foreach ($elements as $element) { 126 // r 127 $objWriter->startElement($prefix . 'r'); 128 129 // rPr 130 if ($element instanceof Run) { 131 // rPr 132 $objWriter->startElement($prefix . 'rPr'); 133 134 // rFont 135 $objWriter->startElement($prefix . 'rFont'); 136 $objWriter->writeAttribute('val', $element->getFont()->getName()); 137 $objWriter->endElement(); 138 139 // Bold 140 $objWriter->startElement($prefix . 'b'); 141 $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); 142 $objWriter->endElement(); 143 144 // Italic 145 $objWriter->startElement($prefix . 'i'); 146 $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); 147 $objWriter->endElement(); 148 149 // Superscript / subscript 150 if ($element->getFont()->getSuperscript() || $element->getFont()->getSubscript()) { 151 $objWriter->startElement($prefix . 'vertAlign'); 152 if ($element->getFont()->getSuperscript()) { 153 $objWriter->writeAttribute('val', 'superscript'); 154 } elseif ($element->getFont()->getSubscript()) { 155 $objWriter->writeAttribute('val', 'subscript'); 156 } 157 $objWriter->endElement(); 158 } 159 160 // Strikethrough 161 $objWriter->startElement($prefix . 'strike'); 162 $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); 163 $objWriter->endElement(); 164 165 // Color 166 $objWriter->startElement($prefix . 'color'); 167 $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); 168 $objWriter->endElement(); 169 170 // Size 171 $objWriter->startElement($prefix . 'sz'); 172 $objWriter->writeAttribute('val', $element->getFont()->getSize()); 173 $objWriter->endElement(); 174 175 // Underline 176 $objWriter->startElement($prefix . 'u'); 177 $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); 178 $objWriter->endElement(); 179 180 $objWriter->endElement(); 181 } 182 183 // t 184 $objWriter->startElement($prefix . 't'); 185 $objWriter->writeAttribute('xml:space', 'preserve'); 186 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText())); 187 $objWriter->endElement(); 188 189 $objWriter->endElement(); 190 } 191 } 192 193 /** 194 * Write Rich Text. 195 * 196 * @param RichText|string $richText text string or Rich text 197 * @param string $prefix Optional Namespace prefix 198 */ 199 public function writeRichTextForCharts(XMLWriter $objWriter, $richText = null, $prefix = null): void 200 { 201 if (!$richText instanceof RichText) { 202 $textRun = $richText; 203 $richText = new RichText(); 204 $richText->createTextRun($textRun); 205 } 206 207 if ($prefix !== null) { 208 $prefix .= ':'; 209 } 210 211 // Loop through rich text elements 212 $elements = $richText->getRichTextElements(); 213 foreach ($elements as $element) { 214 // r 215 $objWriter->startElement($prefix . 'r'); 216 217 // rPr 218 $objWriter->startElement($prefix . 'rPr'); 219 220 // Bold 221 $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); 222 // Italic 223 $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); 224 // Underline 225 $underlineType = $element->getFont()->getUnderline(); 226 switch ($underlineType) { 227 case 'single': 228 $underlineType = 'sng'; 229 230 break; 231 case 'double': 232 $underlineType = 'dbl'; 233 234 break; 235 } 236 $objWriter->writeAttribute('u', $underlineType); 237 // Strikethrough 238 $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); 239 240 // rFont 241 $objWriter->startElement($prefix . 'latin'); 242 $objWriter->writeAttribute('typeface', $element->getFont()->getName()); 243 $objWriter->endElement(); 244 245 $objWriter->endElement(); 246 247 // t 248 $objWriter->startElement($prefix . 't'); 249 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText())); 250 $objWriter->endElement(); 251 252 $objWriter->endElement(); 253 } 254 } 255 256 /** 257 * Flip string table (for index searching). 258 * 259 * @param array $stringTable Stringtable 260 * 261 * @return array 262 */ 263 public function flipStringTable(array $stringTable) 264 { 265 // Return value 266 $returnValue = []; 267 268 // Loop through stringtable and add flipped items to $returnValue 269 foreach ($stringTable as $key => $value) { 270 if (!$value instanceof RichText) { 271 $returnValue[$value] = $key; 272 } elseif ($value instanceof RichText) { 273 $returnValue[$value->getHashCode()] = $key; 274 } 275 } 276 277 return $returnValue; 278 } 279 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body