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