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\Coordinate; 6 use PhpOffice\PhpSpreadsheet\Comment; 7 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; 8 9 class Comments extends WriterPart 10 { 11 /** 12 * Write comments to XML format. 13 * 14 * @return string XML Output 15 */ 16 public function writeComments(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet) 17 { 18 // Create XML writer 19 $objWriter = null; 20 if ($this->getParentWriter()->getUseDiskCaching()) { 21 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 22 } else { 23 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 24 } 25 26 // XML header 27 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 28 29 // Comments cache 30 $comments = $pWorksheet->getComments(); 31 32 // Authors cache 33 $authors = []; 34 $authorId = 0; 35 foreach ($comments as $comment) { 36 if (!isset($authors[$comment->getAuthor()])) { 37 $authors[$comment->getAuthor()] = $authorId++; 38 } 39 } 40 41 // comments 42 $objWriter->startElement('comments'); 43 $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); 44 45 // Loop through authors 46 $objWriter->startElement('authors'); 47 foreach ($authors as $author => $index) { 48 $objWriter->writeElement('author', $author); 49 } 50 $objWriter->endElement(); 51 52 // Loop through comments 53 $objWriter->startElement('commentList'); 54 foreach ($comments as $key => $value) { 55 $this->writeComment($objWriter, $key, $value, $authors); 56 } 57 $objWriter->endElement(); 58 59 $objWriter->endElement(); 60 61 // Return 62 return $objWriter->getData(); 63 } 64 65 /** 66 * Write comment to XML format. 67 * 68 * @param XMLWriter $objWriter XML Writer 69 * @param string $pCellReference Cell reference 70 * @param Comment $pComment Comment 71 * @param array $pAuthors Array of authors 72 */ 73 private function writeComment(XMLWriter $objWriter, $pCellReference, Comment $pComment, array $pAuthors): void 74 { 75 // comment 76 $objWriter->startElement('comment'); 77 $objWriter->writeAttribute('ref', $pCellReference); 78 $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); 79 80 // text 81 $objWriter->startElement('text'); 82 $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); 83 $objWriter->endElement(); 84 85 $objWriter->endElement(); 86 } 87 88 /** 89 * Write VML comments to XML format. 90 * 91 * @return string XML Output 92 */ 93 public function writeVMLComments(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet) 94 { 95 // Create XML writer 96 $objWriter = null; 97 if ($this->getParentWriter()->getUseDiskCaching()) { 98 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); 99 } else { 100 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); 101 } 102 103 // XML header 104 $objWriter->startDocument('1.0', 'UTF-8', 'yes'); 105 106 // Comments cache 107 $comments = $pWorksheet->getComments(); 108 109 // xml 110 $objWriter->startElement('xml'); 111 $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); 112 $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); 113 $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); 114 115 // o:shapelayout 116 $objWriter->startElement('o:shapelayout'); 117 $objWriter->writeAttribute('v:ext', 'edit'); 118 119 // o:idmap 120 $objWriter->startElement('o:idmap'); 121 $objWriter->writeAttribute('v:ext', 'edit'); 122 $objWriter->writeAttribute('data', '1'); 123 $objWriter->endElement(); 124 125 $objWriter->endElement(); 126 127 // v:shapetype 128 $objWriter->startElement('v:shapetype'); 129 $objWriter->writeAttribute('id', '_x0000_t202'); 130 $objWriter->writeAttribute('coordsize', '21600,21600'); 131 $objWriter->writeAttribute('o:spt', '202'); 132 $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); 133 134 // v:stroke 135 $objWriter->startElement('v:stroke'); 136 $objWriter->writeAttribute('joinstyle', 'miter'); 137 $objWriter->endElement(); 138 139 // v:path 140 $objWriter->startElement('v:path'); 141 $objWriter->writeAttribute('gradientshapeok', 't'); 142 $objWriter->writeAttribute('o:connecttype', 'rect'); 143 $objWriter->endElement(); 144 145 $objWriter->endElement(); 146 147 // Loop through comments 148 foreach ($comments as $key => $value) { 149 $this->writeVMLComment($objWriter, $key, $value); 150 } 151 152 $objWriter->endElement(); 153 154 // Return 155 return $objWriter->getData(); 156 } 157 158 /** 159 * Write VML comment to XML format. 160 * 161 * @param XMLWriter $objWriter XML Writer 162 * @param string $pCellReference Cell reference, eg: 'A1' 163 * @param Comment $pComment Comment 164 */ 165 private function writeVMLComment(XMLWriter $objWriter, $pCellReference, Comment $pComment): void 166 { 167 // Metadata 168 [$column, $row] = Coordinate::coordinateFromString($pCellReference); 169 $column = Coordinate::columnIndexFromString($column); 170 $id = 1024 + $column + $row; 171 $id = substr($id, 0, 4); 172 173 // v:shape 174 $objWriter->startElement('v:shape'); 175 $objWriter->writeAttribute('id', '_x0000_s' . $id); 176 $objWriter->writeAttribute('type', '#_x0000_t202'); 177 $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); 178 $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); 179 $objWriter->writeAttribute('o:insetmode', 'auto'); 180 181 // v:fill 182 $objWriter->startElement('v:fill'); 183 $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); 184 $objWriter->endElement(); 185 186 // v:shadow 187 $objWriter->startElement('v:shadow'); 188 $objWriter->writeAttribute('on', 't'); 189 $objWriter->writeAttribute('color', 'black'); 190 $objWriter->writeAttribute('obscured', 't'); 191 $objWriter->endElement(); 192 193 // v:path 194 $objWriter->startElement('v:path'); 195 $objWriter->writeAttribute('o:connecttype', 'none'); 196 $objWriter->endElement(); 197 198 // v:textbox 199 $objWriter->startElement('v:textbox'); 200 $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); 201 202 // div 203 $objWriter->startElement('div'); 204 $objWriter->writeAttribute('style', 'text-align:left'); 205 $objWriter->endElement(); 206 207 $objWriter->endElement(); 208 209 // x:ClientData 210 $objWriter->startElement('x:ClientData'); 211 $objWriter->writeAttribute('ObjectType', 'Note'); 212 213 // x:MoveWithCells 214 $objWriter->writeElement('x:MoveWithCells', ''); 215 216 // x:SizeWithCells 217 $objWriter->writeElement('x:SizeWithCells', ''); 218 219 // x:AutoFill 220 $objWriter->writeElement('x:AutoFill', 'False'); 221 222 // x:Row 223 $objWriter->writeElement('x:Row', ($row - 1)); 224 225 // x:Column 226 $objWriter->writeElement('x:Column', ($column - 1)); 227 228 $objWriter->endElement(); 229 230 $objWriter->endElement(); 231 } 232 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body