Skip to content

Commit 8c70086

Browse files
committed
Html Better Support for Indent
1 parent 9601d87 commit 8c70086

File tree

8 files changed

+56
-10
lines changed

8 files changed

+56
-10
lines changed

src/PhpSpreadsheet/Reader/Html.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,11 @@ private function applyInlineStyle(Worksheet &$sheet, int $row, string $column, a
10951095
break;
10961096

10971097
case 'text-indent':
1098+
$indentDimension = new CssDimension($styleValueString);
1099+
$indent = $indentDimension
1100+
->toUnit(CssDimension::UOM_PIXELS);
10981101
$cellStyle->getAlignment()->setIndent(
1099-
(int) str_replace(['px'], '', $styleValueString)
1102+
(int) ($indent / Alignment::INDENT_UNITS_TO_PIXELS)
11001103
);
11011104

11021105
break;

src/PhpSpreadsheet/Style/Alignment.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class Alignment extends Supervisor
9292
const TEXTROTATION_STACK_EXCEL = 255;
9393
const TEXTROTATION_STACK_PHPSPREADSHEET = -165; // 90 - 255
9494

95+
public const INDENT_UNITS_TO_PIXELS = 9;
96+
9597
/**
9698
* Horizontal alignment.
9799
*/

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,12 @@ private function createCSSStyleAlignment(Alignment $alignment): array
11151115
if ($textAlign) {
11161116
$css['text-align'] = $textAlign;
11171117
if (in_array($textAlign, ['left', 'right'])) {
1118-
$css['padding-' . $textAlign] = (string) ((int) $alignment->getIndent() * 9) . 'px';
1118+
$css['padding-' . $textAlign] = (string) ($alignment->getIndent() * Alignment::INDENT_UNITS_TO_PIXELS) . 'px';
1119+
}
1120+
} else {
1121+
$indent = $alignment->getIndent();
1122+
if ($indent !== 0) {
1123+
$css['text-indent'] = (string) ($alignment->getIndent() * Alignment::INDENT_UNITS_TO_PIXELS) . 'px';
11191124
}
11201125
}
11211126
$rotation = $alignment->getTextRotation();
@@ -1522,7 +1527,6 @@ private function generateRowCellDataValue(Worksheet $worksheet, Cell $cell, stri
15221527
/** @param string|string[] $cssClass */
15231528
private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cell, array|string &$cssClass): string
15241529
{
1525-
$cellData = ' ';
15261530
if ($cell instanceof Cell) {
15271531
$cellData = '';
15281532
// Don't know what this does, and no test cases.
@@ -1571,13 +1575,21 @@ private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cel
15711575
}
15721576
}
15731577
} else {
1578+
$cellData = "$cell";
15741579
// Use default borders for empty cell
15751580
if (is_string($cssClass)) {
15761581
$cssClass .= ' style0';
15771582
}
15781583
}
1584+
/*
1585+
* Browsers may remove an entirely empty row.
1586+
* An interesting option is to leave an empty cell empty using css.
1587+
* td:empty::after{content: "\00a0";}
1588+
* This works well in modern browsers.
1589+
* Alas, none of our Pdf writers can handle it.
1590+
*/
15791591

1580-
return $cellData;
1592+
return (trim($cellData) === '') ? ' ' : $cellData;
15811593
}
15821594

15831595
private function generateRowIncludeCharts(Worksheet $worksheet, string $coordinate): string

tests/PhpSpreadsheetTests/Reader/Html/HtmlTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public function testCanApplyAlignment(): void
199199
<td valign="center">Center valign</td>
200200
<td style="text-align: center;">Center align</td>
201201
<td style="vertical-align: center;">Center valign</td>
202-
<td style="text-indent: 10px;">Text indent</td>
202+
<td style="text-indent: 9px;">Text indent</td>
203203
<td style="word-wrap: break-word;">Wraptext</td>
204204
</tr>
205205
</table>';
@@ -220,7 +220,7 @@ public function testCanApplyAlignment(): void
220220
self::assertEquals(Alignment::VERTICAL_CENTER, $style->getAlignment()->getVertical());
221221

222222
$style = $firstSheet->getCell('E1')->getStyle();
223-
self::assertEquals(10, $style->getAlignment()->getIndent());
223+
self::assertEquals(1, $style->getAlignment()->getIndent());
224224

225225
$style = $firstSheet->getCell('F1')->getStyle();
226226
self::assertTrue($style->getAlignment()->getWrapText());
@@ -302,14 +302,14 @@ public function testTextIndentUseRowspan(): void
302302
</tr>
303303
<tr>
304304
<td>2</td>
305-
<td style="text-indent:10px">Text Indent</td>
305+
<td style="text-indent:9px">Text Indent</td>
306306
</tr>
307307
</table>';
308308
$filename = HtmlHelper::createHtml($html);
309309
$spreadsheet = HtmlHelper::loadHtmlIntoSpreadsheet($filename, true);
310310
$firstSheet = $spreadsheet->getSheet(0);
311311
$style = $firstSheet->getCell('C2')->getStyle();
312-
self::assertEquals(10, $style->getAlignment()->getIndent());
312+
self::assertEquals(1, $style->getAlignment()->getIndent());
313313
$spreadsheet->disconnectWorksheets();
314314
}
315315

