Skip to content

Commit ffeaa42

Browse files
committed
Emulate Xlsx More Closely
Xlsx conditional styles cannot be used to change alignment, nor font family, nor font size. Conditional::getStyle currently allocates a new style as an unconditional style; it is changed to do so a conditional ctyle. Border should not be conditionally merged if borderStyle is OMIT. Inline Css was generating `class="gridlines gridlinesp"` for all cells. It is changed to use the worksheet settings to decide which classes to use.
1 parent a150917 commit ffeaa42

File tree

7 files changed

+57
-38
lines changed

7 files changed

+57
-38
lines changed

src/PhpSpreadsheet/Style/Conditional.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ public function addCondition($condition): static
272272
public function getStyle(mixed $cellData = null): Style
273273
{
274274
if ($this->conditionType === self::CONDITION_COLORSCALE && $cellData !== null && $this->colorScale !== null && is_numeric($cellData)) {
275-
$style = new Style();
275+
$style = new Style(isConditional: true);
276276
$style->getFill()->setFillType(Fill::FILL_SOLID);
277277
$style->getFill()->getStartColor()->setARGB($this->colorScale->getColorForValue((float) $cellData));
278278

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,13 +1046,13 @@ public function buildCSS(bool $generateSurroundingHTML = true): array
10461046
*
10471047
* @return string[]
10481048
*/
1049-
private function createCSSStyle(Style $style): array
1049+
private function createCSSStyle(Style $style, bool $conditional = false): array
10501050
{
10511051
// Create CSS
10521052
return array_merge(
1053-
$this->createCSSStyleAlignment($style->getAlignment()),
1053+
$conditional ? [] : $this->createCSSStyleAlignment($style->getAlignment()),
10541054
$this->createCSSStyleBorders($style->getBorders()),
1055-
$this->createCSSStyleFont($style->getFont()),
1055+
$this->createCSSStyleFont($style->getFont(), conditional: $conditional),
10561056
$this->createCSSStyleFill($style->getFill())
10571057
);
10581058
}
@@ -1096,7 +1096,7 @@ private function createCSSStyleAlignment(Alignment $alignment): array
10961096
*
10971097
* @return string[]
10981098
*/
1099-
private function createCSSStyleFont(Font $font, bool $useDefaults = false): array
1099+
private function createCSSStyleFont(Font $font, bool $useDefaults = false, bool $conditional = false): array
11001100
{
11011101
// Construct CSS
11021102
$css = [];
@@ -1123,12 +1123,29 @@ private function createCSSStyleFont(Font $font, bool $useDefaults = false): arra
11231123
}
11241124

11251125
$css['color'] = '#' . $font->getColor()->getRGB();
1126-
$css['font-family'] = '\'' . htmlspecialchars((string) $font->getName(), ENT_QUOTES) . '\'';
1127-
$css['font-size'] = $font->getSize() . 'pt';
1126+
if (!$conditional) {
1127+
$css['font-family'] = '\'' . htmlspecialchars((string) $font->getName(), ENT_QUOTES) . '\'';
1128+
$css['font-size'] = $font->getSize() . 'pt';
1129+
}
11281130

11291131
return $css;
11301132
}
11311133

1134+
/**
1135+
* @param string[] $css
1136+
*/
1137+
private function styleBorder(array &$css, string $index, Border $border): void
1138+
{
1139+
$borderStyle = $border->getBorderStyle();
1140+
// Mpdf doesn't process !important, so omit unimportant border none
1141+
if ($borderStyle === Border::BORDER_NONE && $this instanceof Pdf\Mpdf) {
1142+
return;
1143+
}
1144+
if ($borderStyle !== Border::BORDER_OMIT) {
1145+
$css[$index] = $this->createCSSStyleBorder($border);
1146+
}
1147+
}
1148+
11321149
/**
11331150
* Create CSS style.
11341151
*
@@ -1142,26 +1159,10 @@ private function createCSSStyleBorders(Borders $borders): array
11421159
$css = [];
11431160

11441161
// Create CSS
1145-
if (!($this instanceof Pdf\Mpdf)) {
1146-
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
1147-
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
1148-
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
1149-
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
1150-
} else {
1151-
// Mpdf doesn't process !important, so omit unimportant border none
1152-
if ($borders->getBottom()->getBorderStyle() !== Border::BORDER_NONE) {
1153-
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
1154-
}
1155-
if ($borders->getTop()->getBorderStyle() !== Border::BORDER_NONE) {
1156-
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
1157-
}
1158-
if ($borders->getLeft()->getBorderStyle() !== Border::BORDER_NONE) {
1159-
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
1160-
}
1161-
if ($borders->getRight()->getBorderStyle() !== Border::BORDER_NONE) {
1162-
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
1163-
}
1164-
}
1162+
$this->styleBorder($css, 'border-bottom', $borders->getBottom());
1163+
$this->styleBorder($css, 'border-top', $borders->getTop());
1164+
$this->styleBorder($css, 'border-left', $borders->getLeft());
1165+
$this->styleBorder($css, 'border-right', $borders->getRight());
11651166

11661167
return $css;
11671168
}
@@ -1594,7 +1595,15 @@ private function generateRowWriteCell(
15941595
/** @var string[] $xcssClass */
15951596
$holdCss = $this->assembleCSS($xcssClass);
15961597
if ($this->useInlineCss) {
1597-
$html .= ' class="gridlines gridlinesp"';
1598+
$prntgrid = $worksheet->getPrintGridlines();
1599+
$viewgrid = $this->isPdf ? $prntgrid : $worksheet->getShowGridlines();
1600+
if ($viewgrid && $prntgrid) {
1601+
$html .= ' class="gridlines gridlinesp"';
1602+
} elseif ($viewgrid) {
1603+
$html .= ' class="gridlines"';
1604+
} elseif ($prntgrid) {
1605+
$html .= ' class="gridlinesp"';
1606+
}
15981607
}
15991608
}
16001609

