Skip to content

Commit d539dfa

Browse files
authored
Merge pull request #4047 from oleibman/issue3557
Writer Mpdf and Tcpdf Borders on Merged Cells
2 parents 68218c1 + 60d49ec commit d539dfa

File tree

4 files changed

+113
-7
lines changed

4 files changed

+113
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2828
- Incorrect Reader CSV with BOM. [Issue #4028](https://github.com/PHPOffice/PhpSpreadsheet/issues/4028) [PR #4029](https://github.com/PHPOffice/PhpSpreadsheet/pull/4029)
2929
- POWER Null/Bool Args. [PR #4031](https://github.com/PHPOffice/PhpSpreadsheet/pull/4031)
3030
- Do Not Output Alignment and Protection for Conditional Format. [Issue #4025](https://github.com/PHPOffice/PhpSpreadsheet/issues/4025) [PR #4027](https://github.com/PHPOffice/PhpSpreadsheet/pull/4027)
31+
- Mpdf and Tcpdf Borders on Merged Cells. [Issue #3557](https://github.com/PHPOffice/PhpSpreadsheet/issues/3557) [PR #4047](https://github.com/PHPOffice/PhpSpreadsheet/pull/4047)
3132
- Xls Conditional Format Improvements. [PR #4030](https://github.com/PHPOffice/PhpSpreadsheet/pull/4030) [PR #4033](https://github.com/PHPOffice/PhpSpreadsheet/pull/4033)
3233
- Csv Reader allow use of html mimetype. [Issue #4036](https://github.com/PHPOffice/PhpSpreadsheet/issues/4036) [PR #4049](https://github.com/PHPOffice/PhpSpreadsheet/pull/4040)
3334

src/PhpSpreadsheet/Writer/Html.php

+32-7
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,9 @@ private function mapHAlign(string $hAlign): string
241241
return Alignment::HORIZONTAL_ALIGNMENT_FOR_HTML[$hAlign] ?? '';
242242
}
243243

244+
const BORDER_NONE = 'none';
244245
const BORDER_ARR = [
245-
Border::BORDER_NONE => 'none',
246+
Border::BORDER_NONE => self::BORDER_NONE,
246247
Border::BORDER_DASHDOT => '1px dashed',
247248
Border::BORDER_DASHDOTDOT => '1px dotted',
248249
Border::BORDER_DASHED => '1px dashed',
@@ -263,7 +264,7 @@ private function mapHAlign(string $hAlign): string
263264
*/
264265
private function mapBorderStyle($borderStyle): string
265266
{
266-
return array_key_exists($borderStyle, self::BORDER_ARR) ? self::BORDER_ARR[$borderStyle] : '1px solid';
267+
return self::BORDER_ARR[$borderStyle] ?? '1px solid';
267268
}
268269

269270
/**
@@ -1069,10 +1070,26 @@ private function createCSSStyleBorders(Borders $borders): array
10691070
$css = [];
10701071

10711072
// Create CSS
1072-
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
1073-
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
1074-
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
1075-
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
1073+
if (!($this instanceof Pdf\Mpdf)) {
1074+
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
1075+
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
1076+
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
1077+
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
1078+
} else {
1079+
// Mpdf doesn't process !important, so omit unimportant border none
1080+
if ($borders->getBottom()->getBorderStyle() !== Border::BORDER_NONE) {
1081+
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
1082+
}
1083+
if ($borders->getTop()->getBorderStyle() !== Border::BORDER_NONE) {
1084+
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
1085+
}
1086+
if ($borders->getLeft()->getBorderStyle() !== Border::BORDER_NONE) {
1087+
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
1088+
}
1089+
if ($borders->getRight()->getBorderStyle() !== Border::BORDER_NONE) {
1090+
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
1091+
}
1092+
}
10761093

10771094
return $css;
10781095
}
@@ -1087,7 +1104,7 @@ private function createCSSStyleBorder(Border $border): string
10871104
// Create CSS - add !important to non-none border styles for merged cells
10881105
$borderStyle = $this->mapBorderStyle($border->getBorderStyle());
10891106

1090-
return $borderStyle . ' #' . $border->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important');
1107+
return $borderStyle . ' #' . $border->getColor()->getRGB() . (($borderStyle === self::BORDER_NONE) ? '' : ' !important');
10911108
}
10921109

10931110
/**
@@ -1507,6 +1524,14 @@ private function generateRow(Worksheet $worksheet, array $values, int $row, stri
15071524
$endCellCoord = Coordinate::stringFromColumnIndex($colNum + $colSpan) . ($row + $rowSpan);
15081525
if (!$this->useInlineCss) {
15091526
$cssClass .= ' style' . $worksheet->getCell($endCellCoord)->getXfIndex();
1527+
} else {
1528+
$endBorders = $this->spreadsheet->getCellXfByIndex($worksheet->getCell($endCellCoord)->getXfIndex())->getBorders();
1529+
$altBorders = $this->createCSSStyleBorders($endBorders);
1530+
foreach ($altBorders as $altKey => $altValue) {
1531+
if (str_contains($altValue, '!important')) {
1532+
$cssClass[$altKey] = $altValue;
1533+
}
1534+
}
15101535
}
15111536
}
15121537

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Writer\Mpdf;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PhpOffice\PhpSpreadsheet\Style\Border;
9+
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class MergedBorderTest extends TestCase
13+
{
14+
public static function testMergedBorder(): void
15+
{
16+
$spreadsheet = new Spreadsheet();
17+
$sheet = $spreadsheet->getActiveSheet();
18+
$target = 'A2:B5';
19+
$sheet->mergeCells($target);
20+
$sheet->setCellValue('A2', 'Planning');
21+
$sheet->getStyle($target)->applyFromArray([
22+
'borders' => [
23+
'outline' => [
24+
'borderStyle' => Border::BORDER_HAIR,
25+
'color' => ['rgb' => 'FF0000'],
26+
],
27+
],
28+
]);
29+
$sheet->setSelectedCells('D1');
30+
$sheet->setCellValue('D1', 'Edge');
31+
$sheet->setCellValue('D5', 'Edge');
32+
$sheet->setShowGridlines(false);
33+
$writer = new Mpdf($spreadsheet);
34+
$html = $writer->generateHtmlAll();
35+
self::assertSame(0, preg_match('/border-(top|bottom|right|left):none #000000;/', $html));
36+
self::assertSame(1, preg_match('/border-top:1px solid #FF0000 !important; border-left:1px solid #FF0000 !important;/', $html));
37+
self::assertSame(1, preg_match('/border-bottom:1px solid #FF0000 !important; border-left:1px solid #FF0000 !important;/', $html));
38+
self::assertSame(1, preg_match('/border-top:1px solid #FF0000 !important; border-right:1px solid #FF0000 !important;/', $html));
39+
self::assertSame(1, preg_match('/border-bottom:1px solid #FF0000 !important; border-right:1px solid #FF0000 !important;/', $html));
40+
$spreadsheet->disconnectWorksheets();
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Writer\Tcpdf;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PhpOffice\PhpSpreadsheet\Style\Border;
9+
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class MergedBorderTest extends TestCase
13+
{
14+
public static function testMergedBorder(): void
15+
{
16+
$spreadsheet = new Spreadsheet();
17+
$sheet = $spreadsheet->getActiveSheet();
18+
$target = 'A2:B5';
19+
$sheet->mergeCells($target);
20+
$sheet->setCellValue('A2', 'Planning');
21+
$sheet->getStyle($target)->applyFromArray([
22+
'borders' => [
23+
'outline' => [
24+
'borderStyle' => Border::BORDER_HAIR,
25+
'color' => ['rgb' => 'FF0000'],
26+
],
27+
],
28+
]);
29+
$sheet->setSelectedCells('D1');
30+
$sheet->setCellValue('D1', 'Edge');
31+
$sheet->setCellValue('D5', 'Edge');
32+
$sheet->setShowGridlines(false);
33+
$writer = new Tcpdf($spreadsheet);
34+
$html = $writer->generateHtmlAll();
35+
self::assertSame(1, preg_match('/border-bottom:1px solid #FF0000 !important; border-top:1px solid #FF0000 !important; border-left:1px solid #FF0000 !important; border-right:1px solid #FF0000 !important; color:#000000;[^>]+ colspan="2" rowspan="4"/', $html));
36+
$spreadsheet->disconnectWorksheets();
37+
}
38+
}

0 commit comments

Comments
 (0)