Test for calendar when reading Excel Files.

Set Excel calendar to be used for calculations and formatting for the calendar stored against the spreadsheet.
This commit is contained in:
MarkBaker
2022-07-13 17:42:40 +02:00
parent 95cf51b412
commit 3964087779
9 changed files with 166 additions and 18 deletions
-10
View File
@@ -990,11 +990,6 @@ parameters:
count: 6
path: src/PhpSpreadsheet/Cell/Cell.php
-
message: "#^Unreachable statement \\- code above always terminates\\.$#"
count: 1
path: src/PhpSpreadsheet/Cell/Cell.php
-
message: "#^Call to an undefined method object\\:\\:getHashCode\\(\\)\\.$#"
count: 1
@@ -2580,11 +2575,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Shared/OLERead.php
-
message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#"
count: 1
path: src/PhpSpreadsheet/Shared/StringHelper.php
-
message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#"
count: 1
+15 -6
View File
@@ -15,6 +15,7 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Style;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Throwable;
use function _PHPStan_59fb0a3b2\RingCentral\Psr7\str;
class Cell
{
@@ -176,16 +177,22 @@ class Cell
/**
* Get cell value with formatting.
*
* @return string
*/
public function getFormattedValue()
public function getFormattedValue(): string
{
return (string) NumberFormat::toFormattedString(
$currentCalendar = SharedDate::getExcelCalendar();
SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar());
$formattedValue = (string) NumberFormat::toFormattedString(
$this->getCalculatedValue(),
$this->getStyle()
->getNumberFormat()->getFormatCode()
);
SharedDate::setExcelCalendar($currentCalendar);
return $formattedValue;
}
/**
@@ -342,8 +349,6 @@ class Cell
break;
default:
throw new Exception('Invalid datatype: ' . $dataType);
break;
}
// set the datatype
@@ -403,6 +408,8 @@ class Cell
{
if ($this->dataType === DataType::TYPE_FORMULA) {
try {
// $currentCalendar = SharedDate::getExcelCalendar();
// SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar());
$coordinate = $this->getCoordinate();
$worksheet = $this->getWorksheet();
$value = $this->value;
@@ -430,6 +437,7 @@ class Cell
$this->getWorksheet()->setSelectedCells($selected);
$this->getWorksheet()->getParent()->setActiveSheetIndex($index);
} catch (Exception $ex) {
// SharedDate::setExcelCalendar($currentCalendar);
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
return $this->calculatedValue; // Fallback for calculations referencing external files.
} elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) {
@@ -441,6 +449,7 @@ class Cell
);
}
// SharedDate::setExcelCalendar($currentCalendar);
if ($result === '#Not Yet Implemented') {
return $this->calculatedValue; // Fallback if calculation engine does not support the formula.
}
+3 -2
View File
@@ -67,7 +67,7 @@ class Date
protected static $defaultTimeZone;
/**
* Set the Excel Default Calendar (Windows 1900 or Mac 1904).
* Set the Excel Date Calendar (Windows 1900 or Mac 1904) used for calculations and formatting.
*
* @param int $baseYear Excel base date (1900 or 1904)
*
@@ -85,7 +85,8 @@ class Date
}
/**
* Return the Excel Default Calendar (Windows 1900 or Mac 1904).
* Return the Excel Date Calendar (Windows 1900 or Mac 1904)
* to be used for current calculations and formatting.
*
* @return int Excel base date (1900 or 1904)
*/
@@ -0,0 +1,45 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PHPUnit\Framework\TestCase;
class DateReaderTest extends TestCase
{
protected function tearDown(): void
{
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
}
public function testReadExcel1900Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLS/1900_Calendar.xls';
$reader = new Xls();
$spreadsheet = $reader->load($filename);
self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar());
$worksheet = $spreadsheet->getActiveSheet();
self::assertSame(44562, $worksheet->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
self::assertSame(44926, $worksheet->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
}
public function testReadExcel1904Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLS/1904_Calendar.xls';
$reader = new Xls();
$spreadsheet = $reader->load($filename);
self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar());
$worksheet = $spreadsheet->getActiveSheet();
self::assertSame(43100, $worksheet->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
self::assertSame(43464, $worksheet->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
}
}
@@ -0,0 +1,103 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PHPUnit\Framework\TestCase;
class DateReaderTest extends TestCase
{
protected function tearDown(): void
{
Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
}
public function testReadExcel1900Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLSX/1900_Calendar.xlsx';
$reader = new Xlsx();
$spreadsheet = $reader->load($filename);
self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar());
$worksheet = $spreadsheet->getActiveSheet();
self::assertSame(44562, $worksheet->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
self::assertSame(44926, $worksheet->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
self::assertSame(44561, $worksheet->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue());
self::assertSame(44927, $worksheet->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue());
}
public function testReadExcel1904Spreadsheet(): void
{
$filename = 'tests/data/Reader/XLSX/1904_Calendar.xlsx';
$reader = new Xlsx();
$spreadsheet = $reader->load($filename);
self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar());
$worksheet = $spreadsheet->getActiveSheet();
self::assertSame(43100, $worksheet->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue());
self::assertSame(43464, $worksheet->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue());
self::assertSame(43099, $worksheet->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue());
self::assertSame(43465, $worksheet->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue());
}
public function testSwitchCalendars(): void
{
$filename1900 = 'tests/data/Reader/XLSX/1900_Calendar.xlsx';
$reader1900 = new Xlsx();
$spreadsheet1900 = $reader1900->load($filename1900);
$worksheet1900 = $spreadsheet1900->getActiveSheet();
$filename1904 = 'tests/data/Reader/XLSX/1904_Calendar.xlsx';
$reader1904 = new Xlsx();
$spreadsheet1904 = $reader1904->load($filename1904);
$worksheet1904 = $spreadsheet1904->getActiveSheet();
self::assertSame(44562, $worksheet1900->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue());
self::assertSame(44926, $worksheet1900->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue());
self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue());
self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue());
self::assertSame(43100, $worksheet1904->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue());
self::assertSame(43464, $worksheet1904->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue());
self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue());
self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue());
// Check that accessing date values from one spreadsheet doesn't break accessing correct values from another
self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue());
self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue());
self::assertSame(44562, $worksheet1900->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue());
self::assertSame(44926, $worksheet1900->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue());
self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue());
self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue());
self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue());
self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue());
self::assertSame(43100, $worksheet1904->getCell('A1')->getValue());
self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue());
self::assertSame(43464, $worksheet1904->getCell('A2')->getValue());
self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue());
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.