Merge pull request #1559 from PHPOffice/Page-Setup-Page-Order
Support pageOrder in page setup for Xlsx/Xls Readers/Writers, and implement basic page setup support for other Readers/Writers
This commit is contained in:
commit
bd66a58203
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Added
|
||||
|
||||
- Implemented Page Order for Xlsx and Xls Readers, and provided Page Settings (Orientation, Scale, Horizontal/Vertical Centering, Page Order, Margins) support for Ods, Gnumeric and Xls Readers [#1559](https://github.com/PHPOffice/PhpSpreadsheet/pull/1559)
|
||||
- Implementation of the Excel `LOGNORM.DIST()`, `NORM.S.DIST()`, `GAMMA()` and `GAUSS()` functions. [#1588](https://github.com/PHPOffice/PhpSpreadsheet/pull/1588)
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader;
|
|||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\NamedRange;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\PageSetup;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
|
@ -23,6 +24,8 @@ use XMLReader;
|
|||
|
||||
class Gnumeric extends BaseReader
|
||||
{
|
||||
private const UOM_CONVERSION_POINTS_TO_CENTIMETERS = 0.03527777778;
|
||||
|
||||
/**
|
||||
* Shared Expressions.
|
||||
*
|
||||
|
@ -401,53 +404,6 @@ class Gnumeric extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
private function sheetMargin(string $key, float $marginSize): void
|
||||
{
|
||||
switch ($key) {
|
||||
case 'top':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setTop($marginSize);
|
||||
|
||||
break;
|
||||
case 'bottom':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setBottom($marginSize);
|
||||
|
||||
break;
|
||||
case 'left':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setLeft($marginSize);
|
||||
|
||||
break;
|
||||
case 'right':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setRight($marginSize);
|
||||
|
||||
break;
|
||||
case 'header':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setHeader($marginSize);
|
||||
|
||||
break;
|
||||
case 'footer':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setFooter($marginSize);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function sheetMargins(SimpleXMLElement $sheet): void
|
||||
{
|
||||
if (!$this->readDataOnly && isset($sheet->PrintInformation, $sheet->PrintInformation->Margins)) {
|
||||
foreach ($sheet->PrintInformation->Margins->children($this->gnm, true) as $key => $margin) {
|
||||
$marginAttributes = $margin->attributes();
|
||||
$marginSize = 72 / 100; // Default
|
||||
switch ($marginAttributes['PrefUnit']) {
|
||||
case 'mm':
|
||||
$marginSize = (int) ($marginAttributes['Points']) / 100;
|
||||
|
||||
break;
|
||||
}
|
||||
$this->sheetMargin($key, (float) $marginSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processComments(SimpleXMLElement $sheet): void
|
||||
{
|
||||
if ((!$this->readDataOnly) && (isset($sheet->Objects))) {
|
||||
|
@ -513,7 +469,11 @@ class Gnumeric extends BaseReader
|
|||
// name in line with the formula, not the reverse
|
||||
$this->spreadsheet->getActiveSheet()->setTitle($worksheetName, false, false);
|
||||
|
||||
$this->sheetMargins($sheet);
|
||||
if (!$this->readDataOnly) {
|
||||
(new PageSetup($this->spreadsheet, $this->gnm))
|
||||
->printInformation($sheet)
|
||||
->sheetMargins($sheet);
|
||||
}
|
||||
|
||||
foreach ($sheet->Cells->Cell as $cell) {
|
||||
$cellAttributes = $cell->attributes();
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageMargins;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup as WorksheetPageSetup;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class PageSetup
|
||||
{
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $gnm;
|
||||
|
||||
public function __construct(Spreadsheet $spreadsheet, string $gnm)
|
||||
{
|
||||
$this->spreadsheet = $spreadsheet;
|
||||
$this->gnm = $gnm;
|
||||
}
|
||||
|
||||
public function printInformation(SimpleXMLElement $sheet): self
|
||||
{
|
||||
if (isset($sheet->PrintInformation)) {
|
||||
$printInformation = $sheet->PrintInformation[0];
|
||||
$scale = (string) $printInformation->Scale->attributes()['percentage'];
|
||||
$pageOrder = (string) $printInformation->order;
|
||||
$orientation = (string) $printInformation->orientation;
|
||||
$horizontalCentered = (string) $printInformation->hcenter->attributes()['value'];
|
||||
$verticalCentered = (string) $printInformation->vcenter->attributes()['value'];
|
||||
|
||||
$this->spreadsheet->getActiveSheet()->getPageSetup()
|
||||
->setPageOrder($pageOrder === 'r_then_d' ? WorksheetPageSetup::PAGEORDER_OVER_THEN_DOWN : WorksheetPageSetup::PAGEORDER_DOWN_THEN_OVER)
|
||||
->setScale((int) $scale)
|
||||
->setOrientation($orientation ?? WorksheetPageSetup::ORIENTATION_DEFAULT)
|
||||
->setHorizontalCentered((bool) $horizontalCentered)
|
||||
->setVerticalCentered((bool) $verticalCentered);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function sheetMargins(SimpleXMLElement $sheet): self
|
||||
{
|
||||
if (isset($sheet->PrintInformation, $sheet->PrintInformation->Margins)) {
|
||||
$marginSet = [
|
||||
// Default Settings
|
||||
'top' => 0.75,
|
||||
'header' => 0.3,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.75,
|
||||
'footer' => 0.3,
|
||||
];
|
||||
|
||||
$marginSet = $this->buildMarginSet($sheet, $marginSet);
|
||||
$this->adjustMargins($marginSet);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function buildMarginSet(SimpleXMLElement $sheet, array $marginSet): array
|
||||
{
|
||||
foreach ($sheet->PrintInformation->Margins->children($this->gnm, true) as $key => $margin) {
|
||||
$marginAttributes = $margin->attributes();
|
||||
$marginSize = ($marginAttributes['Points']) ?? 72; // Default is 72pt
|
||||
// Convert value in points to inches
|
||||
$marginSize = PageMargins::fromPoints((float) $marginSize);
|
||||
$marginSet[$key] = $marginSize;
|
||||
}
|
||||
|
||||
return $marginSet;
|
||||
}
|
||||
|
||||
private function adjustMargins(array $marginSet): void
|
||||
{
|
||||
foreach ($marginSet as $key => $marginSize) {
|
||||
// Gnumeric is quirky in the way it displays the header/footer values:
|
||||
// header is actually the sum of top and header; footer is actually the sum of bottom and footer
|
||||
// then top is actually the header value, and bottom is actually the footer value
|
||||
switch ($key) {
|
||||
case 'left':
|
||||
case 'right':
|
||||
$this->sheetMargin($key, $marginSize);
|
||||
|
||||
break;
|
||||
case 'top':
|
||||
$this->sheetMargin($key, $marginSet['header'] ?? 0);
|
||||
|
||||
break;
|
||||
case 'bottom':
|
||||
$this->sheetMargin($key, $marginSet['footer'] ?? 0);
|
||||
|
||||
break;
|
||||
case 'header':
|
||||
$this->sheetMargin($key, ($marginSet['top'] ?? 0) - $marginSize);
|
||||
|
||||
break;
|
||||
case 'footer':
|
||||
$this->sheetMargin($key, ($marginSet['bottom'] ?? 0) - $marginSize);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sheetMargin(string $key, float $marginSize): void
|
||||
{
|
||||
switch ($key) {
|
||||
case 'top':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setTop($marginSize);
|
||||
|
||||
break;
|
||||
case 'bottom':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setBottom($marginSize);
|
||||
|
||||
break;
|
||||
case 'left':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setLeft($marginSize);
|
||||
|
||||
break;
|
||||
case 'right':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setRight($marginSize);
|
||||
|
||||
break;
|
||||
case 'header':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setHeader($marginSize);
|
||||
|
||||
break;
|
||||
case 'footer':
|
||||
$this->spreadsheet->getActiveSheet()->getPageMargins()->setFooter($marginSize);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ use DOMNode;
|
|||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
|
@ -276,7 +277,17 @@ class Ods extends BaseReader
|
|||
|
||||
(new DocumentProperties($spreadsheet))->load($xml, $namespacesMeta);
|
||||
|
||||
// Content
|
||||
// Styles
|
||||
|
||||
$dom = new DOMDocument('1.01', 'UTF-8');
|
||||
$dom->loadXML(
|
||||
$this->securityScanner->scan($zip->getFromName('styles.xml')),
|
||||
Settings::getLibXmlLoaderOptions()
|
||||
);
|
||||
|
||||
$pageSettings = new PageSettings($dom);
|
||||
|
||||
// Main Content
|
||||
|
||||
$dom = new DOMDocument('1.01', 'UTF-8');
|
||||
$dom->loadXML(
|
||||
|
@ -289,6 +300,10 @@ class Ods extends BaseReader
|
|||
$textNs = $dom->lookupNamespaceUri('text');
|
||||
$xlinkNs = $dom->lookupNamespaceUri('xlink');
|
||||
|
||||
$pageSettings->readStyleCrossReferences($dom);
|
||||
|
||||
// Content
|
||||
|
||||
$spreadsheets = $dom->getElementsByTagNameNS($officeNs, 'body')
|
||||
->item(0)
|
||||
->getElementsByTagNameNS($officeNs, 'spreadsheet');
|
||||
|
@ -309,6 +324,8 @@ class Ods extends BaseReader
|
|||
continue;
|
||||
}
|
||||
|
||||
$worksheetStyleName = $worksheetDataSet->getAttributeNS($tableNs, 'style-name');
|
||||
|
||||
// Create sheet
|
||||
if ($worksheetID > 0) {
|
||||
$spreadsheet->createSheet(); // First sheet is added by default
|
||||
|
@ -319,7 +336,7 @@ class Ods extends BaseReader
|
|||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
|
||||
// formula cells... during the load, all formulae should be correct, and we're simply
|
||||
// bringing the worksheet name in line with the formula, not the reverse
|
||||
$spreadsheet->getActiveSheet()->setTitle($worksheetName, false, false);
|
||||
$spreadsheet->getActiveSheet()->setTitle((string) $worksheetName, false, false);
|
||||
}
|
||||
|
||||
// Go through every child of table element
|
||||
|
@ -641,6 +658,7 @@ class Ods extends BaseReader
|
|||
break;
|
||||
}
|
||||
}
|
||||
$pageSettings->setPrintSettingsForWorksheet($spreadsheet->getActiveSheet(), $worksheetStyleName);
|
||||
++$worksheetID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<?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 $stylesFo;
|
||||
|
||||
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');
|
||||
$this->stylesFo = $styleDom->lookupNamespaceUri('fo');
|
||||
}
|
||||
|
||||
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');
|
||||
$centered = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'table-centering');
|
||||
|
||||
$marginLeft = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-left');
|
||||
$marginRight = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-right');
|
||||
$marginTop = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-top');
|
||||
$marginBottom = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-bottom');
|
||||
$header = $styleSet->getElementsByTagNameNS($this->stylesNs, 'header-style')[0];
|
||||
$headerProperties = $header->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
|
||||
$marginHeader = $headerProperties->getAttributeNS($this->stylesFo, 'min-height');
|
||||
$footer = $styleSet->getElementsByTagNameNS($this->stylesNs, 'footer-style')[0];
|
||||
$footerProperties = $footer->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
|
||||
$marginFooter = $footerProperties->getAttributeNS($this->stylesFo, 'min-height');
|
||||
|
||||
$this->pageLayoutStyles[$styleName] = (object) [
|
||||
'orientation' => $styleOrientation ?: PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => $styleScale ?: 100,
|
||||
'printOrder' => $stylePrintOrder,
|
||||
'horizontalCentered' => $centered === 'horizontal' || $centered === 'both',
|
||||
'verticalCentered' => $centered === 'vertical' || $centered === 'both',
|
||||
// margin size is already stored in inches, so no UOM conversion is required
|
||||
'marginLeft' => (float) $marginLeft ?? 0.7,
|
||||
'marginRight' => (float) $marginRight ?? 0.7,
|
||||
'marginTop' => (float) $marginTop ?? 0.3,
|
||||
'marginBottom' => (float) $marginBottom ?? 0.3,
|
||||
'marginHeader' => (float) $marginHeader ?? 0.45,
|
||||
'marginFooter' => (float) $marginFooter ?? 0.45,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
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, '%'))
|
||||
->setHorizontalCentered($printSettings->horizontalCentered)
|
||||
->setVerticalCentered($printSettings->verticalCentered);
|
||||
|
||||
$worksheet->getPageMargins()
|
||||
->setLeft($printSettings->marginLeft)
|
||||
->setRight($printSettings->marginRight)
|
||||
->setTop($printSettings->marginTop)
|
||||
->setBottom($printSettings->marginBottom)
|
||||
->setHeader($printSettings->marginHeader)
|
||||
->setFooter($printSettings->marginFooter);
|
||||
}
|
||||
}
|
|
@ -3444,6 +3444,9 @@ class Xls extends BaseReader
|
|||
|
||||
// offset: 10; size: 2; option flags
|
||||
|
||||
// bit: 0; mask: 0x0001; 0=down then over, 1=over then down
|
||||
$isOverThenDown = (0x0001 & self::getUInt2d($recordData, 10));
|
||||
|
||||
// bit: 1; mask: 0x0002; 0=landscape, 1=portrait
|
||||
$isPortrait = (0x0002 & self::getUInt2d($recordData, 10)) >> 1;
|
||||
|
||||
|
@ -3453,16 +3456,8 @@ class Xls extends BaseReader
|
|||
|
||||
if (!$isNotInit) {
|
||||
$this->phpSheet->getPageSetup()->setPaperSize($paperSize);
|
||||
switch ($isPortrait) {
|
||||
case 0:
|
||||
$this->phpSheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
$this->phpSheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_PORTRAIT);
|
||||
|
||||
break;
|
||||
}
|
||||
$this->phpSheet->getPageSetup()->setPageOrder(((bool) $isOverThenDown) ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER);
|
||||
$this->phpSheet->getPageSetup()->setOrientation(((bool) $isPortrait) ? PageSetup::ORIENTATION_PORTRAIT : PageSetup::ORIENTATION_LANDSCAPE);
|
||||
|
||||
$this->phpSheet->getPageSetup()->setScale($scale, false);
|
||||
$this->phpSheet->getPageSetup()->setFitToPage((bool) $this->isFitToPages);
|
||||
|
|
|
@ -69,6 +69,9 @@ class PageSetup extends BaseParserClass
|
|||
self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])) {
|
||||
$docPageSetup->setFirstPageNumber((int) ($xmlSheet->pageSetup['firstPageNumber']));
|
||||
}
|
||||
if (isset($xmlSheet->pageSetup['pageOrder'])) {
|
||||
$docPageSetup->setPageOrder((string) $xmlSheet->pageSetup['pageOrder']);
|
||||
}
|
||||
|
||||
$relAttributes = $xmlSheet->pageSetup->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
if (isset($relAttributes['id'])) {
|
||||
|
|
|
@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
|||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Document\Properties;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xml\PageSettings;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
@ -569,7 +570,7 @@ class Xml extends BaseReader
|
|||
$columnReference = $columnNumber;
|
||||
}
|
||||
// Bracketed C references are relative to the current column
|
||||
if ($columnReference[0] == '[') {
|
||||
if (is_string($columnReference) && $columnReference[0] == '[') {
|
||||
$columnReference = $columnNumber + trim($columnReference, '[]');
|
||||
}
|
||||
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference;
|
||||
|
@ -626,6 +627,11 @@ class Xml extends BaseReader
|
|||
|
||||
++$rowID;
|
||||
}
|
||||
|
||||
$xmlX = $worksheet->children($namespaces['x']);
|
||||
if (isset($xmlX->WorksheetOptions)) {
|
||||
(new PageSettings($xmlX, $namespaces))->loadPageSettings($spreadsheet);
|
||||
}
|
||||
}
|
||||
++$worksheetID;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Reader\Xml;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use SimpleXMLElement;
|
||||
use stdClass;
|
||||
|
||||
class PageSettings
|
||||
{
|
||||
/**
|
||||
* @var stdClass
|
||||
*/
|
||||
private $printSettings;
|
||||
|
||||
public function __construct(SimpleXMLElement $xmlX, array $namespaces)
|
||||
{
|
||||
$printSettings = $this->pageSetup($xmlX, $namespaces, $this->getPrintDefaults());
|
||||
$this->printSettings = $this->printSetup($xmlX, $printSettings);
|
||||
}
|
||||
|
||||
public function loadPageSettings(Spreadsheet $spreadsheet): void
|
||||
{
|
||||
$spreadsheet->getActiveSheet()->getPageSetup()
|
||||
->setPaperSize($this->printSettings->paperSize)
|
||||
->setOrientation($this->printSettings->orientation)
|
||||
->setScale($this->printSettings->scale)
|
||||
->setVerticalCentered($this->printSettings->verticalCentered)
|
||||
->setHorizontalCentered($this->printSettings->horizontalCentered)
|
||||
->setPageOrder($this->printSettings->printOrder);
|
||||
$spreadsheet->getActiveSheet()->getPageMargins()
|
||||
->setTop($this->printSettings->topMargin)
|
||||
->setHeader($this->printSettings->headerMargin)
|
||||
->setLeft($this->printSettings->leftMargin)
|
||||
->setRight($this->printSettings->rightMargin)
|
||||
->setBottom($this->printSettings->bottomMargin)
|
||||
->setFooter($this->printSettings->footerMargin);
|
||||
}
|
||||
|
||||
private function getPrintDefaults(): stdClass
|
||||
{
|
||||
return (object) [
|
||||
'paperSize' => 9,
|
||||
'orientation' => PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'printOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
'topMargin' => 0.75,
|
||||
'headerMargin' => 0.3,
|
||||
'leftMargin' => 0.7,
|
||||
'rightMargin' => 0.7,
|
||||
'bottomMargin' => 0.75,
|
||||
'footerMargin' => 0.3,
|
||||
];
|
||||
}
|
||||
|
||||
private function pageSetup(SimpleXMLElement $xmlX, array $namespaces, stdClass $printDefaults): stdClass
|
||||
{
|
||||
if (isset($xmlX->WorksheetOptions->PageSetup)) {
|
||||
foreach ($xmlX->WorksheetOptions->PageSetup as $pageSetupData) {
|
||||
foreach ($pageSetupData as $pageSetupKey => $pageSetupValue) {
|
||||
$pageSetupAttributes = $pageSetupValue->attributes($namespaces['x']);
|
||||
switch ($pageSetupKey) {
|
||||
case 'Layout':
|
||||
$this->setLayout($printDefaults, $pageSetupAttributes);
|
||||
|
||||
break;
|
||||
case 'Header':
|
||||
$printDefaults->headerMargin = (float) $pageSetupAttributes->Margin ?: 1.0;
|
||||
|
||||
break;
|
||||
case 'Footer':
|
||||
$printDefaults->footerMargin = (float) $pageSetupAttributes->Margin ?: 1.0;
|
||||
|
||||
break;
|
||||
case 'PageMargins':
|
||||
$this->setMargins($printDefaults, $pageSetupAttributes);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $printDefaults;
|
||||
}
|
||||
|
||||
private function printSetup(SimpleXMLElement $xmlX, stdClass $printDefaults): stdClass
|
||||
{
|
||||
if (isset($xmlX->WorksheetOptions->Print)) {
|
||||
foreach ($xmlX->WorksheetOptions->Print as $printData) {
|
||||
foreach ($printData as $printKey => $printValue) {
|
||||
switch ($printKey) {
|
||||
case 'LeftToRight':
|
||||
$printDefaults->printOrder = PageSetup::PAGEORDER_OVER_THEN_DOWN;
|
||||
|
||||
break;
|
||||
case 'PaperSizeIndex':
|
||||
$printDefaults->paperSize = (int) $printValue ?: 9;
|
||||
|
||||
break;
|
||||
case 'Scale':
|
||||
$printDefaults->scale = (int) $printValue ?: 100;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $printDefaults;
|
||||
}
|
||||
|
||||
private function setLayout(stdClass $printDefaults, SimpleXMLElement $pageSetupAttributes): void
|
||||
{
|
||||
$printDefaults->orientation = (string) strtolower($pageSetupAttributes->Orientation) ?: PageSetup::ORIENTATION_PORTRAIT;
|
||||
$printDefaults->horizontalCentered = (bool) $pageSetupAttributes->CenterHorizontal ?: false;
|
||||
$printDefaults->verticalCentered = (bool) $pageSetupAttributes->CenterVertical ?: false;
|
||||
}
|
||||
|
||||
private function setMargins(stdClass $printDefaults, SimpleXMLElement $pageSetupAttributes): void
|
||||
{
|
||||
$printDefaults->leftMargin = (float) $pageSetupAttributes->Left ?: 1.0;
|
||||
$printDefaults->rightMargin = (float) $pageSetupAttributes->Right ?: 1.0;
|
||||
$printDefaults->topMargin = (float) $pageSetupAttributes->Top ?: 1.0;
|
||||
$printDefaults->bottomMargin = (float) $pageSetupAttributes->Bottom ?: 1.0;
|
||||
}
|
||||
}
|
|
@ -211,4 +211,34 @@ class PageMargins
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromCentimeters(float $value): float
|
||||
{
|
||||
return $value / 2.54;
|
||||
}
|
||||
|
||||
public static function toCentimeters(float $value): float
|
||||
{
|
||||
return $value * 2.54;
|
||||
}
|
||||
|
||||
public static function fromMillimeters(float $value): float
|
||||
{
|
||||
return $value / 25.4;
|
||||
}
|
||||
|
||||
public static function toMillimeters(float $value): float
|
||||
{
|
||||
return $value * 25.4;
|
||||
}
|
||||
|
||||
public static function fromPoints(float $value): float
|
||||
{
|
||||
return $value / 72;
|
||||
}
|
||||
|
||||
public static function toPoints(float $value): float
|
||||
{
|
||||
return $value * 72;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,9 @@ class PageSetup
|
|||
const SETPRINTRANGE_OVERWRITE = 'O';
|
||||
const SETPRINTRANGE_INSERT = 'I';
|
||||
|
||||
const PAGEORDER_OVER_THEN_DOWN = 'overThenDown';
|
||||
const PAGEORDER_DOWN_THEN_OVER = 'downThenOver';
|
||||
|
||||
/**
|
||||
* Paper size.
|
||||
*
|
||||
|
@ -246,6 +249,8 @@ class PageSetup
|
|||
*/
|
||||
private $firstPageNumber;
|
||||
|
||||
private $pageOrder = self::PAGEORDER_DOWN_THEN_OVER;
|
||||
|
||||
/**
|
||||
* Create a new PageSetup.
|
||||
*/
|
||||
|
@ -818,6 +823,20 @@ class PageSetup
|
|||
return $this->setFirstPageNumber(null);
|
||||
}
|
||||
|
||||
public function getPageOrder(): string
|
||||
{
|
||||
return $this->pageOrder;
|
||||
}
|
||||
|
||||
public function setPageOrder(?string $pageOrder): self
|
||||
{
|
||||
if ($pageOrder === null || $pageOrder === self::PAGEORDER_DOWN_THEN_OVER || $pageOrder === self::PAGEORDER_OVER_THEN_DOWN) {
|
||||
$this->pageOrder = $pageOrder ?? self::PAGEORDER_DOWN_THEN_OVER;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement PHP __clone to create a deep clone, not just a shallow copy.
|
||||
*/
|
||||
|
|
|
@ -1729,11 +1729,12 @@ class Worksheet extends BIFFwriter
|
|||
$numFtr = $this->phpSheet->getPageMargins()->getFooter(); // Footer Margin
|
||||
$iCopies = 0x01; // Number of copies
|
||||
|
||||
$fLeftToRight = 0x0; // Print over then down
|
||||
|
||||
// Order of printing pages
|
||||
$fLeftToRight = $this->phpSheet->getPageSetup()->getPageOrder() === PageSetup::PAGEORDER_DOWN_THEN_OVER
|
||||
? 0x1 : 0x0;
|
||||
// Page orientation
|
||||
$fLandscape = ($this->phpSheet->getPageSetup()->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE) ?
|
||||
0x0 : 0x1;
|
||||
$fLandscape = ($this->phpSheet->getPageSetup()->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE)
|
||||
? 0x0 : 0x1;
|
||||
|
||||
$fNoPls = 0x0; // Setup not read from printer
|
||||
$fNoColor = 0x0; // Print black and white
|
||||
|
|
|
@ -875,6 +875,7 @@ class Worksheet extends WriterPart
|
|||
$objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber());
|
||||
$objWriter->writeAttribute('useFirstPageNumber', '1');
|
||||
}
|
||||
$objWriter->writeAttribute('pageOrder', $pSheet->getPageSetup()->getPageOrder());
|
||||
|
||||
$getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData();
|
||||
if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) {
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Gnumeric;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageSetupTest extends TestCase
|
||||
{
|
||||
private const MARGIN_PRECISION = 0.001;
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
protected function setup(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/Gnumeric/PageSetup.gnumeric';
|
||||
$reader = new Gnumeric();
|
||||
$this->spreadsheet = $reader->load($filename);
|
||||
}
|
||||
|
||||
public function testPageSetup(): void
|
||||
{
|
||||
$assertions = $this->pageSetupAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageSetup()->$testMethodName();
|
||||
self::assertSame(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPageMargins(): void
|
||||
{
|
||||
$assertions = $this->pageMarginAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageMargins()->$testMethodName();
|
||||
self::assertEqualsWithDelta(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
self::MARGIN_PRECISION,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test} margin"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetupAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 75,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet2' => [
|
||||
'orientation' => PageSetup::ORIENTATION_LANDSCAPE,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_OVER_THEN_DOWN,
|
||||
],
|
||||
'Sheet3' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 90,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function pageMarginAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
// Here the values are in inches
|
||||
'top' => 0.315,
|
||||
'header' => 0.630,
|
||||
'left' => 0.512,
|
||||
'right' => 0.512,
|
||||
'bottom' => 0.315,
|
||||
'footer' => 0.433,
|
||||
],
|
||||
'Sheet2' => [
|
||||
// Here the values are in inches
|
||||
'top' => 0.315,
|
||||
'header' => 0.433,
|
||||
'left' => 0.709,
|
||||
'right' => 0.709,
|
||||
'bottom' => 0.315,
|
||||
'footer' => 0.433,
|
||||
],
|
||||
'Sheet3' => [
|
||||
// Here the values are in inches
|
||||
'top' => 0.512,
|
||||
'header' => 0.433,
|
||||
'left' => 0.709,
|
||||
'right' => 0.709,
|
||||
'bottom' => 0.512,
|
||||
'footer' => 0.433,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings (in inches)
|
||||
'top' => 0.3,
|
||||
'header' => 0.45,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.3,
|
||||
'footer' => 0.45,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageSetupTest extends TestCase
|
||||
{
|
||||
private const MARGIN_PRECISION = 0.00000001;
|
||||
|
||||
private const MARGIN_UNIT_CONVERSION = 2.54; // Inches to cm
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
protected function setup(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/Ods/PageSetup.ods';
|
||||
$reader = new Ods();
|
||||
$this->spreadsheet = $reader->load($filename);
|
||||
}
|
||||
|
||||
public function testPageSetup(): void
|
||||
{
|
||||
$assertions = $this->pageSetupAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageSetup()->$testMethodName();
|
||||
self::assertSame(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPageMargins(): void
|
||||
{
|
||||
$assertions = $this->pageMarginAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageMargins()->$testMethodName();
|
||||
self::assertEqualsWithDelta(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
self::MARGIN_PRECISION,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test} margin"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetupAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 75,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet2' => [
|
||||
'orientation' => PageSetup::ORIENTATION_LANDSCAPE,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_OVER_THEN_DOWN,
|
||||
],
|
||||
'Sheet3' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 90,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings
|
||||
'orientation' => PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function pageMarginAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
// Here the values are in cm
|
||||
'top' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.6 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.1 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet2' => [
|
||||
// Here the values are in cm
|
||||
'top' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.1 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.1 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet3' => [
|
||||
// Here the values are in cm
|
||||
'top' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.1 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.1 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings (already in inches)
|
||||
'top' => 0.3,
|
||||
'header' => 0.45,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.3,
|
||||
'footer' => 0.45,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageSetupTest extends TestCase
|
||||
{
|
||||
private const MARGIN_PRECISION = 0.00000001;
|
||||
|
||||
private const MARGIN_UNIT_CONVERSION = 2.54; // Inches to cm
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
protected function setup(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLS/PageSetup.xls';
|
||||
$reader = new Xls();
|
||||
$this->spreadsheet = $reader->load($filename);
|
||||
}
|
||||
|
||||
public function testPageSetup(): void
|
||||
{
|
||||
$assertions = $this->pageSetupAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageSetup()->$testMethodName();
|
||||
self::assertSame(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPageMargins(): void
|
||||
{
|
||||
$assertions = $this->pageMarginAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageMargins()->$testMethodName();
|
||||
self::assertEqualsWithDelta(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
self::MARGIN_PRECISION,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test} margin"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetupAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 75,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet2' => [
|
||||
'orientation' => PageSetup::ORIENTATION_LANDSCAPE,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_OVER_THEN_DOWN,
|
||||
],
|
||||
'Sheet3' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 90,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings
|
||||
'orientation' => PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function pageMarginAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet2' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet3' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings (already in inches for comparison)
|
||||
'top' => 0.75,
|
||||
'header' => 0.3,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.75,
|
||||
'footer' => 0.3,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageSetupTest extends TestCase
|
||||
{
|
||||
private const MARGIN_PRECISION = 0.00000001;
|
||||
|
||||
private const MARGIN_UNIT_CONVERSION = 2.54; // Inches to cm
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
protected function setup(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/XLSX/PageSetup.xlsx';
|
||||
$reader = new Xlsx();
|
||||
$this->spreadsheet = $reader->load($filename);
|
||||
}
|
||||
|
||||
public function testPageSetup(): void
|
||||
{
|
||||
$assertions = $this->pageSetupAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageSetup()->$testMethodName();
|
||||
self::assertSame(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPageMargins(): void
|
||||
{
|
||||
$assertions = $this->pageMarginAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageMargins()->$testMethodName();
|
||||
self::assertEqualsWithDelta(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
self::MARGIN_PRECISION,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test} margin"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetupAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 75,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet2' => [
|
||||
'orientation' => PageSetup::ORIENTATION_LANDSCAPE,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_OVER_THEN_DOWN,
|
||||
],
|
||||
'Sheet3' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 90,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings
|
||||
'orientation' => PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function pageMarginAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet2' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet3' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings (already in inches for comparison)
|
||||
'top' => 0.75,
|
||||
'header' => 0.3,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.75,
|
||||
'footer' => 0.3,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xml;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xml;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageSetupTest extends TestCase
|
||||
{
|
||||
private const MARGIN_PRECISION = 0.000001;
|
||||
|
||||
private const MARGIN_UNIT_CONVERSION = 2.54; // Inches to cm
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
private $spreadsheet;
|
||||
|
||||
protected function setup(): void
|
||||
{
|
||||
$filename = 'tests/data/Reader/Xml/PageSetup.xml';
|
||||
$reader = new Xml();
|
||||
$this->spreadsheet = $reader->load($filename);
|
||||
}
|
||||
|
||||
public function testPageSetup(): void
|
||||
{
|
||||
$assertions = $this->pageSetupAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageSetup()->$testMethodName();
|
||||
self::assertSame(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testPageMargins(): void
|
||||
{
|
||||
$assertions = $this->pageMarginAssertions();
|
||||
|
||||
foreach ($this->spreadsheet->getAllSheets() as $worksheet) {
|
||||
if (!array_key_exists($worksheet->getTitle(), $assertions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetAssertions = $assertions[$worksheet->getTitle()];
|
||||
foreach ($sheetAssertions as $test => $expectedResult) {
|
||||
$testMethodName = 'get' . ucfirst($test);
|
||||
$actualResult = $worksheet->getPageMargins()->$testMethodName();
|
||||
self::assertEqualsWithDelta(
|
||||
$expectedResult,
|
||||
$actualResult,
|
||||
self::MARGIN_PRECISION,
|
||||
"Failed assertion for Worksheet '{$worksheet->getTitle()}' {$test} margin"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function pageSetupAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 75,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet2' => [
|
||||
'orientation' => PageSetup::ORIENTATION_LANDSCAPE,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_OVER_THEN_DOWN,
|
||||
],
|
||||
'Sheet3' => [
|
||||
'orientation' => PageSetup::ORIENTATION_PORTRAIT,
|
||||
'scale' => 90,
|
||||
'horizontalCentered' => true,
|
||||
'verticalCentered' => true,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings
|
||||
'orientation' => PageSetup::ORIENTATION_DEFAULT,
|
||||
'scale' => 100,
|
||||
'horizontalCentered' => false,
|
||||
'verticalCentered' => false,
|
||||
'pageOrder' => PageSetup::PAGEORDER_DOWN_THEN_OVER,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function pageMarginAssertions(): array
|
||||
{
|
||||
return [
|
||||
'Sheet1' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet2' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 1.9 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 0.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet3' => [
|
||||
// Here the values are in cm, so we convert to inches for comparison with internal uom
|
||||
'top' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'header' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
'left' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'right' => 1.8 / self::MARGIN_UNIT_CONVERSION,
|
||||
'bottom' => 2.4 / self::MARGIN_UNIT_CONVERSION,
|
||||
'footer' => 1.3 / self::MARGIN_UNIT_CONVERSION,
|
||||
],
|
||||
'Sheet4' => [
|
||||
// Default Settings (already in inches for comparison)
|
||||
'top' => 0.75,
|
||||
'header' => 0.3,
|
||||
'left' => 0.7,
|
||||
'right' => 0.7,
|
||||
'bottom' => 0.75,
|
||||
'footer' => 0.3,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\PageMargins;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PageMarginsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerPointsAndInches
|
||||
*/
|
||||
public function testPointsToInches(float $value, float $expectedResult): void
|
||||
{
|
||||
$actualResult = PageMargins::fromPoints($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPointsAndInches
|
||||
*/
|
||||
public function testInchesToPoints(float $expectedResult, float $value): void
|
||||
{
|
||||
$actualResult = PageMargins::toPoints($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCentimetersAndInches
|
||||
*/
|
||||
public function testCentimetersToInches(float $value, float $expectedResult): void
|
||||
{
|
||||
$actualResult = PageMargins::fromCentimeters($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCentimetersAndInches
|
||||
*/
|
||||
public function testPointsToCentimeters(float $expectedResult, float $value): void
|
||||
{
|
||||
$actualResult = PageMargins::toCentimeters($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMillimetersAndInches
|
||||
*/
|
||||
public function testMillimetersToInches(float $value, float $expectedResult): void
|
||||
{
|
||||
$actualResult = PageMargins::fromMillimeters($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMillimetersAndInches
|
||||
*/
|
||||
public function testPointsToMillimeters(float $expectedResult, float $value): void
|
||||
{
|
||||
$actualResult = PageMargins::toMillimeters($value);
|
||||
self::assertSame($expectedResult, $actualResult);
|
||||
}
|
||||
|
||||
public function providerPointsAndInches(): array
|
||||
{
|
||||
return [
|
||||
[36, 0.5],
|
||||
[72, 1.0],
|
||||
[90, 1.25],
|
||||
[144, 2.0],
|
||||
];
|
||||
}
|
||||
|
||||
public function providerCentimetersAndInches(): array
|
||||
{
|
||||
return [
|
||||
[1.27, 0.5],
|
||||
[2.54, 1.0],
|
||||
];
|
||||
}
|
||||
|
||||
public function providerMillimetersAndInches(): array
|
||||
{
|
||||
return [
|
||||
[12.7, 0.5],
|
||||
[25.4, 1.0],
|
||||
];
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,250 @@
|
|||
<?xml version="1.0"?>
|
||||
<?mso-application progid="Excel.Sheet"?>
|
||||
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40">
|
||||
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<Author>Mark Baker</Author>
|
||||
<LastAuthor>Mark Baker</LastAuthor>
|
||||
<LastPrinted>2020-07-04T11:51:41Z</LastPrinted>
|
||||
<Created>2020-06-29T17:37:00Z</Created>
|
||||
<LastSaved>2020-07-04T11:52:32Z</LastSaved>
|
||||
<Version>16.00</Version>
|
||||
</DocumentProperties>
|
||||
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<AllowPNG/>
|
||||
</OfficeDocumentSettings>
|
||||
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<WindowHeight>13170</WindowHeight>
|
||||
<WindowWidth>21600</WindowWidth>
|
||||
<WindowTopX>2145</WindowTopX>
|
||||
<WindowTopY>2145</WindowTopY>
|
||||
<ProtectStructure>False</ProtectStructure>
|
||||
<ProtectWindows>False</ProtectWindows>
|
||||
</ExcelWorkbook>
|
||||
<Styles>
|
||||
<Style ss:ID="Default" ss:Name="Normal">
|
||||
<Alignment ss:Vertical="Bottom"/>
|
||||
<Borders/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
|
||||
<Interior/>
|
||||
<NumberFormat/>
|
||||
<Protection/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Sheet1">
|
||||
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="5" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="14.25">
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">1</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">2</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">3</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">4</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">5</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">6</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">7</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">8</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">9</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:Index="5" ss:AutoFitHeight="0">
|
||||
<Cell ss:Formula="=SUM(R[-3]C:R[-3]C[2],R[-4]C[1]:R[-2]C[1])"><Data
|
||||
ss:Type="Number">30</Data></Cell>
|
||||
<Cell ss:Formula="=COUNT(R[-3]C[-1]:R[-3]C[1],R[-4]C:R[-2]C)"><Data
|
||||
ss:Type="Number">6</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Layout x:CenterHorizontal="1"/>
|
||||
<Header x:Margin="0.31496062992125984"/>
|
||||
<Footer x:Margin="0.31496062992125984"/>
|
||||
<PageMargins x:Bottom="0.74803149606299213" x:Left="0.51181102362204722"
|
||||
x:Right="0.51181102362204722" x:Top="0.94488188976377963"/>
|
||||
</PageSetup>
|
||||
<Unsynced/>
|
||||
<Print>
|
||||
<ValidPrinterInfo/>
|
||||
<PaperSizeIndex>9</PaperSizeIndex>
|
||||
<Scale>75</Scale>
|
||||
<VerticalResolution>0</VerticalResolution>
|
||||
</Print>
|
||||
<Selected/>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
<RangeSelection>R1C1:R5C3</RangeSelection>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Sheet2">
|
||||
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="5" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="14.25">
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">1</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">2</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">3</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">4</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">5</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">6</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">7</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">8</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">9</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:Index="5" ss:AutoFitHeight="0">
|
||||
<Cell ss:Formula="=SUM(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">60</Data></Cell>
|
||||
<Cell ss:Formula="=COUNT(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">12</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Layout x:Orientation="Landscape" x:CenterVertical="1"/>
|
||||
<Header x:Margin="0.31496062992125984"/>
|
||||
<Footer x:Margin="0.31496062992125984"/>
|
||||
<PageMargins x:Bottom="0.74803149606299213" x:Left="0.70866141732283472"
|
||||
x:Right="0.70866141732283472" x:Top="0.74803149606299213"/>
|
||||
</PageSetup>
|
||||
<Unsynced/>
|
||||
<Print>
|
||||
<LeftToRight/>
|
||||
<ValidPrinterInfo/>
|
||||
<PaperSizeIndex>9</PaperSizeIndex>
|
||||
<VerticalResolution>0</VerticalResolution>
|
||||
</Print>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
<RangeSelection>R1C1:R5C3</RangeSelection>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Sheet3">
|
||||
<Names>
|
||||
<NamedRange ss:Name="Print_Area" ss:RefersTo="=Sheet3!R1C1:R5C3"/>
|
||||
</Names>
|
||||
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="5" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="14.25">
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">1</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">2</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">3</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">4</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">5</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">6</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="Number">7</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">8</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell><Data ss:Type="Number">9</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
</Row>
|
||||
<Row ss:Index="5" ss:AutoFitHeight="0">
|
||||
<Cell ss:Formula="=SUM(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">60</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
<Cell ss:Formula="=COUNT(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">12</Data><NamedCell ss:Name="Print_Area"/></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Layout x:CenterHorizontal="1" x:CenterVertical="1"/>
|
||||
<Header x:Margin="0.51181102362204722"/>
|
||||
<Footer x:Margin="0.51181102362204722"/>
|
||||
<PageMargins x:Bottom="0.94488188976377963" x:Left="0.70866141732283472"
|
||||
x:Right="0.70866141732283472" x:Top="0.94488188976377963"/>
|
||||
</PageSetup>
|
||||
<Unsynced/>
|
||||
<Print>
|
||||
<ValidPrinterInfo/>
|
||||
<PaperSizeIndex>9</PaperSizeIndex>
|
||||
<Scale>90</Scale>
|
||||
<VerticalResolution>0</VerticalResolution>
|
||||
</Print>
|
||||
<FreezePanes/>
|
||||
<FrozenNoSplit/>
|
||||
<SplitHorizontal>1</SplitHorizontal>
|
||||
<TopRowBottomPane>1</TopRowBottomPane>
|
||||
<SplitVertical>1</SplitVertical>
|
||||
<LeftColumnRightPane>1</LeftColumnRightPane>
|
||||
<ActivePane>0</ActivePane>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>1</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>2</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>0</Number>
|
||||
<ActiveRow>0</ActiveRow>
|
||||
<ActiveCol>0</ActiveCol>
|
||||
<RangeSelection>R1C1:R5C3</RangeSelection>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Sheet4">
|
||||
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="5" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="51" ss:DefaultRowHeight="14.25">
|
||||
<Row>
|
||||
<Cell><Data ss:Type="Number">1</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">2</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">3</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="Number">4</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">5</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">6</Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell><Data ss:Type="Number">7</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">8</Data></Cell>
|
||||
<Cell><Data ss:Type="Number">9</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:Index="5">
|
||||
<Cell ss:Formula="=SUM(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">60</Data></Cell>
|
||||
<Cell ss:Formula="=COUNT(R1C1:R1C3,R3C1:R3C3,R1C1:R3C1,R1C3:R3C3)"><Data
|
||||
ss:Type="Number">12</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
<RangeSelection>R1C1:R5C3</RangeSelection>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
</Workbook>
|
Loading…
Reference in New Issue