tests/PhpSpreadsheetTests/Reader/Xlsx/Issue4248Test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public function testHtml(): void
9393
$data = str_replace(["\r", "\n"], '', $writer->generateHtmlAll());
9494
$expected = ' <tr class="row17">' // Cell D18
9595
. ' <td class="column0 style0">&nbsp;</td>'
96-
. ' <td class="column1 style28 null"></td>'
96+
. ' <td class="column1 style28 null">&nbsp;</td>'
9797
. ' <td class="column2 style35 s">Eligible </td>'
9898
. ' <td class="column3 style70 s">Non</td>';
9999
self::assertStringContainsString($expected, $data, 'Cell D18 style');

tests/PhpSpreadsheetTests/Writer/Html/HtmlColourScaleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function testColourScaleHtmlOutput(): void
5757
['G3', 'background-color:#EC926F;">7<', 'cell G3'],
5858
['H3', 'background-color:#E67C73;">8<', 'cell H3'],
5959
['A4', 'background-color:#57BB8A;">1<', 'cell A4'],
60-
['I4', 'null"><', 'empty cell I4'],
60+
['I4', 'null">&nbsp;<', 'empty cell I4'],
6161
['J4', 'background-color:#E67C73;">10<', 'cell J4'],
6262
];
6363
foreach ($expectedMatches as $expected) {

tests/PhpSpreadsheetTests/Writer/Html/HtmlNumberFormatTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public function testFormatValueWithMask(mixed $expectedResult, mixed $val, strin
151151

152152
$writer = new Html($spreadsheet);
153153
$html = $writer->generateHTMLAll();
154+
$html = str_replace('>&nbsp;<', '><', $html); // clear empty cells
154155
$dom = new DOMDocument();
155156
$dom->loadHTML($html);
156157
$body = $dom->getElementsByTagName('body')->item(0);

tests/PhpSpreadsheetTests/Writer/Html/ReadOrderTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public function testInline(): void
2525
->getAlignment()->setReadOrder(Alignment::READORDER_LTR);
2626
$sheet->getStyle('A2')->getFont()->setName('Arial');
2727
$sheet->getStyle('A3')->getFont()->setName('Times New Roman');
28+
$sheet->setCellValue('A5', 'hello');
29+
$sheet->getStyle('A5')->getFont()->setName('Tahoma');
30+
$sheet->getStyle('A5')
31+
->getAlignment()->setIndent(2);
2832
$writer = new HtmlWriter($spreadsheet);
2933
$writer->setUseInlineCss(true);
3034
$html = $writer->generateHtmlAll();
@@ -40,6 +44,14 @@ public function testInline(): void
4044
'<td class="gridlines" style="vertical-align:bottom; color:#000000; font-family:\'Times New Roman\';',
4145
$html
4246
);
47+
self::assertStringContainsString(
48+
'>&nbsp;</td>',
49+
$html
50+
);
51+
self::assertStringContainsString(
52+
'<td class="gridlines" style="vertical-align:bottom; text-indent:18px; color:#000000; font-family:\'Tahoma\';',
53+
$html
54+
);
4355
$spreadsheet->disconnectWorksheets();
4456

4557
$reader = new HtmlReader();
@@ -57,6 +69,10 @@ public function testInline(): void
5769
Alignment::READORDER_CONTEXT,
5870
$sheet0->getStyle('A3')->getAlignment()->getReadOrder()
5971
);
72+
self::assertSame(
73+
2,
74+
$sheet0->getStyle('A5')->getAlignment()->getIndent()
75+
);
6076
$spreadsheet2->disconnectWorksheets();
6177
}
6278

@@ -73,6 +89,10 @@ public function testNotInline(): void
7389
->getAlignment()->setReadOrder(Alignment::READORDER_LTR);
7490
$sheet->getStyle('A2')->getFont()->setName('Arial');
7591
$sheet->getStyle('A3')->getFont()->setName('Times New Roman');
92+
$sheet->setCellValue('A5', 'hello');
93+
$sheet->getStyle('A5')->getFont()->setName('Tahoma');
94+
$sheet->getStyle('A5')
95+
->getAlignment()->setIndent(2);
7696
$writer = new HtmlWriter($spreadsheet);
7797
$html = $writer->generateHtmlAll();
7898
self::assertStringContainsString(
@@ -87,6 +107,14 @@ public function testNotInline(): void
87107
'td.style3, th.style3 { vertical-align:bottom; border-bottom',
88108
$html
89109
);
110+
self::assertStringContainsString(
111+
'>&nbsp;</td>',
112+
$html
113+
);
114+
self::assertStringContainsString(
115+
'td.style4, th.style4 { vertical-align:bottom; text-indent:18px;',
116+
$html
117+
);
90118
$spreadsheet->disconnectWorksheets();
91119
// PhpSpreadsheet does not read non-inline styles
92120
}

0 commit comments

Comments
 (0)