See Release Notes
Long Term Support Release
Differences Between: [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Writer\Ods\Cell; 4 5 use PhpOffice\PhpSpreadsheet\Helper\Dimension; 6 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; 7 use PhpOffice\PhpSpreadsheet\Style\Alignment; 8 use PhpOffice\PhpSpreadsheet\Style\Fill; 9 use PhpOffice\PhpSpreadsheet\Style\Font; 10 use PhpOffice\PhpSpreadsheet\Style\Style as CellStyle; 11 use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension; 12 use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension; 13 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; 14 15 class Style 16 { 17 public const CELL_STYLE_PREFIX = 'ce'; 18 public const COLUMN_STYLE_PREFIX = 'co'; 19 public const ROW_STYLE_PREFIX = 'ro'; 20 public const TABLE_STYLE_PREFIX = 'ta'; 21 22 private $writer; 23 24 public function __construct(XMLWriter $writer) 25 { 26 $this->writer = $writer; 27 } 28 29 private function mapHorizontalAlignment(string $horizontalAlignment): string 30 { 31 switch ($horizontalAlignment) { 32 case Alignment::HORIZONTAL_CENTER: 33 case Alignment::HORIZONTAL_CENTER_CONTINUOUS: 34 case Alignment::HORIZONTAL_DISTRIBUTED: 35 return 'center'; 36 case Alignment::HORIZONTAL_RIGHT: 37 return 'end'; 38 case Alignment::HORIZONTAL_FILL: 39 case Alignment::HORIZONTAL_JUSTIFY: 40 return 'justify'; 41 } 42 43 return 'start'; 44 } 45 46 private function mapVerticalAlignment(string $verticalAlignment): string 47 { 48 switch ($verticalAlignment) { 49 case Alignment::VERTICAL_TOP: 50 return 'top'; 51 case Alignment::VERTICAL_CENTER: 52 return 'middle'; 53 case Alignment::VERTICAL_DISTRIBUTED: 54 case Alignment::VERTICAL_JUSTIFY: 55 return 'automatic'; 56 } 57 58 return 'bottom'; 59 } 60 61 private function writeFillStyle(Fill $fill): void 62 { 63 switch ($fill->getFillType()) { 64 case Fill::FILL_SOLID: 65 $this->writer->writeAttribute('fo:background-color', sprintf( 66 '#%s', 67 strtolower($fill->getStartColor()->getRGB()) 68 )); 69 70 break; 71 case Fill::FILL_GRADIENT_LINEAR: 72 case Fill::FILL_GRADIENT_PATH: 73 /// TODO :: To be implemented 74 break; 75 case Fill::FILL_NONE: 76 default: 77 } 78 } 79 80 private function writeCellProperties(CellStyle $style): void 81 { 82 // Align 83 $hAlign = $style->getAlignment()->getHorizontal(); 84 $vAlign = $style->getAlignment()->getVertical(); 85 $wrap = $style->getAlignment()->getWrapText(); 86 87 $this->writer->startElement('style:table-cell-properties'); 88 if (!empty($vAlign) || $wrap) { 89 if (!empty($vAlign)) { 90 $vAlign = $this->mapVerticalAlignment($vAlign); 91 $this->writer->writeAttribute('style:vertical-align', $vAlign); 92 } 93 if ($wrap) { 94 $this->writer->writeAttribute('fo:wrap-option', 'wrap'); 95 } 96 } 97 $this->writer->writeAttribute('style:rotation-align', 'none'); 98 99 // Fill 100 if ($fill = $style->getFill()) { 101 $this->writeFillStyle($fill); 102 } 103 104 $this->writer->endElement(); 105 106 if (!empty($hAlign)) { 107 $hAlign = $this->mapHorizontalAlignment($hAlign); 108 $this->writer->startElement('style:paragraph-properties'); 109 $this->writer->writeAttribute('fo:text-align', $hAlign); 110 $this->writer->endElement(); 111 } 112 } 113 114 protected function mapUnderlineStyle(Font $font): string 115 { 116 switch ($font->getUnderline()) { 117 case Font::UNDERLINE_DOUBLE: 118 case Font::UNDERLINE_DOUBLEACCOUNTING: 119 return'double'; 120 case Font::UNDERLINE_SINGLE: 121 case Font::UNDERLINE_SINGLEACCOUNTING: 122 return'single'; 123 } 124 125 return 'none'; 126 } 127 128 protected function writeTextProperties(CellStyle $style): void 129 { 130 // Font 131 $this->writer->startElement('style:text-properties'); 132 133 $font = $style->getFont(); 134 135 if ($font->getBold()) { 136 $this->writer->writeAttribute('fo:font-weight', 'bold'); 137 $this->writer->writeAttribute('style:font-weight-complex', 'bold'); 138 $this->writer->writeAttribute('style:font-weight-asian', 'bold'); 139 } 140 141 if ($font->getItalic()) { 142 $this->writer->writeAttribute('fo:font-style', 'italic'); 143 } 144 145 if ($color = $font->getColor()) { 146 $this->writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB())); 147 } 148 149 if ($family = $font->getName()) { 150 $this->writer->writeAttribute('fo:font-family', $family); 151 } 152 153 if ($size = $font->getSize()) { 154 $this->writer->writeAttribute('fo:font-size', sprintf('%.1Fpt', $size)); 155 } 156 157 if ($font->getUnderline() && $font->getUnderline() !== Font::UNDERLINE_NONE) { 158 $this->writer->writeAttribute('style:text-underline-style', 'solid'); 159 $this->writer->writeAttribute('style:text-underline-width', 'auto'); 160 $this->writer->writeAttribute('style:text-underline-color', 'font-color'); 161 162 $underline = $this->mapUnderlineStyle($font); 163 $this->writer->writeAttribute('style:text-underline-type', $underline); 164 } 165 166 $this->writer->endElement(); // Close style:text-properties 167 } 168 169 protected function writeColumnProperties(ColumnDimension $columnDimension): void 170 { 171 $this->writer->startElement('style:table-column-properties'); 172 $this->writer->writeAttribute( 173 'style:column-width', 174 round($columnDimension->getWidth(Dimension::UOM_CENTIMETERS), 3) . 'cm' 175 ); 176 $this->writer->writeAttribute('fo:break-before', 'auto'); 177 178 // End 179 $this->writer->endElement(); // Close style:table-column-properties 180 } 181 182 public function writeColumnStyles(ColumnDimension $columnDimension, int $sheetId): void 183 { 184 $this->writer->startElement('style:style'); 185 $this->writer->writeAttribute('style:family', 'table-column'); 186 $this->writer->writeAttribute( 187 'style:name', 188 sprintf('%s_%d_%d', self::COLUMN_STYLE_PREFIX, $sheetId, $columnDimension->getColumnNumeric()) 189 ); 190 191 $this->writeColumnProperties($columnDimension); 192 193 // End 194 $this->writer->endElement(); // Close style:style 195 } 196 197 protected function writeRowProperties(RowDimension $rowDimension): void 198 { 199 $this->writer->startElement('style:table-row-properties'); 200 $this->writer->writeAttribute( 201 'style:row-height', 202 round($rowDimension->getRowHeight(Dimension::UOM_CENTIMETERS), 3) . 'cm' 203 ); 204 $this->writer->writeAttribute('style:use-optimal-row-height', 'false'); 205 $this->writer->writeAttribute('fo:break-before', 'auto'); 206 207 // End 208 $this->writer->endElement(); // Close style:table-row-properties 209 } 210 211 public function writeRowStyles(RowDimension $rowDimension, int $sheetId): void 212 { 213 $this->writer->startElement('style:style'); 214 $this->writer->writeAttribute('style:family', 'table-row'); 215 $this->writer->writeAttribute( 216 'style:name', 217 sprintf('%s_%d_%d', self::ROW_STYLE_PREFIX, $sheetId, $rowDimension->getRowIndex()) 218 ); 219 220 $this->writeRowProperties($rowDimension); 221 222 // End 223 $this->writer->endElement(); // Close style:style 224 } 225 226 public function writeTableStyle(Worksheet $worksheet, int $sheetId): void 227 { 228 $this->writer->startElement('style:style'); 229 $this->writer->writeAttribute('style:family', 'table'); 230 $this->writer->writeAttribute( 231 'style:name', 232 sprintf('%s%d', self::TABLE_STYLE_PREFIX, $sheetId) 233 ); 234 235 $this->writer->startElement('style:table-properties'); 236 237 $this->writer->writeAttribute( 238 'table:display', 239 $worksheet->getSheetState() === Worksheet::SHEETSTATE_VISIBLE ? 'true' : 'false' 240 ); 241 242 $this->writer->endElement(); // Close style:table-properties 243 $this->writer->endElement(); // Close style:style 244 } 245 246 public function write(CellStyle $style): void 247 { 248 $this->writer->startElement('style:style'); 249 $this->writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex()); 250 $this->writer->writeAttribute('style:family', 'table-cell'); 251 $this->writer->writeAttribute('style:parent-style-name', 'Default'); 252 253 // Alignment, fill colour, etc 254 $this->writeCellProperties($style); 255 256 // style:text-properties 257 $this->writeTextProperties($style); 258 259 // End 260 $this->writer->endElement(); // Close style:style 261 } 262 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body