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