Skip to content

Commit

Permalink
Merge pull request #4047 from oleibman/issue3557
Browse files Browse the repository at this point in the history
Writer Mpdf and Tcpdf Borders on Merged Cells
  • Loading branch information
oleibman authored May 30, 2024
2 parents 68218c1 + 60d49ec commit d539dfa
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Incorrect Reader CSV with BOM. [Issue #4028](https://github.com/PHPOffice/PhpSpreadsheet/issues/4028) [PR #4029](https://github.com/PHPOffice/PhpSpreadsheet/pull/4029)
- POWER Null/Bool Args. [PR #4031](https://github.com/PHPOffice/PhpSpreadsheet/pull/4031)
- 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)
- 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)
- Xls Conditional Format Improvements. [PR #4030](https://github.com/PHPOffice/PhpSpreadsheet/pull/4030) [PR #4033](https://github.com/PHPOffice/PhpSpreadsheet/pull/4033)
- 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)

Expand Down
39 changes: 32 additions & 7 deletions src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ private function mapHAlign(string $hAlign): string
return Alignment::HORIZONTAL_ALIGNMENT_FOR_HTML[$hAlign] ?? '';
}

const BORDER_NONE = 'none';
const BORDER_ARR = [
Border::BORDER_NONE => 'none',
Border::BORDER_NONE => self::BORDER_NONE,
Border::BORDER_DASHDOT => '1px dashed',
Border::BORDER_DASHDOTDOT => '1px dotted',
Border::BORDER_DASHED => '1px dashed',
Expand All @@ -263,7 +264,7 @@ private function mapHAlign(string $hAlign): string
*/
private function mapBorderStyle($borderStyle): string
{
return array_key_exists($borderStyle, self::BORDER_ARR) ? self::BORDER_ARR[$borderStyle] : '1px solid';
return self::BORDER_ARR[$borderStyle] ?? '1px solid';
}

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

// Create CSS
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
if (!($this instanceof Pdf\Mpdf)) {
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
} else {
// Mpdf doesn't process !important, so omit unimportant border none
if ($borders->getBottom()->getBorderStyle() !== Border::BORDER_NONE) {
$css['border-bottom'] = $this->createCSSStyleBorder($borders->getBottom());
}
if ($borders->getTop()->getBorderStyle() !== Border::BORDER_NONE) {
$css['border-top'] = $this->createCSSStyleBorder($borders->getTop());
}
if ($borders->getLeft()->getBorderStyle() !== Border::BORDER_NONE) {
$css['border-left'] = $this->createCSSStyleBorder($borders->getLeft());
}
if ($borders->getRight()->getBorderStyle() !== Border::BORDER_NONE) {
$css['border-right'] = $this->createCSSStyleBorder($borders->getRight());
}
}

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

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

/**
Expand Down Expand Up @@ -1507,6 +1524,14 @@ private function generateRow(Worksheet $worksheet, array $values, int $row, stri
$endCellCoord = Coordinate::stringFromColumnIndex($colNum + $colSpan) . ($row + $rowSpan);
if (!$this->useInlineCss) {
$cssClass .= ' style' . $worksheet->getCell($endCellCoord)->getXfIndex();
} else {
$endBorders = $this->spreadsheet->getCellXfByIndex($worksheet->getCell($endCellCoord)->getXfIndex())->getBorders();
$altBorders = $this->createCSSStyleBorders($endBorders);
foreach ($altBorders as $altKey => $altValue) {
if (str_contains($altValue, '!important')) {
$cssClass[$altKey] = $altValue;
}
}
}
}

Expand Down
42 changes: 42 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Mpdf/MergedBorderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Writer\Mpdf;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;
use PHPUnit\Framework\TestCase;

class MergedBorderTest extends TestCase
{
public static function testMergedBorder(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$target = 'A2:B5';
$sheet->mergeCells($target);
$sheet->setCellValue('A2', 'Planning');
$sheet->getStyle($target)->applyFromArray([
'borders' => [
'outline' => [
'borderStyle' => Border::BORDER_HAIR,
'color' => ['rgb' => 'FF0000'],
],
],
]);
$sheet->setSelectedCells('D1');
$sheet->setCellValue('D1', 'Edge');
$sheet->setCellValue('D5', 'Edge');
$sheet->setShowGridlines(false);
$writer = new Mpdf($spreadsheet);
$html = $writer->generateHtmlAll();
self::assertSame(0, preg_match('/border-(top|bottom|right|left):none #000000;/', $html));
self::assertSame(1, preg_match('/border-top:1px solid #FF0000 !important; border-left:1px solid #FF0000 !important;/', $html));
self::assertSame(1, preg_match('/border-bottom:1px solid #FF0000 !important; border-left:1px solid #FF0000 !important;/', $html));
self::assertSame(1, preg_match('/border-top:1px solid #FF0000 !important; border-right:1px solid #FF0000 !important;/', $html));
self::assertSame(1, preg_match('/border-bottom:1px solid #FF0000 !important; border-right:1px solid #FF0000 !important;/', $html));
$spreadsheet->disconnectWorksheets();
}
}
38 changes: 38 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Tcpdf/MergedBorderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Writer\Tcpdf;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf;
use PHPUnit\Framework\TestCase;

class MergedBorderTest extends TestCase
{
public static function testMergedBorder(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$target = 'A2:B5';
$sheet->mergeCells($target);
$sheet->setCellValue('A2', 'Planning');
$sheet->getStyle($target)->applyFromArray([
'borders' => [
'outline' => [
'borderStyle' => Border::BORDER_HAIR,
'color' => ['rgb' => 'FF0000'],
],
],
]);
$sheet->setSelectedCells('D1');
$sheet->setCellValue('D1', 'Edge');
$sheet->setCellValue('D5', 'Edge');
$sheet->setShowGridlines(false);
$writer = new Tcpdf($spreadsheet);
$html = $writer->generateHtmlAll();
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));
$spreadsheet->disconnectWorksheets();
}
}

0 comments on commit d539dfa

Please sign in to comment.