Skip to content

Commit 31e097a

Browse files
committed
Improve PDF Support for Page Size and Orientation
Fix PHPOffice#1691. PhpSpreadsheet allows the setting of different page size and orientation on each worksheet. It also allows the setting of page size and orientation on the PDF writer. It isn't clear which is supposed to prevail when the two are in conflict. In the cited issue, the user expects the PDF writer setting to prevail, and I tend to agree. Code is changed to do this, and handling things in this manner is now explicitly documented. PhpSpreadsheet uses a default paper size of Letter, and a default orientation of Default (which Excel treats as Portrait). New static routines are added to change the default for sheets created subsequent to such calls. This could allow users to configure these defaults better for their environments. The new functions are added to the documentation.
1 parent b674042 commit 31e097a

File tree

11 files changed

+234
-121
lines changed

11 files changed

+234
-121
lines changed

docs/topics/reading-and-writing-to-file.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,16 @@ which sheet to write to PDF:
918918
$writer->setSheetIndex(0);
919919
```
920920

921+
#### Setting Orientation and PaperSize
922+
923+
PhpSpreadsheet will attempt to honor the orientation and paper size specified
924+
in the worksheet for each page it prints, if the renderer supports that. However, you can set all pages
925+
to have the same orientation and paper size, e.g.
926+
927+
```php
928+
$writer->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
929+
```
930+
921931
#### Formula pre-calculation
922932

923933
By default, this writer pre-calculates all formulas in the spreadsheet.

docs/topics/recipes.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,21 @@ $spreadsheet->getActiveSheet()->getPageSetup()
303303
Note that there are additional page settings available. Please refer to
304304
the [API documentation](https://phpoffice.github.io/PhpSpreadsheet) for all possible options.
305305

306+
The default papersize is initially PAPERSIZE_LETTER. However, this default
307+
can be changed for new sheets with the following call:
308+
```php
309+
\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::setPaperSizeDefault(
310+
\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_A4
311+
);
312+
```
313+
314+
The default orientation is ORIENTATION_DEFAULT, which will be treated as Portrait in Excel. However, this default can be changed for new sheets with the following call:
315+
```php
316+
\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::setOrientationDefault(
317+
\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE
318+
);
319+
```
320+
306321
### Page Setup: Scaling options
307322

308323
The page setup scaling options in PhpSpreadsheet relate directly to the

phpstan-baseline.neon

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6660,11 +6660,6 @@ parameters:
66606660
count: 1
66616661
path: src/PhpSpreadsheet/Writer/Html.php
66626662

6663-
-
6664-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:getSheetIndex\\(\\) should return int but returns int\\|null\\.$#"
6665-
count: 1
6666-
path: src/PhpSpreadsheet/Writer/Html.php
6667-
66686663
-
66696664
message: "#^Parameter \\#1 \\$borderStyle of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapBorderStyle\\(\\) expects int, string given\\.$#"
66706665
count: 1
@@ -6780,26 +6775,6 @@ parameters:
67806775
count: 2
67816776
path: src/PhpSpreadsheet/Writer/Ods/Settings.php
67826777

6783-
-
6784-
message: "#^Parameter \\#2 \\$str of function fwrite expects string, string\\|null given\\.$#"
6785-
count: 1
6786-
path: src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
6787-
6788-
-
6789-
message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
6790-
count: 1
6791-
path: src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
6792-
6793-
-
6794-
message: "#^Strict comparison using \\=\\=\\= between null and int will always evaluate to false\\.$#"
6795-
count: 1
6796-
path: src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
6797-
6798-
-
6799-
message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
6800-
count: 1
6801-
path: src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
6802-
68036778
-
68046779
message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
68056780
count: 1

src/PhpSpreadsheet/Worksheet/PageSetup.php

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,32 @@ class PageSetup
160160
const PAGEORDER_DOWN_THEN_OVER = 'downThenOver';
161161

162162
/**
163-
* Paper size.
163+
* Paper size default.
164164
*
165165
* @var int
166166
*/
167-
private $paperSize = self::PAPERSIZE_LETTER;
167+
private static $paperSizeDefault = self::PAPERSIZE_LETTER;
168+
169+
/**
170+
* Paper size.
171+
*
172+
* @var ?int
173+
*/
174+
private $paperSize;
175+
176+
/**
177+
* Orientation default.
178+
*
179+
* @var string
180+
*/
181+
private static $orientationDefault = self::ORIENTATION_DEFAULT;
168182

169183
/**
170184
* Orientation.
171185
*
172186
* @var string
173187
*/
174-
private $orientation = self::ORIENTATION_DEFAULT;
188+
private $orientation;
175189

176190
/**
177191
* Scale (Print Scale).
@@ -256,6 +270,7 @@ class PageSetup
256270
*/
257271
public function __construct()
258272
{
273+
$this->orientation = self::$orientationDefault;
259274
}
260275

261276
/**
@@ -265,7 +280,7 @@ public function __construct()
265280
*/
266281
public function getPaperSize()
267282
{
268-
return $this->paperSize;
283+
return $this->paperSize ?? self::$paperSizeDefault;
269284
}
270285

271286
/**
@@ -282,6 +297,22 @@ public function setPaperSize($paperSize)
282297
return $this;
283298
}
284299

300+
/**
301+
* Get Paper Size default.
302+
*/
303+
public static function getPaperSizeDefault(): int
304+
{
305+
return self::$paperSizeDefault;
306+
}
307+
308+
/**
309+
* Set Paper Size Default.
310+
*/
311+
public static function setPaperSizeDefault(int $paperSize): void
312+
{
313+
self::$paperSizeDefault = $paperSize;
314+
}
315+
285316
/**
286317
* Get Orientation.
287318
*
@@ -301,11 +332,25 @@ public function getOrientation()
301332
*/
302333
public function setOrientation($orientation)
303334
{
304-
$this->orientation = $orientation;
335+
if ($orientation === self::ORIENTATION_LANDSCAPE || $orientation === self::ORIENTATION_PORTRAIT || $orientation === self::ORIENTATION_DEFAULT) {
336+
$this->orientation = $orientation;
337+
}
305338

306339
return $this;
307340
}
308341

342+
public static function getOrientationDefault(): string
343+
{
344+
return self::$orientationDefault;
345+
}
346+
347+
public static function setOrientationDefault(string $orientation): void
348+
{
349+
if ($orientation === self::ORIENTATION_LANDSCAPE || $orientation === self::ORIENTATION_PORTRAIT || $orientation === self::ORIENTATION_DEFAULT) {
350+
self::$orientationDefault = $orientation;
351+
}
352+
}
353+
309354
/**
310355
* Get Scale.
311356
*

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,8 @@ private function mapBorderStyle($borderStyle)
291291

292292
/**
293293
* Get sheet index.
294-
*
295-
* @return int
296294
*/
297-
public function getSheetIndex()
295+
public function getSheetIndex(): ?int
298296
{
299297
return $this->sheetIndex;
300298
}
@@ -1780,6 +1778,11 @@ private function writeComment(Worksheet $worksheet, $coordinate)
17801778
return $result;
17811779
}
17821780

1781+
public function getOrientation(): ?string
1782+
{
1783+
return null;
1784+
}
1785+
17831786
/**
17841787
* Generate @page declarations.
17851788
*
@@ -1815,7 +1818,7 @@ private function generatePageDeclarations($generateSurroundingHTML)
18151818
$htmlPage .= 'margin-top: ' . $top;
18161819
$bottom = StringHelper::FormatNumber($worksheet->getPageMargins()->getBottom()) . 'in; ';
18171820
$htmlPage .= 'margin-bottom: ' . $bottom;
1818-
$orientation = $worksheet->getPageSetup()->getOrientation();
1821+
$orientation = $this->getOrientation() ?? $worksheet->getPageSetup()->getOrientation();
18191822
if ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE) {
18201823
$htmlPage .= 'size: landscape; ';
18211824
} elseif ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_PORTRAIT) {

src/PhpSpreadsheet/Writer/Pdf.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ abstract class Pdf extends Html
2626
/**
2727
* Orientation (Over-ride).
2828
*
29-
* @var string
29+
* @var ?string
3030
*/
3131
protected $orientation;
3232

3333
/**
3434
* Paper size (Over-ride).
3535
*
36-
* @var int
36+
* @var ?int
3737
*/
3838
protected $paperSize;
3939

@@ -155,7 +155,7 @@ public function setFont($fontName)
155155
/**
156156
* Get Paper Size.
157157
*
158-
* @return int
158+
* @return ?int
159159
*/
160160
public function getPaperSize()
161161
{
@@ -178,10 +178,8 @@ public function setPaperSize($paperSize)
178178

179179
/**
180180
* Get Orientation.
181-
*
182-
* @return string
183181
*/
184-
public function getOrientation()
182+
public function getOrientation(): ?string
185183
{
186184
return $this->orientation;
187185
}

src/PhpSpreadsheet/Writer/Pdf/Dompdf.php

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,14 @@ public function save($filename, int $flags = 0): void
3030
$paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.)
3131

3232
// Check for paper size and page orientation
33-
if ($this->getSheetIndex() === null) {
34-
$orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
35-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
36-
$printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
37-
} else {
38-
$orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
39-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
40-
$printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
41-
}
33+
$setup = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageSetup();
34+
$orientation = $this->getOrientation() ?? $setup->getOrientation();
35+
$orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
36+
$printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize();
37+
$paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault();
4238

4339
$orientation = ($orientation == 'L') ? 'landscape' : 'portrait';
4440

45-
// Override Page Orientation
46-
if ($this->getOrientation() !== null) {
47-
$orientation = ($this->getOrientation() == PageSetup::ORIENTATION_DEFAULT)
48-
? PageSetup::ORIENTATION_PORTRAIT
49-
: $this->getOrientation();
50-
}
51-
// Override Paper Size
52-
if ($this->getPaperSize() !== null) {
53-
$printPaperSize = $this->getPaperSize();
54-
}
55-
56-
if (isset(self::$paperSizes[$printPaperSize])) {
57-
$paperSize = self::$paperSizes[$printPaperSize];
58-
}
59-
6041
// Create PDF
6142
$pdf = $this->createExternalWriterInstance();
6243
$pdf->setPaper($paperSize, $orientation);
@@ -65,7 +46,7 @@ public function save($filename, int $flags = 0): void
6546
$pdf->render();
6647

6748
// Write to file
68-
fwrite($fileHandle, $pdf->output());
49+
fwrite($fileHandle, $pdf->output() ?? '');
6950

7051
parent::restoreStateAfterSave();
7152
}

src/PhpSpreadsheet/Writer/Pdf/Mpdf.php

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,12 @@ public function save($filename, int $flags = 0): void
2828
{
2929
$fileHandle = parent::prepareForSave($filename);
3030

31-
// Default PDF paper size
32-
$paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.)
33-
3431
// Check for paper size and page orientation
35-
if (null === $this->getSheetIndex()) {
36-
$orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
37-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
38-
$printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
39-
} else {
40-
$orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
41-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
42-
$printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
43-
}
44-
$this->setOrientation($orientation);
45-
46-
// Override Page Orientation
47-
if (null !== $this->getOrientation()) {
48-
$orientation = ($this->getOrientation() == PageSetup::ORIENTATION_DEFAULT)
49-
? PageSetup::ORIENTATION_PORTRAIT
50-
: $this->getOrientation();
51-
}
52-
$orientation = strtoupper($orientation);
53-
54-
// Override Paper Size
55-
if (null !== $this->getPaperSize()) {
56-
$printPaperSize = $this->getPaperSize();
57-
}
58-
59-
if (isset(self::$paperSizes[$printPaperSize])) {
60-
$paperSize = self::$paperSizes[$printPaperSize];
61-
}
32+
$setup = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageSetup();
33+
$orientation = $this->getOrientation() ?? $setup->getOrientation();
34+
$orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
35+
$printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize();
36+
$paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault();
6237

6338
// Create PDF
6439
$config = ['tempDir' => $this->tempDir . '/mpdf'];

src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,32 +46,12 @@ public function save($filename, int $flags = 0): void
4646
$paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.)
4747

4848
// Check for paper size and page orientation
49-
if ($this->getSheetIndex() === null) {
50-
$orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation()
51-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
52-
$printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize();
53-
$printMargins = $this->spreadsheet->getSheet(0)->getPageMargins();
54-
} else {
55-
$orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()
56-
== PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
57-
$printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();
58-
$printMargins = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageMargins();
59-
}
60-
61-
// Override Page Orientation
62-
if ($this->getOrientation() !== null) {
63-
$orientation = ($this->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE)
64-
? 'L'
65-
: 'P';
66-
}
67-
// Override Paper Size
68-
if ($this->getPaperSize() !== null) {
69-
$printPaperSize = $this->getPaperSize();
70-
}
71-
72-
if (isset(self::$paperSizes[$printPaperSize])) {
73-
$paperSize = self::$paperSizes[$printPaperSize];
74-
}
49+
$setup = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageSetup();
50+
$orientation = $this->getOrientation() ?? $setup->getOrientation();
51+
$orientation = ($orientation === PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P';
52+
$printPaperSize = $this->getPaperSize() ?? $setup->getPaperSize();
53+
$paperSize = self::$paperSizes[$printPaperSize] ?? PageSetup::getPaperSizeDefault();
54+
$printMargins = $this->spreadsheet->getSheet($this->getSheetIndex() ?? 0)->getPageMargins();
7555

7656
// Create PDF
7757
$pdf = $this->createExternalWriterInstance($orientation, 'pt', $paperSize);

0 commit comments

Comments
 (0)