Refactor reading Ods Page Settings into a separate class

This commit is contained in:
MarkBaker 2020-06-30 22:23:33 +02:00
parent 13a3363410
commit 4dadf4a5c8
2 changed files with 108 additions and 65 deletions

View File

@ -11,6 +11,7 @@ use DOMNode;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings;
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties; use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\RichText;
@ -19,8 +20,6 @@ use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use XMLReader; use XMLReader;
use ZipArchive; use ZipArchive;
@ -291,36 +290,8 @@ class Ods extends BaseReader
$this->securityScanner->scan($zip->getFromName('styles.xml')), $this->securityScanner->scan($zip->getFromName('styles.xml')),
Settings::getLibXmlLoaderOptions() Settings::getLibXmlLoaderOptions()
); );
$officeNs = $dom->lookupNamespaceUri('office');
$stylesNs = $dom->lookupNamespaceUri('style');
$styles = $dom->getElementsByTagNameNS($officeNs, 'automatic-styles') $pageSettings = new PageSettings($dom);
->item(0)
->getElementsByTagNameNS($stylesNs, 'page-layout');
foreach ($styles as $styleSet) {
$styleName = $styleSet->getAttributeNS($stylesNs, 'name');
$pageLayoutProperties = $styleSet->getElementsByTagNameNS($stylesNs, 'page-layout-properties')[0];
$styleOrientation = $pageLayoutProperties->getAttributeNS($stylesNs, 'print-orientation');
$styleScale = $pageLayoutProperties->getAttributeNS($stylesNs, 'scale-to');
$stylePrintOrder = $pageLayoutProperties->getAttributeNS($stylesNs, 'print-page-order');
$this->pageLayoutStyles[$styleName] = (object) [
'orientation' => $styleOrientation,
'scale' => $styleScale,
'printOrder' => $stylePrintOrder,
];
}
$styleMasterLookup = $dom->getElementsByTagNameNS($officeNs, 'master-styles')
->item(0)
->getElementsByTagNameNS($stylesNs, 'master-page');
foreach ($styleMasterLookup as $styleMasterSet) {
$styleMasterName = $styleMasterSet->getAttributeNS($stylesNs, 'name');
$pageLayoutName = $styleMasterSet->getAttributeNS($stylesNs, 'page-layout-name');
$this->masterPrintStylesCrossReference[$styleMasterName] = $pageLayoutName;
}
// Main Content // Main Content
@ -335,17 +306,7 @@ class Ods extends BaseReader
$textNs = $dom->lookupNamespaceUri('text'); $textNs = $dom->lookupNamespaceUri('text');
$xlinkNs = $dom->lookupNamespaceUri('xlink'); $xlinkNs = $dom->lookupNamespaceUri('xlink');
$styleXReferences = $dom->getElementsByTagNameNS($officeNs, 'automatic-styles') $pageSettings->readStyleCrossReferences($dom);
->item(0)
->getElementsByTagNameNS($stylesNs, 'style');
foreach ($styleXReferences as $styleXreferenceSet) {
$styleXRefName = $styleXreferenceSet->getAttributeNS($stylesNs, 'name');
$stylePageLayoutName = $styleXreferenceSet->getAttributeNS($stylesNs, 'master-page-name');
if (!empty($stylePageLayoutName)) {
$this->masterStylesCrossReference[$styleXRefName] = $stylePageLayoutName;
}
}
// Content // Content
@ -703,7 +664,7 @@ class Ods extends BaseReader
break; break;
} }
} }
$this->getPrintSettings($spreadsheet->getActiveSheet(), $worksheetStyleName); $pageSettings->setPrintSettingsForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName);
++$worksheetID; ++$worksheetID;
} }
} }
@ -712,28 +673,6 @@ class Ods extends BaseReader
return $spreadsheet; return $spreadsheet;
} }
private function getPrintSettings(Worksheet $worksheet, string $styleName): void
{
if (!array_key_exists($styleName, $this->masterStylesCrossReference)) {
return;
}
$masterStyleName = $this->masterStylesCrossReference[$styleName];
if (!array_key_exists($masterStyleName, $this->masterPrintStylesCrossReference)) {
return;
}
$printSettingsIndex = $this->masterPrintStylesCrossReference[$masterStyleName];
if (!array_key_exists($printSettingsIndex, $this->pageLayoutStyles)) {
return;
}
$printSettings = $this->pageLayoutStyles[$printSettingsIndex];
$worksheet->getPageSetup()->setOrientation($printSettings->orientation ?? PageSetup::ORIENTATION_DEFAULT);
$worksheet->getPageSetup()->setScale((int) trim($printSettings->scale, '%'));
$worksheet->getPageSetup()->setPageOrder($printSettings->printOrder === 'ltr' ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER);
}
/** /**
* Recursively scan element. * Recursively scan element.
* *

View File

@ -0,0 +1,104 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
use DOMDocument;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class PageSettings
{
private $officeNs;
private $stylesNs;
private $pageLayoutStyles = [];
private $masterStylesCrossReference = [];
private $masterPrintStylesCrossReference = [];
public function __construct(DOMDocument $styleDom)
{
$this->setDomNameSpaces($styleDom);
$this->readPageSettingStyles($styleDom);
$this->readStyleMasterLookup($styleDom);
}
private function setDomNameSpaces(DOMDocument $styleDom): void
{
$this->officeNs = $styleDom->lookupNamespaceUri('office');
$this->stylesNs = $styleDom->lookupNamespaceUri('style');
}
private function readPageSettingStyles(DOMDocument $styleDom): void
{
$styles = $styleDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')
->item(0)
->getElementsByTagNameNS($this->stylesNs, 'page-layout');
foreach ($styles as $styleSet) {
$styleName = $styleSet->getAttributeNS($this->stylesNs, 'name');
$pageLayoutProperties = $styleSet->getElementsByTagNameNS($this->stylesNs, 'page-layout-properties')[0];
$styleOrientation = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-orientation');
$styleScale = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'scale-to');
$stylePrintOrder = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-page-order');
$this->pageLayoutStyles[$styleName] = (object) [
'orientation' => $styleOrientation,
'scale' => $styleScale,
'printOrder' => $stylePrintOrder,
];
}
}
private function readStyleMasterLookup(DOMDocument $styleDom): void
{
$styleMasterLookup = $styleDom->getElementsByTagNameNS($this->officeNs, 'master-styles')
->item(0)
->getElementsByTagNameNS($this->stylesNs, 'master-page');
foreach ($styleMasterLookup as $styleMasterSet) {
$styleMasterName = $styleMasterSet->getAttributeNS($this->stylesNs, 'name');
$pageLayoutName = $styleMasterSet->getAttributeNS($this->stylesNs, 'page-layout-name');
$this->masterPrintStylesCrossReference[$styleMasterName] = $pageLayoutName;
}
}
public function readStyleCrossReferences(DOMDocument $contentDom): void
{
$styleXReferences = $contentDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')
->item(0)
->getElementsByTagNameNS($this->stylesNs, 'style');
foreach ($styleXReferences as $styleXreferenceSet) {
$styleXRefName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'name');
$stylePageLayoutName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'master-page-name');
if (!empty($stylePageLayoutName)) {
$this->masterStylesCrossReference[$styleXRefName] = $stylePageLayoutName;
}
}
}
public function setPrintSettingsForWorksheet(Worksheet $worksheet, string $styleName): void
{
if (!array_key_exists($styleName, $this->masterStylesCrossReference)) {
return;
}
$masterStyleName = $this->masterStylesCrossReference[$styleName];
if (!array_key_exists($masterStyleName, $this->masterPrintStylesCrossReference)) {
return;
}
$printSettingsIndex = $this->masterPrintStylesCrossReference[$masterStyleName];
if (!array_key_exists($printSettingsIndex, $this->pageLayoutStyles)) {
return;
}
$printSettings = $this->pageLayoutStyles[$printSettingsIndex];
$worksheet->getPageSetup()
->setOrientation($printSettings->orientation ?? PageSetup::ORIENTATION_DEFAULT)
->setPageOrder($printSettings->printOrder === 'ltr' ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER)
->setScale((int) trim($printSettings->scale, '%'));
}
}