@@ -1642,9 +1651,12 @@ private function generateRowWriteCell(
16421651
}
16431652
}
16441653
if ($matched) {
1645-
$styles = $this->createCSSStyle($styleMerger->getStyle());
1646-
$html .= ' style="' . $holdCss . ' ';
1647-
$holdCss = '';
1654+
$styles = $this->createCSSStyle($styleMerger->getStyle(), true);
1655+
$html .= ' style="';
1656+
if ($holdCss !== '') {
1657+
$html .= "$holdCss; ";
1658+
$holdCss = '';
1659+
}
16481660
foreach ($styles as $key => $value) {
16491661
$html .= $key . ':' . $value . ';';
16501662
}

tests/PhpSpreadsheetTests/Writer/Html/BetterBooleanTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public function testInline(): void
139139
{
140140
$spreadsheet = new Spreadsheet();
141141
$sheet = $spreadsheet->getActiveSheet();
142+
$sheet->setPrintGridlines(true);
142143
$sheet->getCell('A1')->setValue(1);
143144
$sheet->getCell('B1')->setValue('Hello');
144145
$sheet->getCell('C1')->setValue(true);

tests/PhpSpreadsheetTests/Writer/Html/Issue3678Test.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public function testInlineAndNot(): void
1515
{
1616
$spreadsheet = new Spreadsheet();
1717
$sheet = $spreadsheet->getActiveSheet();
18+
$sheet->setShowGridlines(false);
19+
$sheet->setPrintGridlines(true);
1820
$sheet->getCell('A1')->setValue(1);
1921
$styleArray = [
2022
'fill' => [
@@ -34,7 +36,10 @@ public function testInlineAndNot(): void
3436
self::assertStringContainsString('.n { text-align:right }', $html);
3537
$writer->setUseInlineCss(true);
3638
$html = $writer->generateHtmlAll();
37-
self::assertStringContainsString('<td class="gridlines gridlinesp" style="' . $style2 . '">1</td>', $html);
39+
self::assertStringContainsString('<td class="gridlinesp" style="' . $style2 . '">1</td>', $html);
40+
$sheet->setPrintGridlines(false);
41+
$html = $writer->generateHtmlAll();
42+
self::assertStringContainsString('<td style="' . $style2 . '">1</td>', $html);
3843
$spreadsheet->disconnectWorksheets();
3944
}
4045
}

tests/PhpSpreadsheetTests/Writer/Html/Issue4539Test.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ public function testInlineAndNot(): void
1919
$writer->setConditionalFormatting(true);
2020
$writer->setUseInlineCss(true);
2121
$html = $writer->generateHtmlAll();
22-
$expected = '<td class="gridlines gridlinesp" style="vertical-align:bottom; color:#000000; font-family:\'Aptos Narrow\'; font-size:12pt; text-align:right; width:102pt vertical-align:bottom;border-bottom:none #000000;border-top:none #000000;border-left:none #000000;border-right:none #000000;color:#000000;font-family:\'Aptos Narrow\';font-size:12pt;background-color:#5A8AC6;">5</td>';
22+
$expected = '<td class="gridlines" style="vertical-align:bottom; color:#000000; font-family:\'Aptos Narrow\'; font-size:12pt; text-align:right; width:102pt; color:#000000;background-color:#5A8AC6;">5</td>';
2323
self::assertStringContainsString($expected, $html, 'inline conditional style');
24-
$expected = '<td class="gridlines gridlinesp" style="vertical-align:bottom; font-weight:bold; color:#000000; font-family:\'Aptos Narrow\'; font-size:12pt; text-align:left; width:102pt">Column Heading</td>';
24+
$expected = '<td class="gridlines" style="vertical-align:bottom; font-weight:bold; color:#000000; font-family:\'Aptos Narrow\'; font-size:12pt; text-align:left; width:102pt">Column Heading</td>';
2525
self::assertStringContainsString($expected, $html, 'inline no conditional style');
2626

2727
$writer->setUseInlineCss(false);
2828
$html = $writer->generateHtmlAll();
29-
$expected = '<td class="column0 style2 n" style=" vertical-align:bottom;border-bottom:none #000000;border-top:none #000000;border-left:none #000000;border-right:none #000000;color:#000000;font-family:\'Aptos Narrow\';font-size:12pt;background-color:#5A8AC6;">5</td>';
29+
$expected = '<td class="column0 style2 n" style="color:#000000;background-color:#5A8AC6;">5</td>';
3030
self::assertStringContainsString($expected, $html, 'notinline conditional style');
3131
$expected = '<td class="column0 style1 s">Column Heading</td>';
3232
self::assertStringContainsString($expected, $html, 'notinline no conditional style');

tests/PhpSpreadsheetTests/Writer/Html/NoTitleTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function testNoTitle(): void
2323
$writer->setUseInlineCss(true);
2424
$html = $writer->generateHTMLAll();
2525
self::assertStringContainsString('<title>Sheet1</title>', $html);
26-
self::assertStringContainsString('<td class="gridlines gridlinesp" style="vertical-align:bottom; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:left; width:42pt">C1</td>', $html);
26+
self::assertStringContainsString('<td class="gridlines" style="vertical-align:bottom; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:left; width:42pt">C1</td>', $html);
2727
$writer->setUseInlineCss(false);
2828
$html = $writer->generateHTMLAll();
2929
self::assertStringContainsString('<td class="column2 style0 s">C1</td>', $html);
@@ -55,8 +55,8 @@ public function testHideSomeGridlines(): void
5555
$writer = new Html($spreadsheet);
5656
$writer->setUseInlineCss(true);
5757
$html = $writer->generateHTMLAll();
58-
self::assertStringContainsString('<td class="gridlines gridlinesp" style="vertical-align:bottom; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:right; width:42pt">7</td>', $html);
59-
self::assertStringContainsString('<td class="gridlines gridlinesp" style="vertical-align:bottom; border-bottom:none #808080; border-top:none #808080; border-left:none #808080; border-right:none #808080; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:right; width:42pt">19</td>', $html);
58+
self::assertStringContainsString('<td class="gridlines" style="vertical-align:bottom; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:right; width:42pt">7</td>', $html);
59+
self::assertStringContainsString('<td class="gridlines" style="vertical-align:bottom; border-bottom:none #808080; border-top:none #808080; border-left:none #808080; border-right:none #808080; color:#000000; font-family:\'Calibri\'; font-size:11pt; text-align:right; width:42pt">19</td>', $html);
6060
$spreadsheet->disconnectWorksheets();
6161
}
6262
}

tests/PhpSpreadsheetTests/Writer/Tcpdf/HideMergeTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public function testHideWithMerge(): void
1717
{
1818
$spreadsheet = new Spreadsheet();
1919
$worksheet = $spreadsheet->getActiveSheet();
20+
$worksheet->setPrintGridlines(true);
2021
// just some labels for better visualisation of the problem
2122
$worksheet->setCellValue('A1', 'A');
2223
$worksheet->setCellValue('B1', 'B');

0 commit comments

Comments
 (0)