Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 $pSheet Worksheet 18 * @param string[] $pExistingTable Existing table to eventually merge with 19 * 20 * @return string[] String table for worksheet 21 */ 22 public function createStringTable(Worksheet $pSheet, $pExistingTable = 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 (($pExistingTable !== null) && is_array($pExistingTable)) { 31 $aStringTable = $pExistingTable; 32 } 33 34 // Fill index array 35 $aFlippedStringTable = $this->flipStringTable($aStringTable); 36 37 // Loop through cells 38 foreach ($pSheet->getCoordinates() as $coordinate) { 39 $cell = $pSheet->getCell($coordinate); 40 $cellValue = $cell->getValue(); 41 if ( 42 !is_object($cellValue) && 43 ($cellValue !== null) && 44 $cellValue !== '' && 45 !isset($aFlippedStringTable[$cellValue]) && 46 ($cell->getDataType() == DataType::TYPE_STRING || $cell->getDataType() == DataType::TYPE_STRING2 || $cell->getDataType() == DataType::TYPE_NULL) 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[] $pStringTable 67 * 68 * @return string XML Output 69 */ 70 public function writeStringTable(array $pStringTable) 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($pStringTable)); 87 88 // Loop through string table 89 foreach ($pStringTable 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 XMLWriter $objWriter XML Writer 116 * @param RichText $pRichText Rich text 117 * @param string $prefix Optional Namespace prefix 118 */ 119 public function writeRichText(XMLWriter $objWriter, RichText $pRichText, $prefix = null): void 120 { 121 if ($prefix !== null) { 122 $prefix .= ':'; 123 } 124 125 // Loop through rich text elements 126 $elements = $pRichText->getRichTextElements(); 127 foreach ($elements as $element) { 128 // r 129 $objWriter->startElement($prefix . 'r'); 130 131 // rPr 132 if ($element instanceof Run) { 133 // rPr 134 $objWriter->startElement($prefix . 'rPr'); 135 136 // rFont 137 $objWriter->startElement($prefix . 'rFont'); 138 $objWriter->writeAttribute('val', $element->getFont()->getName()); 139 $objWriter->endElement(); 140 141 // Bold 142 $objWriter->startElement($prefix . 'b'); 143 $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); 144 $objWriter->endElement(); 145 146 // Italic 147 $objWriter->startElement($prefix . 'i'); 148 $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); 149 $objWriter->endElement(); 150 151 // Superscript / subscript 152 if ($element->getFont()->getSuperscript() || $element->getFont()->getSubscript()) { 153 $objWriter->startElement($prefix . 'vertAlign'); 154 if ($element->getFont()->getSuperscript()) { 155 $objWriter->writeAttribute('val', 'superscript'); 156 } elseif ($element->getFont()->getSubscript()) { 157 $objWriter->writeAttribute('val', 'subscript'); 158 } 159 $objWriter->endElement(); 160 } 161 162 // Strikethrough 163 $objWriter->startElement($prefix . 'strike'); 164 $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); 165 $objWriter->endElement(); 166 167 // Color 168 $objWriter->startElement($prefix . 'color'); 169 $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); 170 $objWriter->endElement(); 171 172 // Size 173 $objWriter->startElement($prefix . 'sz'); 174 $objWriter->writeAttribute('val', $element->getFont()->getSize()); 175 $objWriter->endElement(); 176 177 // Underline 178 $objWriter->startElement($prefix . 'u'); 179 $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); 180 $objWriter->endElement(); 181 182 $objWriter->endElement(); 183 } 184 185 // t 186 $objWriter->startElement($prefix . 't'); 187 $objWriter->writeAttribute('xml:space', 'preserve'); 188 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText())); 189 $objWriter->endElement(); 190 191 $objWriter->endElement(); 192 } 193 } 194 195 /** 196 * Write Rich Text. 197 * 198 * @param XMLWriter $objWriter XML Writer 199 * @param RichText|string $pRichText text string or Rich text 200 * @param string $prefix Optional Namespace prefix 201 */ 202 public function writeRichTextForCharts(XMLWriter $objWriter, $pRichText = null, $prefix = null): void 203 { 204 if (!$pRichText instanceof RichText) { 205 $textRun = $pRichText; 206 $pRichText = new RichText(); 207 $pRichText->createTextRun($textRun); 208 } 209 210 if ($prefix !== null) { 211 $prefix .= ':'; 212 } 213 214 // Loop through rich text elements 215 $elements = $pRichText->getRichTextElements(); 216 foreach ($elements as $element) { 217 // r 218 $objWriter->startElement($prefix . 'r'); 219 220 // rPr 221 $objWriter->startElement($prefix . 'rPr'); 222 223 // Bold 224 $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); 225 // Italic 226 $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); 227 // Underline 228 $underlineType = $element->getFont()->getUnderline(); 229 switch ($underlineType) { 230 case 'single': 231 $underlineType = 'sng'; 232 233 break; 234 case 'double': 235 $underlineType = 'dbl'; 236 237 break; 238 } 239 $objWriter->writeAttribute('u', $underlineType); 240 // Strikethrough 241 $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); 242 243 // rFont 244 $objWriter->startElement($prefix . 'latin'); 245 $objWriter->writeAttribute('typeface', $element->getFont()->getName()); 246 $objWriter->endElement(); 247 248 $objWriter->endElement(); 249 250 // t 251 $objWriter->startElement($prefix . 't'); 252 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($element->getText())); 253 $objWriter->endElement(); 254 255 $objWriter->endElement(); 256 } 257 } 258 259 /** 260 * Flip string table (for index searching). 261 * 262 * @param array $stringTable Stringtable 263 * 264 * @return array 265 */ 266 public function flipStringTable(array $stringTable) 267 { 268 // Return value 269 $returnValue = []; 270 271 // Loop through stringtable and add flipped items to $returnValue 272 foreach ($stringTable as $key => $value) { 273 if (!$value instanceof RichText) { 274 $returnValue[$value] = $key; 275 } elseif ($value instanceof RichText) { 276 $returnValue[$value->getHashCode()] = $key; 277 } 278 } 279 280 return $returnValue; 281 } 282 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body