PHPStan Level 2

This commit is contained in:
Adrien Crivelli 2021-04-03 17:42:11 +09:00
parent 42761f90b7
commit d02352845c
No known key found for this signature in database
GPG Key ID: 16D79B903B4B5874
90 changed files with 778 additions and 591 deletions

View File

@ -160,7 +160,7 @@ return PhpCsFixer\Config::create()
'php_unit_test_annotation' => true, 'php_unit_test_annotation' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'php_unit_test_class_requires_covers' => false, // We don't care as much as we should about coverage 'php_unit_test_class_requires_covers' => false, // We don't care as much as we should about coverage
'phpdoc_add_missing_param_annotation' => true, 'phpdoc_add_missing_param_annotation' => false, // Don't add things that bring no value
'phpdoc_align' => false, // Waste of time 'phpdoc_align' => false, // Waste of time
'phpdoc_annotation_without_dot' => true, 'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true, 'phpdoc_indent' => true,

View File

@ -1,11 +1,16 @@
parameters: parameters:
level: 1 level: 2
paths: paths:
- src/ - src/
- tests/ - tests/
ignoreErrors: ignoreErrors:
- '~^Class GdImage not found\.$~' - '~^Class GdImage not found\.$~'
- '~^Return typehint of method .* has invalid type GdImage\.$~'
- '~^Property .* has unknown class GdImage as its type\.$~'
- '~^Parameter .* of method .* has invalid typehint type GdImage\.$~'
# Ignore all JpGraph issues # Ignore all JpGraph issues
- '~^Constant (MARK_CIRCLE|MARK_CROSS|MARK_DIAMOND|MARK_DTRIANGLE|MARK_FILLEDCIRCLE|MARK_SQUARE|MARK_STAR|MARK_UTRIANGLE|MARK_X|SIDE_RIGHT) not found\.$~' - '~^Constant (MARK_CIRCLE|MARK_CROSS|MARK_DIAMOND|MARK_DTRIANGLE|MARK_FILLEDCIRCLE|MARK_SQUARE|MARK_STAR|MARK_UTRIANGLE|MARK_X|SIDE_RIGHT) not found\.$~'
- '~^Instantiated class (AccBarPlot|AccLinePlot|BarPlot|ContourPlot|Graph|GroupBarPlot|GroupBarPlot|LinePlot|LinePlot|PieGraph|PiePlot|PiePlot3D|PiePlotC|RadarGraph|RadarPlot|ScatterPlot|Spline|StockPlot) not found\.$~' - '~^Instantiated class (AccBarPlot|AccLinePlot|BarPlot|ContourPlot|Graph|GroupBarPlot|GroupBarPlot|LinePlot|LinePlot|PieGraph|PiePlot|PiePlot3D|PiePlotC|RadarGraph|RadarPlot|ScatterPlot|Spline|StockPlot) not found\.$~'
- '~^Call to method .*\(\) on an unknown class (AccBarPlot|AccLinePlot|BarPlot|ContourPlot|Graph|GroupBarPlot|GroupBarPlot|LinePlot|LinePlot|PieGraph|PiePlot|PiePlot3D|PiePlotC|RadarGraph|RadarPlot|ScatterPlot|Spline|StockPlot)\.$~'
- '~^Access to property .* on an unknown class (AccBarPlot|AccLinePlot|BarPlot|ContourPlot|Graph|GroupBarPlot|GroupBarPlot|LinePlot|LinePlot|PieGraph|PiePlot|PiePlot3D|PiePlotC|RadarGraph|RadarPlot|ScatterPlot|Spline|StockPlot)\.$~'

View File

@ -198,7 +198,7 @@ class DateTime
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
* depending on the value of the ReturnDateType flag * depending on the value of the ReturnDateType flag
*/ */
public static function DATEVALUE($dateValue = 1) public static function DATEVALUE($dateValue)
{ {
return DateTimeExcel\DateValue::funcDateValue($dateValue); return DateTimeExcel\DateValue::funcDateValue($dateValue);
} }

View File

@ -89,7 +89,7 @@ class DateDif
private static function datedifM(DateInterval $PHPDiffDateObject): int private static function datedifM(DateInterval $PHPDiffDateObject): int
{ {
return (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m'); return 12 * (int) $PHPDiffDateObject->format('%y') + (int) $PHPDiffDateObject->format('%m');
} }
private static function datedifMD(int $startDays, int $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int private static function datedifMD(int $startDays, int $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int

View File

@ -33,7 +33,7 @@ class DateValue
* @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
* depending on the value of the ReturnDateType flag * depending on the value of the ReturnDateType flag
*/ */
public static function funcDateValue($dateValue = 1) public static function funcDateValue($dateValue)
{ {
$dti = new DateTimeImmutable(); $dti = new DateTimeImmutable();
$baseYear = Date::getExcelCalendar(); $baseYear = Date::getExcelCalendar();

View File

@ -19,20 +19,20 @@ class Days360
* DAYS360(startDate,endDate[,method]) * DAYS360(startDate,endDate[,method])
* *
* @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string * PHP DateTime object, or a standard date string
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string * PHP DateTime object, or a standard date string
* @param mixed $method US or European Method as a bool * @param mixed $method US or European Method as a bool
* FALSE or omitted: U.S. (NASD) method. If the starting date is * FALSE or omitted: U.S. (NASD) method. If the starting date is
* the last day of a month, it becomes equal to the 30th of the * the last day of a month, it becomes equal to the 30th of the
* same month. If the ending date is the last day of a month and * same month. If the ending date is the last day of a month and
* the starting date is earlier than the 30th of a month, the * the starting date is earlier than the 30th of a month, the
* ending date becomes equal to the 1st of the next month; * ending date becomes equal to the 1st of the next month;
* otherwise the ending date becomes equal to the 30th of the * otherwise the ending date becomes equal to the 30th of the
* same month. * same month.
* TRUE: European method. Starting dates and ending dates that * TRUE: European method. Starting dates and ending dates that
* occur on the 31st of a month become equal to the 30th of the * occur on the 31st of a month become equal to the 30th of the
* same month. * same month.
* *
* @return int|string Number of days between start date and end date * @return int|string Number of days between start date and end date
*/ */

View File

@ -67,9 +67,9 @@ class WeekNum
return 0; return 0;
} }
Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches Helpers::silly1900($PHPDateObject, '+ 5 years'); // 1905 calendar matches
$dayOfYear = $PHPDateObject->format('z'); $dayOfYear = (int) $PHPDateObject->format('z');
$PHPDateObject->modify('-' . $dayOfYear . ' days'); $PHPDateObject->modify('-' . $dayOfYear . ' days');
$firstDayOfFirstWeek = $PHPDateObject->format('w'); $firstDayOfFirstWeek = (int) $PHPDateObject->format('w');
$daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7; $daysInFirstWeek = (6 - $firstDayOfFirstWeek + $method) % 7;
$daysInFirstWeek += 7 * !$daysInFirstWeek; $daysInFirstWeek += 7 * !$daysInFirstWeek;
$endFirstWeek = $daysInFirstWeek - 1; $endFirstWeek = $daysInFirstWeek - 1;

View File

@ -129,6 +129,7 @@ class WorkDay
$startDoW = WeekDay::funcWeekDay($startDate, 3); $startDoW = WeekDay::funcWeekDay($startDate, 3);
if (WeekDay::funcWeekDay($startDate, 3) >= 5) { if (WeekDay::funcWeekDay($startDate, 3) >= 5) {
// @phpstan-ignore-next-line
$startDate += -$startDoW + 4; $startDate += -$startDoW + 4;
++$endDays; ++$endDays;
} }
@ -173,6 +174,7 @@ class WorkDay
// Adjust the calculated end date if it falls over a weekend // Adjust the calculated end date if it falls over a weekend
$endDoW = WeekDay::funcWeekDay($endDate, 3); $endDoW = WeekDay::funcWeekDay($endDate, 3);
if ($endDoW >= 5) { if ($endDoW >= 5) {
// @phpstan-ignore-next-line
$endDate += -$endDoW + 4; $endDate += -$endDoW + 4;
} }
} }

View File

@ -22,11 +22,11 @@ class BesselI
* This code provides a more accurate calculation * This code provides a more accurate calculation
* *
* @param mixed $x A float value at which to evaluate the function. * @param mixed $x A float value at which to evaluate the function.
* If x is nonnumeric, BESSELI returns the #VALUE! error value. * If x is nonnumeric, BESSELI returns the #VALUE! error value.
* @param mixed $ord The integer order of the Bessel function. * @param mixed $ord The integer order of the Bessel function.
* If ord is not an integer, it is truncated. * If ord is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELI returns the #VALUE! error value. * If $ord is nonnumeric, BESSELI returns the #VALUE! error value.
* If $ord < 0, BESSELI returns the #NUM! error value. * If $ord < 0, BESSELI returns the #NUM! error value.
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error
*/ */

View File

@ -21,11 +21,11 @@ class BesselJ
* values with x < -8 and x > 8. This code provides a more accurate calculation * values with x < -8 and x > 8. This code provides a more accurate calculation
* *
* @param mixed $x A float value at which to evaluate the function. * @param mixed $x A float value at which to evaluate the function.
* If x is nonnumeric, BESSELJ returns the #VALUE! error value. * If x is nonnumeric, BESSELJ returns the #VALUE! error value.
* @param mixed $ord The integer order of the Bessel function. * @param mixed $ord The integer order of the Bessel function.
* If ord is not an integer, it is truncated. * If ord is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value.
* If $ord < 0, BESSELJ returns the #NUM! error value. * If $ord < 0, BESSELJ returns the #NUM! error value.
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error
*/ */

View File

@ -19,10 +19,10 @@ class BesselK
* BESSELK(x,ord) * BESSELK(x,ord)
* *
* @param mixed $x A float value at which to evaluate the function. * @param mixed $x A float value at which to evaluate the function.
* If x is nonnumeric, BESSELK returns the #VALUE! error value. * If x is nonnumeric, BESSELK returns the #VALUE! error value.
* @param mixed $ord The integer order of the Bessel function. * @param mixed $ord The integer order of the Bessel function.
* If ord is not an integer, it is truncated. * If ord is not an integer, it is truncated.
* If $ord is nonnumeric, BESSELK returns the #VALUE! error value. * If $ord is nonnumeric, BESSELK returns the #VALUE! error value.
* If $ord < 0, BESSELKI returns the #NUM! error value. * If $ord < 0, BESSELKI returns the #NUM! error value.
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error

View File

@ -198,6 +198,7 @@ class NonPeriodic
return $e->getMessage(); return $e->getMessage();
} }
if ($date0 > $datei) { if ($date0 > $datei) {
/** @phpstan-ignore-next-line */
$dif = $ordered ? Functions::NAN() : -DateTimeExcel\DateDif::funcDateDif($datei, $date0, 'd'); $dif = $ordered ? Functions::NAN() : -DateTimeExcel\DateDif::funcDateDif($datei, $date0, 'd');
} else { } else {
$dif = DateTimeExcel\DateDif::funcDateDif($date0, $datei, 'd'); $dif = DateTimeExcel\DateDif::funcDateDif($date0, $datei, 'd');

View File

@ -576,7 +576,7 @@ class Functions
/** /**
* Convert a multi-dimensional array to a simple 1-dimensional array. * Convert a multi-dimensional array to a simple 1-dimensional array.
* *
* @param mixed (array) $array Array to be flattened * @param array|mixed $array Array to be flattened
* *
* @return array Flattened array * @return array Flattened array
*/ */
@ -609,7 +609,7 @@ class Functions
/** /**
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing. * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing.
* *
* @param mixed (array) $array Array to be flattened * @param array|mixed $array Array to be flattened
* *
* @return array Flattened array * @return array Flattened array
*/ */

View File

@ -9,7 +9,7 @@ class Matrix
/** /**
* TRANSPOSE. * TRANSPOSE.
* *
* @param mixed (array) $matrixData A matrix of values * @param array|mixed $matrixData A matrix of values
* *
* @return array * @return array
*/ */

View File

@ -27,7 +27,7 @@ class AddressHelper
} }
// Bracketed R references are relative to the current row // Bracketed R references are relative to the current row
if ($rowReference[0] === '[') { if ($rowReference[0] === '[') {
$rowReference = $currentRowNumber + trim($rowReference, '[]'); $rowReference = $currentRowNumber + (int) trim($rowReference, '[]');
} }
$columnReference = $cellReference[4]; $columnReference = $cellReference[4];
// Empty C reference is the current column // Empty C reference is the current column
@ -36,7 +36,7 @@ class AddressHelper
} }
// Bracketed C references are relative to the current column // Bracketed C references are relative to the current column
if (is_string($columnReference) && $columnReference[0] === '[') { if (is_string($columnReference) && $columnReference[0] === '[') {
$columnReference = $currentColumnNumber + trim($columnReference, '[]'); $columnReference = $currentColumnNumber + (int) trim($columnReference, '[]');
} }
if ($columnReference <= 0 || $rowReference <= 0) { if ($columnReference <= 0 || $rowReference <= 0) {

View File

@ -25,7 +25,7 @@ abstract class Coordinate
* *
* @param string $pCoordinateString eg: 'A1' * @param string $pCoordinateString eg: 'A1'
* *
* @return string[] Array containing column and row (indexes 0 and 1) * @return array{0: string, 1: string} Array containing column and row (indexes 0 and 1)
*/ */
public static function coordinateFromString($pCoordinateString) public static function coordinateFromString($pCoordinateString)
{ {
@ -40,6 +40,23 @@ abstract class Coordinate
throw new Exception('Invalid cell coordinate ' . $pCoordinateString); throw new Exception('Invalid cell coordinate ' . $pCoordinateString);
} }
/**
* Get indexes from a string coordinates.
*
* @param string $coordinates eg: 'A1', '$B$12'
*
* @return array{0: int, 1: int} Array containing column index and row index (indexes 0 and 1)
*/
public static function indexesFromString(string $coordinates): array
{
[$col, $row] = self::coordinateFromString($coordinates);
return [
self::columnIndexFromString(ltrim($col, '$')),
(int) ltrim($row, '$'),
];
}
/** /**
* Checks if a coordinate represents a range of cells. * Checks if a coordinate represents a range of cells.
* *

View File

@ -135,10 +135,8 @@ class Axis extends Properties
* Get Series Data Type. * Get Series Data Type.
* *
* @param mixed $format_code * @param mixed $format_code
*
* @return string
*/ */
public function setAxisNumberProperties($format_code) public function setAxisNumberProperties($format_code): void
{ {
$this->axisNumber['format'] = (string) $format_code; $this->axisNumber['format'] = (string) $format_code;
$this->axisNumber['source_linked'] = 0; $this->axisNumber['source_linked'] = 0;
@ -367,7 +365,7 @@ class Axis extends Properties
/** /**
* Set Shadow Properties from Mapped Values. * Set Shadow Properties from Mapped Values.
* *
* @param mixed &$reference * @param mixed $reference
* *
* @return $this * @return $this
*/ */

View File

@ -424,7 +424,7 @@ class Chart
/** /**
* Get the top left position of the chart. * Get the top left position of the chart.
* *
* @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell * @return array{cell: string, xOffset: int, yOffset: int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
*/ */
public function getTopLeftPosition() public function getTopLeftPosition()
{ {

View File

@ -318,7 +318,7 @@ class GridLines extends Properties
/** /**
* Set Shadow Properties Values. * Set Shadow Properties Values.
* *
* @param mixed &$reference * @param mixed $reference
* *
* @return $this * @return $this
*/ */

View File

@ -43,10 +43,8 @@ class PlotArea
/** /**
* Get Number of Plot Groups. * Get Number of Plot Groups.
*
* @return array of DataSeries
*/ */
public function getPlotGroupCount() public function getPlotGroupCount(): int
{ {
return count($this->plotSeries); return count($this->plotSeries);
} }

View File

@ -392,13 +392,11 @@ class Properties
/** /**
* Get a Custom Property Type. * Get a Custom Property Type.
* *
* @return string * @return null|string
*/ */
public function getCustomPropertyType(string $propertyName) public function getCustomPropertyType(string $propertyName)
{ {
if (isset($this->customProperties[$propertyName])) { return $this->customProperties[$propertyName]['type'] ?? null;
return $this->customProperties[$propertyName]['type'];
}
} }
private function identifyPropertyType($propertyValue) private function identifyPropertyType($propertyValue)

View File

@ -2,12 +2,15 @@
namespace PhpOffice\PhpSpreadsheet; namespace PhpOffice\PhpSpreadsheet;
/**
* @template T of IComparable
*/
class HashTable class HashTable
{ {
/** /**
* HashTable elements. * HashTable elements.
* *
* @var IComparable[] * @var T[]
*/ */
protected $items = []; protected $items = [];
@ -21,7 +24,7 @@ class HashTable
/** /**
* Create a new \PhpOffice\PhpSpreadsheet\HashTable. * Create a new \PhpOffice\PhpSpreadsheet\HashTable.
* *
* @param IComparable[] $pSource Optional source array to create HashTable from * @param T[] $pSource Optional source array to create HashTable from
*/ */
public function __construct($pSource = null) public function __construct($pSource = null)
{ {
@ -34,7 +37,7 @@ class HashTable
/** /**
* Add HashTable items from source. * Add HashTable items from source.
* *
* @param IComparable[] $pSource Source array to create HashTable from * @param T[] $pSource Source array to create HashTable from
*/ */
public function addFromSource(?array $pSource = null): void public function addFromSource(?array $pSource = null): void
{ {
@ -51,7 +54,7 @@ class HashTable
/** /**
* Add HashTable item. * Add HashTable item.
* *
* @param IComparable $pSource Item to add * @param T $pSource Item to add
*/ */
public function add(IComparable $pSource): void public function add(IComparable $pSource): void
{ {
@ -65,7 +68,7 @@ class HashTable
/** /**
* Remove HashTable item. * Remove HashTable item.
* *
* @param IComparable $pSource Item to remove * @param T $pSource Item to remove
*/ */
public function remove(IComparable $pSource): void public function remove(IComparable $pSource): void
{ {
@ -123,7 +126,7 @@ class HashTable
* *
* @param int $pIndex * @param int $pIndex
* *
* @return IComparable * @return T
*/ */
public function getByIndex($pIndex) public function getByIndex($pIndex)
{ {
@ -139,7 +142,7 @@ class HashTable
* *
* @param string $pHashCode * @param string $pHashCode
* *
* @return IComparable * @return T
*/ */
public function getByHashCode($pHashCode) public function getByHashCode($pHashCode)
{ {
@ -153,7 +156,7 @@ class HashTable
/** /**
* HashTable to array. * HashTable to array.
* *
* @return IComparable[] * @return T[]
*/ */
public function toArray() public function toArray()
{ {

View File

@ -657,7 +657,7 @@ class Gnumeric extends BaseReader
$column = $columnAttributes['No']; $column = $columnAttributes['No'];
$columnWidth = ((float) $columnAttributes['Unit']) / 5.4; $columnWidth = ((float) $columnAttributes['Unit']) / 5.4;
$hidden = (isset($columnAttributes['Hidden'])) && ((string) $columnAttributes['Hidden'] == '1'); $hidden = (isset($columnAttributes['Hidden'])) && ((string) $columnAttributes['Hidden'] == '1');
$columnCount = $columnAttributes['Count'] ?? 1; $columnCount = (int) ($columnAttributes['Count'] ?? 1);
while ($c < $column) { while ($c < $column) {
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth); $this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
++$c; ++$c;
@ -696,7 +696,7 @@ class Gnumeric extends BaseReader
$row = $rowAttributes['No']; $row = $rowAttributes['No'];
$rowHeight = (float) $rowAttributes['Unit']; $rowHeight = (float) $rowAttributes['Unit'];
$hidden = (isset($rowAttributes['Hidden'])) && ((string) $rowAttributes['Hidden'] == '1'); $hidden = (isset($rowAttributes['Hidden'])) && ((string) $rowAttributes['Hidden'] == '1');
$rowCount = $rowAttributes['Count'] ?? 1; $rowCount = (int) ($rowAttributes['Count'] ?? 1);
while ($r < $row) { while ($r < $row) {
++$r; ++$r;
$this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); $this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);

View File

@ -910,8 +910,6 @@ class Html extends BaseReader
/** /**
* Check if has #, so we can get clean hex. * Check if has #, so we can get clean hex.
* *
* @param $value
*
* @return null|string * @return null|string
*/ */
public function getStyleColor($value) public function getStyleColor($value)

View File

@ -380,9 +380,8 @@ class Ods extends BaseReader
} }
$columnID = 'A'; $columnID = 'A';
foreach ($childNode->childNodes as $key => $cellData) { /** @var DOMElement $cellData */
// @var \DOMElement $cellData foreach ($childNode->childNodes as $cellData) {
if ($this->getReadFilter() !== null) { if ($this->getReadFilter() !== null) {
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
++$columnID; ++$columnID;
@ -672,8 +671,9 @@ class Ods extends BaseReader
$this->lookForSelectedCells($settings, $spreadsheet, $configNs); $this->lookForSelectedCells($settings, $spreadsheet, $configNs);
} }
private function lookForActiveSheet(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void private function lookForActiveSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void
{ {
/** @var DOMElement $t */
foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) { foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) {
if ($t->getAttributeNs($configNs, 'name') === 'ActiveTable') { if ($t->getAttributeNs($configNs, 'name') === 'ActiveTable') {
try { try {
@ -687,8 +687,9 @@ class Ods extends BaseReader
} }
} }
private function lookForSelectedCells(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void private function lookForSelectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void
{ {
/** @var DOMElement $t */
foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) { foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) {
if ($t->getAttributeNs($configNs, 'name') === 'Tables') { if ($t->getAttributeNs($configNs, 'name') === 'Tables') {
foreach ($t->getElementsByTagNameNS($configNs, 'config-item-map-entry') as $ws) { foreach ($t->getElementsByTagNameNS($configNs, 'config-item-map-entry') as $ws) {

View File

@ -169,7 +169,7 @@ class Slk extends BaseReader
foreach ($rowData as $rowDatum) { foreach ($rowData as $rowDatum) {
switch ($rowDatum[0]) { switch ($rowDatum[0]) {
case 'X': case 'X':
$columnIndex = substr($rowDatum, 1) - 1; $columnIndex = (int) substr($rowDatum, 1) - 1;
break; break;
case 'Y': case 'Y':
@ -251,7 +251,7 @@ class Slk extends BaseReader
} }
// Bracketed R references are relative to the current row // Bracketed R references are relative to the current row
if ($rowReference[0] == '[') { if ($rowReference[0] == '[') {
$rowReference = $row + trim($rowReference, '[]'); $rowReference = (int) $row + (int) trim($rowReference, '[]');
} }
$columnReference = $cellReference[4][0]; $columnReference = $cellReference[4][0];
// Empty C reference is the current column // Empty C reference is the current column
@ -260,7 +260,7 @@ class Slk extends BaseReader
} }
// Bracketed C references are relative to the current column // Bracketed C references are relative to the current column
if ($columnReference[0] == '[') { if ($columnReference[0] == '[') {
$columnReference = $column + trim($columnReference, '[]'); $columnReference = (int) $column + (int) trim($columnReference, '[]');
} }
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference; $A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference;

View File

@ -224,7 +224,7 @@ class Xls extends BaseReader
/** /**
* Shared fonts. * Shared fonts.
* *
* @var array * @var Font[]
*/ */
private $objFonts; private $objFonts;
@ -1293,7 +1293,7 @@ class Xls extends BaseReader
} }
} }
// Named Value // Named Value
// TODO Provide support for named values // TODO Provide support for named values
} }
} }
$this->data = null; $this->data = null;
@ -3105,7 +3105,7 @@ class Xls extends BaseReader
$len = min($charsLeft, $limitpos - $pos); $len = min($charsLeft, $limitpos - $pos);
for ($j = 0; $j < $len; ++$j) { for ($j = 0; $j < $len; ++$j) {
$retstr .= $recordData[$pos + $j] $retstr .= $recordData[$pos + $j]
. chr(0); . chr(0);
} }
$charsLeft -= $len; $charsLeft -= $len;
$isCompressed = false; $isCompressed = false;
@ -7191,6 +7191,7 @@ class Xls extends BaseReader
{ {
[$baseCol, $baseRow] = Coordinate::coordinateFromString($baseCell); [$baseCol, $baseRow] = Coordinate::coordinateFromString($baseCell);
$baseCol = Coordinate::columnIndexFromString($baseCol) - 1; $baseCol = Coordinate::columnIndexFromString($baseCol) - 1;
$baseRow = (int) $baseRow;
// offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767))
$rowIndex = self::getUInt2d($cellAddressStructure, 0); $rowIndex = self::getUInt2d($cellAddressStructure, 0);
@ -7368,8 +7369,8 @@ class Xls extends BaseReader
*/ */
private function readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') private function readBIFF8CellRangeAddressB($subData, $baseCell = 'A1')
{ {
[$baseCol, $baseRow] = Coordinate::coordinateFromString($baseCell); [$baseCol, $baseRow] = Coordinate::indexesFromString($baseCell);
$baseCol = Coordinate::columnIndexFromString($baseCol) - 1; $baseCol = $baseCol - 1;
// TODO: if cell range is just a single cell, should this funciton // TODO: if cell range is just a single cell, should this funciton
// not just return e.g. 'A1' and not 'A1:A1' ? // not just return e.g. 'A1' and not 'A1:A1' ?

View File

@ -5,12 +5,25 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls;
class MD5 class MD5
{ {
// Context // Context
/**
* @var int
*/
private $a; private $a;
/**
* @var int
*/
private $b; private $b;
/**
* @var int
*/
private $c; private $c;
/**
* @var int
*/
private $d; private $d;
/** /**
@ -56,7 +69,7 @@ class MD5
* *
* @param string $data Data to add * @param string $data Data to add
*/ */
public function add($data): void public function add(string $data): void
{ {
$words = array_values(unpack('V16', $data)); $words = array_values(unpack('V16', $data));
@ -148,34 +161,34 @@ class MD5
$this->d = ($this->d + $D) & 0xffffffff; $this->d = ($this->d + $D) & 0xffffffff;
} }
private static function f($X, $Y, $Z) private static function f(int $X, int $Y, int $Z)
{ {
return ($X & $Y) | ((~$X) & $Z); // X AND Y OR NOT X AND Z return ($X & $Y) | ((~$X) & $Z); // X AND Y OR NOT X AND Z
} }
private static function g($X, $Y, $Z) private static function g(int $X, int $Y, int $Z)
{ {
return ($X & $Z) | ($Y & (~$Z)); // X AND Z OR Y AND NOT Z return ($X & $Z) | ($Y & (~$Z)); // X AND Z OR Y AND NOT Z
} }
private static function h($X, $Y, $Z) private static function h(int $X, int $Y, int $Z)
{ {
return $X ^ $Y ^ $Z; // X XOR Y XOR Z return $X ^ $Y ^ $Z; // X XOR Y XOR Z
} }
private static function i($X, $Y, $Z) private static function i(int $X, int $Y, int $Z)
{ {
return $Y ^ ($X | (~$Z)); // Y XOR (X OR NOT Z) return $Y ^ ($X | (~$Z)); // Y XOR (X OR NOT Z)
} }
private static function step($func, &$A, $B, $C, $D, $M, $s, $t): void private static function step($func, int &$A, int $B, int $C, int $D, int $M, int $s, int $t): void
{ {
$A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff;
$A = self::rotate($A, $s); $A = self::rotate($A, $s);
$A = ($B + $A) & 0xffffffff; $A = ($B + $A) & 0xffffffff;
} }
private static function rotate($decimal, $bits) private static function rotate(int $decimal, int $bits)
{ {
$binary = str_pad(decbin($decimal), 32, '0', STR_PAD_LEFT); $binary = str_pad(decbin($decimal), 32, '0', STR_PAD_LEFT);

View File

@ -272,11 +272,11 @@ class Xlsx extends BaseReader
if (!isset($sharedFormulas[(string) $c->f['si']])) { if (!isset($sharedFormulas[(string) $c->f['si']])) {
$sharedFormulas[$instance] = ['master' => $r, 'formula' => $value]; $sharedFormulas[$instance] = ['master' => $r, 'formula' => $value];
} else { } else {
$master = Coordinate::coordinateFromString($sharedFormulas[$instance]['master']); $master = Coordinate::indexesFromString($sharedFormulas[$instance]['master']);
$current = Coordinate::coordinateFromString($r); $current = Coordinate::indexesFromString($r);
$difference = [0, 0]; $difference = [0, 0];
$difference[0] = Coordinate::columnIndexFromString($current[0]) - Coordinate::columnIndexFromString($master[0]); $difference[0] = $current[0] - $master[0];
$difference[1] = $current[1] - $master[1]; $difference[1] = $current[1] - $master[1];
$value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]);
@ -1141,7 +1141,7 @@ class Xlsx extends BaseReader
)], )],
false false
); );
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1)); $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((int) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1));
$objDrawing->setOffsetX(Drawing::EMUToPixels($oneCellAnchor->from->colOff)); $objDrawing->setOffsetX(Drawing::EMUToPixels($oneCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); $objDrawing->setOffsetY(Drawing::EMUToPixels($oneCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false); $objDrawing->setResizeProportional(false);
@ -1167,7 +1167,7 @@ class Xlsx extends BaseReader
$objDrawing->setWorksheet($docSheet); $objDrawing->setWorksheet($docSheet);
} elseif ($this->includeCharts && $oneCellAnchor->graphicFrame) { } elseif ($this->includeCharts && $oneCellAnchor->graphicFrame) {
// Exported XLSX from Google Sheets positions charts with a oneCellAnchor // Exported XLSX from Google Sheets positions charts with a oneCellAnchor
$coordinates = Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1); $coordinates = Coordinate::stringFromColumnIndex(((int) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1);
$offsetX = Drawing::EMUToPixels($oneCellAnchor->from->colOff); $offsetX = Drawing::EMUToPixels($oneCellAnchor->from->colOff);
$offsetY = Drawing::EMUToPixels($oneCellAnchor->from->rowOff); $offsetY = Drawing::EMUToPixels($oneCellAnchor->from->rowOff);
$width = Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx')); $width = Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx'));
@ -1207,7 +1207,7 @@ class Xlsx extends BaseReader
)], )],
false false
); );
$objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1)); $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1));
$objDrawing->setOffsetX(Drawing::EMUToPixels($twoCellAnchor->from->colOff)); $objDrawing->setOffsetX(Drawing::EMUToPixels($twoCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); $objDrawing->setOffsetY(Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false); $objDrawing->setResizeProportional(false);
@ -1233,10 +1233,10 @@ class Xlsx extends BaseReader
$objDrawing->setWorksheet($docSheet); $objDrawing->setWorksheet($docSheet);
} elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) { } elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) {
$fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1); $fromCoordinate = Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1);
$fromOffsetX = Drawing::EMUToPixels($twoCellAnchor->from->colOff); $fromOffsetX = Drawing::EMUToPixels($twoCellAnchor->from->colOff);
$fromOffsetY = Drawing::EMUToPixels($twoCellAnchor->from->rowOff); $fromOffsetY = Drawing::EMUToPixels($twoCellAnchor->from->rowOff);
$toCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1); $toCoordinate = Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1);
$toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff); $toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff);
$toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff); $toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
$graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic; $graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;
@ -1728,7 +1728,7 @@ class Xlsx extends BaseReader
* *
* @return RichText * @return RichText
*/ */
private function parseRichText($is) private function parseRichText(?SimpleXMLElement $is)
{ {
$value = new RichText(); $value = new RichText();
@ -1736,6 +1736,8 @@ class Xlsx extends BaseReader
$value->createText(StringHelper::controlCharacterOOXML2PHP((string) $is->t)); $value->createText(StringHelper::controlCharacterOOXML2PHP((string) $is->t));
} else { } else {
if (is_object($is->r)) { if (is_object($is->r)) {
/** @var SimpleXMLElement $run */
foreach ($is->r as $run) { foreach ($is->r as $run) {
if (!isset($run->rPr)) { if (!isset($run->rPr)) {
$value->createText(StringHelper::controlCharacterOOXML2PHP((string) $run->t)); $value->createText(StringHelper::controlCharacterOOXML2PHP((string) $run->t));

View File

@ -90,7 +90,7 @@ class Chart
break; break;
case 'valAx': case 'valAx':
if (isset($chartDetail->title)) { if (isset($chartDetail->title, $chartDetail->axPos)) {
$axisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta); $axisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
$axPos = self::getAttribute($chartDetail->axPos, 'val', 'string'); $axPos = self::getAttribute($chartDetail->axPos, 'val', 'string');
@ -355,7 +355,7 @@ class Chart
} elseif (isset($seriesDetail->numRef)) { } elseif (isset($seriesDetail->numRef)) {
$seriesSource = (string) $seriesDetail->numRef->f; $seriesSource = (string) $seriesDetail->numRef->f;
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, null, null, $marker); $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, null, null, $marker);
if (isset($seriesDetail->strRef->strCache)) { if (isset($seriesDetail->numRef->numCache)) {
$seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));
$seriesValues $seriesValues
->setFormatCode($seriesData['formatCode']) ->setFormatCode($seriesData['formatCode'])
@ -539,7 +539,7 @@ class Chart
{ {
$plotAttributes = []; $plotAttributes = [];
if (isset($chartDetail->dLbls)) { if (isset($chartDetail->dLbls)) {
if (isset($chartDetail->dLbls->howLegendKey)) { if (isset($chartDetail->dLbls->showLegendKey)) {
$plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); $plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string');
} }
if (isset($chartDetail->dLbls->showVal)) { if (isset($chartDetail->dLbls->showVal)) {

View File

@ -422,6 +422,7 @@ class Xml extends BaseReader
$worksheetID = 0; $worksheetID = 0;
$xml_ss = $xml->children($namespaces['ss']); $xml_ss = $xml->children($namespaces['ss']);
/** @var null|SimpleXMLElement $worksheetx */
foreach ($xml_ss->Worksheet as $worksheetx) { foreach ($xml_ss->Worksheet as $worksheetx) {
$worksheet = $worksheetx ?? new SimpleXMLElement('<xml></xml>'); $worksheet = $worksheetx ?? new SimpleXMLElement('<xml></xml>');
$worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']); $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
@ -748,9 +749,6 @@ class Xml extends BaseReader
private static $borderPositions = ['top', 'left', 'bottom', 'right']; private static $borderPositions = ['top', 'left', 'bottom', 'right'];
/**
* @param $styleID
*/
private function parseStyleBorders($styleID, SimpleXMLElement $styleData, array $namespaces): void private function parseStyleBorders($styleID, SimpleXMLElement $styleData, array $namespaces): void
{ {
$diagonalDirection = ''; $diagonalDirection = '';
@ -821,9 +819,6 @@ class Xml extends BaseReader
} }
} }
/**
* @param $styleID
*/
private function parseStyleFont(string $styleID, SimpleXMLElement $styleAttributes): void private function parseStyleFont(string $styleID, SimpleXMLElement $styleAttributes): void
{ {
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
@ -861,9 +856,6 @@ class Xml extends BaseReader
} }
} }
/**
* @param $styleID
*/
private function parseStyleInterior($styleID, SimpleXMLElement $styleAttributes): void private function parseStyleInterior($styleID, SimpleXMLElement $styleAttributes): void
{ {
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValuex) { foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValuex) {
@ -887,9 +879,6 @@ class Xml extends BaseReader
} }
} }
/**
* @param $styleID
*/
private function parseStyleNumberFormat($styleID, SimpleXMLElement $styleAttributes): void private function parseStyleNumberFormat($styleID, SimpleXMLElement $styleAttributes): void
{ {
$fromFormats = ['\-', '\ ']; $fromFormats = ['\-', '\ '];

View File

@ -375,17 +375,16 @@ class ReferenceHelper
$allCoordinates = $pSheet->getCoordinates(); $allCoordinates = $pSheet->getCoordinates();
// Get coordinate of $pBefore // Get coordinate of $pBefore
[$beforeColumn, $beforeRow] = Coordinate::coordinateFromString($pBefore); [$beforeColumn, $beforeRow] = Coordinate::indexesFromString($pBefore);
$beforeColumnIndex = Coordinate::columnIndexFromString($beforeColumn);
// Clear cells if we are removing columns or rows // Clear cells if we are removing columns or rows
$highestColumn = $pSheet->getHighestColumn(); $highestColumn = $pSheet->getHighestColumn();
$highestRow = $pSheet->getHighestRow(); $highestRow = $pSheet->getHighestRow();
// 1. Clear column strips if we are removing columns // 1. Clear column strips if we are removing columns
if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) { if ($pNumCols < 0 && $beforeColumn - 2 + $pNumCols > 0) {
for ($i = 1; $i <= $highestRow - 1; ++$i) { for ($i = 1; $i <= $highestRow - 1; ++$i) {
for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) { for ($j = $beforeColumn - 1 + $pNumCols; $j <= $beforeColumn - 2; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($j + 1) . $i; $coordinate = Coordinate::stringFromColumnIndex($j + 1) . $i;
$pSheet->removeConditionalStyles($coordinate); $pSheet->removeConditionalStyles($coordinate);
if ($pSheet->cellExists($coordinate)) { if ($pSheet->cellExists($coordinate)) {
@ -398,7 +397,7 @@ class ReferenceHelper
// 2. Clear row strips if we are removing rows // 2. Clear row strips if we are removing rows
if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) { if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) {
for ($i = $beforeColumnIndex - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) { for ($i = $beforeColumn - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) {
for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) { for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($i + 1) . $j; $coordinate = Coordinate::stringFromColumnIndex($i + 1) . $j;
$pSheet->removeConditionalStyles($coordinate); $pSheet->removeConditionalStyles($coordinate);
@ -427,7 +426,7 @@ class ReferenceHelper
$newCoordinate = Coordinate::stringFromColumnIndex($cellIndex + $pNumCols) . ($cell->getRow() + $pNumRows); $newCoordinate = Coordinate::stringFromColumnIndex($cellIndex + $pNumCols) . ($cell->getRow() + $pNumRows);
// Should the cell be updated? Move value and cellXf index from one cell to another. // Should the cell be updated? Move value and cellXf index from one cell to another.
if (($cellIndex >= $beforeColumnIndex) && ($cell->getRow() >= $beforeRow)) { if (($cellIndex >= $beforeColumn) && ($cell->getRow() >= $beforeRow)) {
// Update cell styles // Update cell styles
$pSheet->getCell($newCoordinate)->setXfIndex($cell->getXfIndex()); $pSheet->getCell($newCoordinate)->setXfIndex($cell->getXfIndex());
@ -457,15 +456,15 @@ class ReferenceHelper
$highestColumn = $pSheet->getHighestColumn(); $highestColumn = $pSheet->getHighestColumn();
$highestRow = $pSheet->getHighestRow(); $highestRow = $pSheet->getHighestRow();
if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { if ($pNumCols > 0 && $beforeColumn - 2 > 0) {
for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) {
// Style // Style
$coordinate = Coordinate::stringFromColumnIndex($beforeColumnIndex - 1) . $i; $coordinate = Coordinate::stringFromColumnIndex($beforeColumn - 1) . $i;
if ($pSheet->cellExists($coordinate)) { if ($pSheet->cellExists($coordinate)) {
$xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); $xfIndex = $pSheet->getCell($coordinate)->getXfIndex();
$conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ?
$pSheet->getConditionalStyles($coordinate) : false; $pSheet->getConditionalStyles($coordinate) : false;
for ($j = $beforeColumnIndex; $j <= $beforeColumnIndex - 1 + $pNumCols; ++$j) { for ($j = $beforeColumn; $j <= $beforeColumn - 1 + $pNumCols; ++$j) {
$pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex); $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex);
if ($conditionalStyles) { if ($conditionalStyles) {
$cloned = []; $cloned = [];
@ -480,7 +479,7 @@ class ReferenceHelper
} }
if ($pNumRows > 0 && $beforeRow - 1 > 0) { if ($pNumRows > 0 && $beforeRow - 1 > 0) {
for ($i = $beforeColumnIndex; $i <= Coordinate::columnIndexFromString($highestColumn); ++$i) { for ($i = $beforeColumn; $i <= Coordinate::columnIndexFromString($highestColumn); ++$i) {
// Style // Style
$coordinate = Coordinate::stringFromColumnIndex($i) . ($beforeRow - 1); $coordinate = Coordinate::stringFromColumnIndex($i) . ($beforeRow - 1);
if ($pSheet->cellExists($coordinate)) { if ($pSheet->cellExists($coordinate)) {
@ -502,28 +501,28 @@ class ReferenceHelper
} }
// Update worksheet: column dimensions // Update worksheet: column dimensions
$this->adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustColumnDimensions($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: row dimensions // Update worksheet: row dimensions
$this->adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustRowDimensions($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: page breaks // Update worksheet: page breaks
$this->adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustPageBreaks($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: comments // Update worksheet: comments
$this->adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustComments($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: hyperlinks // Update worksheet: hyperlinks
$this->adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustHyperlinks($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: data validations // Update worksheet: data validations
$this->adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustDataValidations($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: merge cells // Update worksheet: merge cells
$this->adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustMergeCells($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: protected cells // Update worksheet: protected cells
$this->adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); $this->adjustProtectedCells($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: autofilter // Update worksheet: autofilter
$autoFilter = $pSheet->getAutoFilter(); $autoFilter = $pSheet->getAutoFilter();
@ -654,7 +653,7 @@ class ReferenceHelper
$toString .= $modified3 . ':' . $modified4; $toString .= $modified3 . ':' . $modified4;
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = 100000; $column = 100000;
$row = 10000000 + trim($match[3], '$'); $row = 10000000 + (int) trim($match[3], '$');
$cellIndex = $column . $row; $cellIndex = $column . $row;
$newCellTokens[$cellIndex] = preg_quote($toString, '/'); $newCellTokens[$cellIndex] = preg_quote($toString, '/');
@ -705,7 +704,7 @@ class ReferenceHelper
[$column, $row] = Coordinate::coordinateFromString($match[3]); [$column, $row] = Coordinate::coordinateFromString($match[3]);
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000; $column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000;
$row = trim($row, '$') + 10000000; $row = (int) trim($row, '$') + 10000000;
$cellIndex = $column . $row; $cellIndex = $column . $row;
$newCellTokens[$cellIndex] = preg_quote($toString, '/'); $newCellTokens[$cellIndex] = preg_quote($toString, '/');
@ -731,7 +730,7 @@ class ReferenceHelper
[$column, $row] = Coordinate::coordinateFromString($match[3]); [$column, $row] = Coordinate::coordinateFromString($match[3]);
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000; $column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000;
$row = trim($row, '$') + 10000000; $row = (int) trim($row, '$') + 10000000;
$cellIndex = $row . $column; $cellIndex = $row . $column;
$newCellTokens[$cellIndex] = preg_quote($toString, '/'); $newCellTokens[$cellIndex] = preg_quote($toString, '/');
@ -1021,7 +1020,7 @@ class ReferenceHelper
// Create new row reference // Create new row reference
if ($updateRow) { if ($updateRow) {
$newRow = $newRow + $pNumRows; $newRow = (int) $newRow + $pNumRows;
} }
// Return new reference // Return new reference

View File

@ -14,7 +14,7 @@ interface ITextElement
/** /**
* Set text. * Set text.
* *
* @param $text string Text * @param string $text Text
* *
* @return ITextElement * @return ITextElement
*/ */

View File

@ -35,7 +35,7 @@ class TextElement implements ITextElement
/** /**
* Set text. * Set text.
* *
* @param $text string Text * @param string $text Text
* *
* @return $this * @return $this
*/ */

View File

@ -304,8 +304,8 @@ class Date
} }
// Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0)
$century = substr($year, 0, 2); $century = (int) substr($year, 0, 2);
$decade = substr($year, 2, 2); $decade = (int) substr($year, 2, 2);
$excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear; $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear;
$excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400;

View File

@ -273,14 +273,8 @@ class Font
/** /**
* Get GD text width in pixels for a string of text in a certain font at a certain rotation angle. * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle.
*
* @param string $text
* @param \PhpOffice\PhpSpreadsheet\Style\Font
* @param int $rotation
*
* @return int
*/ */
public static function getTextWidthPixelsExact($text, \PhpOffice\PhpSpreadsheet\Style\Font $font, $rotation = 0) public static function getTextWidthPixelsExact(string $text, \PhpOffice\PhpSpreadsheet\Style\Font $font, int $rotation = 0): int
{ {
if (!function_exists('imagettfbbox')) { if (!function_exists('imagettfbbox')) {
throw new PhpSpreadsheetException('GD library needs to be enabled'); throw new PhpSpreadsheetException('GD library needs to be enabled');
@ -350,7 +344,7 @@ class Font
} else { } else {
// rotated text // rotated text
$columnWidth = $columnWidth * cos(deg2rad($rotation)) $columnWidth = $columnWidth * cos(deg2rad($rotation))
+ $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
} }
} }
@ -415,35 +409,35 @@ class Font
switch ($name) { switch ($name) {
case 'Arial': case 'Arial':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)
: ($italic ? self::ARIAL_ITALIC : self::ARIAL) : ($italic ? self::ARIAL_ITALIC : self::ARIAL)
); );
break; break;
case 'Calibri': case 'Calibri':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)
: ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)
); );
break; break;
case 'Courier New': case 'Courier New':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)
: ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)
); );
break; break;
case 'Comic Sans MS': case 'Comic Sans MS':
$fontFile = ( $fontFile = (
$bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS
); );
break; break;
case 'Georgia': case 'Georgia':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)
: ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)
); );
break; break;
@ -453,8 +447,8 @@ class Font
break; break;
case 'Liberation Sans': case 'Liberation Sans':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)
: ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)
); );
break; break;
@ -472,8 +466,8 @@ class Font
break; break;
case 'Palatino Linotype': case 'Palatino Linotype':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)
: ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)
); );
break; break;
@ -483,28 +477,28 @@ class Font
break; break;
case 'Tahoma': case 'Tahoma':
$fontFile = ( $fontFile = (
$bold ? self::TAHOMA_BOLD : self::TAHOMA $bold ? self::TAHOMA_BOLD : self::TAHOMA
); );
break; break;
case 'Times New Roman': case 'Times New Roman':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)
: ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)
); );
break; break;
case 'Trebuchet MS': case 'Trebuchet MS':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)
: ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)
); );
break; break;
case 'Verdana': case 'Verdana':
$fontFile = ( $fontFile = (
$bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)
: ($italic ? self::VERDANA_ITALIC : self::VERDANA) : ($italic ? self::VERDANA_ITALIC : self::VERDANA)
); );
break; break;
@ -563,13 +557,13 @@ class Font
// Exact width can be determined // Exact width can be determined
$columnWidth = $pPixels ? $columnWidth = $pPixels ?
self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px']
: self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];
} else { } else {
// We don't have data for this particular font and size, use approximation by // We don't have data for this particular font and size, use approximation by
// extrapolating from Calibri 11 // extrapolating from Calibri 11
$columnWidth = $pPixels ? $columnWidth = $pPixels ?
self::$defaultColumnWidths['Calibri'][11]['px'] self::$defaultColumnWidths['Calibri'][11]['px']
: self::$defaultColumnWidths['Calibri'][11]['width']; : self::$defaultColumnWidths['Calibri'][11]['width'];
$columnWidth = $columnWidth * $font->getSize() / 11; $columnWidth = $columnWidth * $font->getSize() / 11;
// Round pixels to closest integer // Round pixels to closest integer

View File

@ -103,7 +103,7 @@ class CholeskyDecomposition
/** /**
* Solve A*X = B. * Solve A*X = B.
* *
* @param $B Row-equal matrix * @param Matrix $B Row-equal matrix
* *
* @return Matrix L * L' * X = B * @return Matrix L * L' * X = B
*/ */
@ -111,7 +111,7 @@ class CholeskyDecomposition
{ {
if ($B->getRowDimension() == $this->m) { if ($B->getRowDimension() == $this->m) {
if ($this->isspd) { if ($this->isspd) {
$X = $B->getArrayCopy(); $X = $B->getArray();
$nx = $B->getColumnDimension(); $nx = $B->getColumnDimension();
for ($k = 0; $k < $this->m; ++$k) { for ($k = 0; $k < $this->m; ++$k) {

View File

@ -456,17 +456,6 @@ class Matrix
return $s; return $s;
} }
/**
* uminus.
*
* Unary minus matrix -A
*
* @return Matrix Unary minus matrix
*/
public function uminus()
{
}
/** /**
* plus. * plus.
* *

View File

@ -15,9 +15,9 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
* of simultaneous linear equations. This will fail if isFullRank() * of simultaneous linear equations. This will fail if isFullRank()
* returns false. * returns false.
* *
* @author Paul Meagher * @author Paul Meagher
* *
* @version 1.1 * @version 1.1
*/ */
class QRDecomposition class QRDecomposition
{ {
@ -54,47 +54,43 @@ class QRDecomposition
/** /**
* QR Decomposition computed by Householder reflections. * QR Decomposition computed by Householder reflections.
* *
* @param matrix $A Rectangular matrix * @param Matrix $A Rectangular matrix
*/ */
public function __construct($A) public function __construct(Matrix $A)
{ {
if ($A instanceof Matrix) { // Initialize.
// Initialize. $this->QR = $A->getArray();
$this->QR = $A->getArray(); $this->m = $A->getRowDimension();
$this->m = $A->getRowDimension(); $this->n = $A->getColumnDimension();
$this->n = $A->getColumnDimension(); // Main loop.
// Main loop. for ($k = 0; $k < $this->n; ++$k) {
for ($k = 0; $k < $this->n; ++$k) { // Compute 2-norm of k-th column without under/overflow.
// Compute 2-norm of k-th column without under/overflow. $nrm = 0.0;
$nrm = 0.0; for ($i = $k; $i < $this->m; ++$i) {
for ($i = $k; $i < $this->m; ++$i) { $nrm = hypo($nrm, $this->QR[$i][$k]);
$nrm = hypo($nrm, $this->QR[$i][$k]);
}
if ($nrm != 0.0) {
// Form k-th Householder vector.
if ($this->QR[$k][$k] < 0) {
$nrm = -$nrm;
}
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$k] /= $nrm;
}
$this->QR[$k][$k] += 1.0;
// Apply transformation to remaining columns.
for ($j = $k + 1; $j < $this->n; ++$j) {
$s = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$s += $this->QR[$i][$k] * $this->QR[$i][$j];
}
$s = -$s / $this->QR[$k][$k];
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$j] += $s * $this->QR[$i][$k];
}
}
}
$this->Rdiag[$k] = -$nrm;
} }
} else { if ($nrm != 0.0) {
throw new CalculationException(Matrix::ARGUMENT_TYPE_EXCEPTION); // Form k-th Householder vector.
if ($this->QR[$k][$k] < 0) {
$nrm = -$nrm;
}
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$k] /= $nrm;
}
$this->QR[$k][$k] += 1.0;
// Apply transformation to remaining columns.
for ($j = $k + 1; $j < $this->n; ++$j) {
$s = 0.0;
for ($i = $k; $i < $this->m; ++$i) {
$s += $this->QR[$i][$k] * $this->QR[$i][$j];
}
$s = -$s / $this->QR[$k][$k];
for ($i = $k; $i < $this->m; ++$i) {
$this->QR[$i][$j] += $s * $this->QR[$i][$k];
}
}
}
$this->Rdiag[$k] = -$nrm;
} }
} }
@ -211,7 +207,7 @@ class QRDecomposition
if ($this->isFullRank()) { if ($this->isFullRank()) {
// Copy right hand side // Copy right hand side
$nx = $B->getColumnDimension(); $nx = $B->getColumnDimension();
$X = $B->getArrayCopy(); $X = $B->getArray();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
for ($k = 0; $k < $this->n; ++$k) { for ($k = 0; $k < $this->n; ++$k) {
for ($j = 0; $j < $nx; ++$j) { for ($j = 0; $j < $nx; ++$j) {

View File

@ -65,7 +65,7 @@ class SingularValueDecomposition
public function __construct($Arg) public function __construct($Arg)
{ {
// Initialize. // Initialize.
$A = $Arg->getArrayCopy(); $A = $Arg->getArray();
$this->m = $Arg->getRowDimension(); $this->m = $Arg->getRowDimension();
$this->n = $Arg->getColumnDimension(); $this->n = $Arg->getColumnDimension();
$nu = min($this->m, $this->n); $nu = min($this->m, $this->n);

View File

@ -42,7 +42,7 @@ class ChainedBlockStream
* ole-chainedblockstream://oleInstanceId=1 * ole-chainedblockstream://oleInstanceId=1
* @param string $mode only "r" is supported * @param string $mode only "r" is supported
* @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
* @param string &$openedPath absolute path of the opened stream (out parameter) * @param string $openedPath absolute path of the opened stream (out parameter)
* *
* @return bool true on success * @return bool true on success
*/ */

View File

@ -200,7 +200,7 @@ class PPS
* Updates index and pointers to previous, next and children PPS's for this * Updates index and pointers to previous, next and children PPS's for this
* PPS. I don't think it'll work with Dir PPS's. * PPS. I don't think it'll work with Dir PPS's.
* *
* @param array &$raList Reference to the array of PPS's for the whole OLE * @param array $raList Reference to the array of PPS's for the whole OLE
* container * container
* @param mixed $to_save * @param mixed $to_save
* @param mixed $depth * @param mixed $depth

View File

@ -237,7 +237,7 @@ class Root extends PPS
* Saving big data (PPS's with data bigger than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL). * Saving big data (PPS's with data bigger than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
* *
* @param int $iStBlk * @param int $iStBlk
* @param array &$raList Reference to array of PPS's * @param array $raList Reference to array of PPS's
*/ */
private function saveBigData($iStBlk, &$raList): void private function saveBigData($iStBlk, &$raList): void
{ {
@ -267,7 +267,7 @@ class Root extends PPS
/** /**
* get small data (PPS's with data smaller than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL). * get small data (PPS's with data smaller than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
* *
* @param array &$raList Reference to array of PPS's * @param array $raList Reference to array of PPS's
* *
* @return string * @return string
*/ */

View File

@ -92,10 +92,8 @@ class OLERead
/** /**
* Read the file. * Read the file.
*
* @param $pFilename string Filename
*/ */
public function read($pFilename): void public function read(string $pFilename): void
{ {
File::assertFile($pFilename); File::assertFile($pFilename);

View File

@ -556,7 +556,7 @@ class StringHelper
* Identify whether a string contains a fractional numeric value, * Identify whether a string contains a fractional numeric value,
* and convert it to a numeric if it is. * and convert it to a numeric if it is.
* *
* @param string &$operand string value to test * @param string $operand string value to test
* *
* @return bool * @return bool
*/ */

View File

@ -44,7 +44,7 @@ class Trend
/** /**
* Cached results for each method when trying to identify which provides the best fit. * Cached results for each method when trying to identify which provides the best fit.
* *
* @var bestFit[] * @var BestFit[]
*/ */
private static $trendCache = []; private static $trendCache = [];

View File

@ -209,8 +209,7 @@ class Xls
*/ */
public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height) public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
{ {
[$column, $row] = Coordinate::coordinateFromString($coordinates); [$col_start, $row] = Coordinate::indexesFromString($coordinates);
$col_start = Coordinate::columnIndexFromString($column);
$row_start = $row - 1; $row_start = $row - 1;
$x1 = $offsetX; $x1 = $offsetX;

View File

@ -70,17 +70,19 @@ class Border extends Supervisor
*/ */
public function getSharedComponent() public function getSharedComponent()
{ {
/** @var Borders $sharedComponent */
$sharedComponent = $this->parent->getSharedComponent();
switch ($this->parentPropertyName) { switch ($this->parentPropertyName) {
case 'bottom': case 'bottom':
return $this->parent->getSharedComponent()->getBottom(); return $sharedComponent->getBottom();
case 'diagonal': case 'diagonal':
return $this->parent->getSharedComponent()->getDiagonal(); return $sharedComponent->getDiagonal();
case 'left': case 'left':
return $this->parent->getSharedComponent()->getLeft(); return $sharedComponent->getLeft();
case 'right': case 'right':
return $this->parent->getSharedComponent()->getRight(); return $sharedComponent->getRight();
case 'top': case 'top':
return $this->parent->getSharedComponent()->getTop(); return $sharedComponent->getTop();
} }
throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.'); throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.');

View File

@ -71,14 +71,16 @@ class Color extends Supervisor
*/ */
public function getSharedComponent() public function getSharedComponent()
{ {
/** @var Border|Fill $sharedComponent */
$sharedComponent = $this->parent->getSharedComponent();
if ($this->parentPropertyName === 'endColor') { if ($this->parentPropertyName === 'endColor') {
return $this->parent->getSharedComponent()->getEndColor(); return $sharedComponent->getEndColor();
} }
if ($this->parentPropertyName === 'startColor') { if ($this->parentPropertyName === 'startColor') {
return $this->parent->getSharedComponent()->getStartColor(); return $sharedComponent->getStartColor();
} }
return $this->parent->getSharedComponent()->getColor(); return $sharedComponent->getColor();
} }
/** /**
@ -200,7 +202,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a * @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value * decimal value
* *
* @return string The extracted colour component * @return int|string The extracted colour component
*/ */
private static function getColourComponent($RGB, $offset, $hex = true) private static function getColourComponent($RGB, $offset, $hex = true)
{ {
@ -216,7 +218,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a * @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value * decimal value
* *
* @return string The red colour component * @return int|string The red colour component
*/ */
public static function getRed($RGB, $hex = true) public static function getRed($RGB, $hex = true)
{ {
@ -230,7 +232,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a * @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value * decimal value
* *
* @return string The green colour component * @return int|string The green colour component
*/ */
public static function getGreen($RGB, $hex = true) public static function getGreen($RGB, $hex = true)
{ {
@ -244,7 +246,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a * @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value * decimal value
* *
* @return string The blue colour component * @return int|string The blue colour component
*/ */
public static function getBlue($RGB, $hex = true) public static function getBlue($RGB, $hex = true)
{ {
@ -264,8 +266,11 @@ class Color extends Supervisor
$rgba = (strlen($hex) === 8); $rgba = (strlen($hex) === 8);
$adjustPercentage = max(-1.0, min(1.0, $adjustPercentage)); $adjustPercentage = max(-1.0, min(1.0, $adjustPercentage));
/** @var int $red */
$red = self::getRed($hex, false); $red = self::getRed($hex, false);
/** @var int $green */
$green = self::getGreen($hex, false); $green = self::getGreen($hex, false);
/** @var int $blue */
$blue = self::getBlue($hex, false); $blue = self::getBlue($hex, false);
if ($adjustPercentage > 0) { if ($adjustPercentage > 0) {
$red += (255 - $red) * $adjustPercentage; $red += (255 - $red) * $adjustPercentage;

View File

@ -13,8 +13,6 @@ class ConditionalFormatValueObject
/** /**
* ConditionalFormatValueObject constructor. * ConditionalFormatValueObject constructor.
* *
* @param $type
* @param $value
* @param null|mixed $cellFormula * @param null|mixed $cellFormula
*/ */
public function __construct($type, $value = null, $cellFormula = null) public function __construct($type, $value = null, $cellFormula = null)

View File

@ -24,8 +24,6 @@ class ConditionalFormattingRuleExtension
/** /**
* ConditionalFormattingRuleExtension constructor. * ConditionalFormattingRuleExtension constructor.
*
* @param $id
*/ */
public function __construct($id = null, string $cfRule = self::CONDITION_EXTENSION_DATABAR) public function __construct($id = null, string $cfRule = self::CONDITION_EXTENSION_DATABAR)
{ {

View File

@ -202,18 +202,17 @@ class Style extends Supervisor
// Calculate range outer borders // Calculate range outer borders
$rangeStart = Coordinate::coordinateFromString($rangeA); $rangeStart = Coordinate::coordinateFromString($rangeA);
$rangeEnd = Coordinate::coordinateFromString($rangeB); $rangeEnd = Coordinate::coordinateFromString($rangeB);
$rangeStartIndexes = Coordinate::indexesFromString($rangeA);
$rangeEndIndexes = Coordinate::indexesFromString($rangeB);
// Translate column into index $columnStart = $rangeStart[0];
$rangeStart0 = $rangeStart[0]; $columnEnd = $rangeEnd[0];
$rangeEnd0 = $rangeEnd[0];
$rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]);
$rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]);
// Make sure we can loop upwards on rows and columns // Make sure we can loop upwards on rows and columns
if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { if ($rangeStartIndexes[0] > $rangeEndIndexes[0] && $rangeStartIndexes[1] > $rangeEndIndexes[1]) {
$tmp = $rangeStart; $tmp = $rangeStartIndexes;
$rangeStart = $rangeEnd; $rangeStartIndexes = $rangeEndIndexes;
$rangeEnd = $tmp; $rangeEndIndexes = $tmp;
} }
// ADVANCED MODE: // ADVANCED MODE:
@ -249,19 +248,19 @@ class Style extends Supervisor
unset($pStyles['borders']['inside']); // not needed any more unset($pStyles['borders']['inside']); // not needed any more
} }
// width and height characteristics of selection, 1, 2, or 3 (for 3 or more) // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
$xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3); $xMax = min($rangeEndIndexes[0] - $rangeStartIndexes[0] + 1, 3);
$yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3); $yMax = min($rangeEndIndexes[1] - $rangeStartIndexes[1] + 1, 3);
// loop through up to 3 x 3 = 9 regions // loop through up to 3 x 3 = 9 regions
for ($x = 1; $x <= $xMax; ++$x) { for ($x = 1; $x <= $xMax; ++$x) {
// start column index for region // start column index for region
$colStart = ($x == 3) ? $colStart = ($x == 3) ?
Coordinate::stringFromColumnIndex($rangeEnd[0]) Coordinate::stringFromColumnIndex($rangeEndIndexes[0])
: Coordinate::stringFromColumnIndex($rangeStart[0] + $x - 1); : Coordinate::stringFromColumnIndex($rangeStartIndexes[0] + $x - 1);
// end column index for region // end column index for region
$colEnd = ($x == 1) ? $colEnd = ($x == 1) ?
Coordinate::stringFromColumnIndex($rangeStart[0]) Coordinate::stringFromColumnIndex($rangeStartIndexes[0])
: Coordinate::stringFromColumnIndex($rangeEnd[0] - $xMax + $x); : Coordinate::stringFromColumnIndex($rangeEndIndexes[0] - $xMax + $x);
for ($y = 1; $y <= $yMax; ++$y) { for ($y = 1; $y <= $yMax; ++$y) {
// which edges are touching the region // which edges are touching the region
@ -285,11 +284,11 @@ class Style extends Supervisor
// start row index for region // start row index for region
$rowStart = ($y == 3) ? $rowStart = ($y == 3) ?
$rangeEnd[1] : $rangeStart[1] + $y - 1; $rangeEndIndexes[1] : $rangeStartIndexes[1] + $y - 1;
// end row index for region // end row index for region
$rowEnd = ($y == 1) ? $rowEnd = ($y == 1) ?
$rangeStart[1] : $rangeEnd[1] - $yMax + $y; $rangeStartIndexes[1] : $rangeEndIndexes[1] - $yMax + $y;
// build range for region // build range for region
$range = $colStart . $rowStart . ':' . $colEnd . $rowEnd; $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
@ -349,7 +348,7 @@ class Style extends Supervisor
} }
// First loop through columns, rows, or cells to find out which styles are affected by this operation // First loop through columns, rows, or cells to find out which styles are affected by this operation
$oldXfIndexes = $this->getOldXfIndexes($selectionType, $rangeStart, $rangeEnd, $rangeStart0, $rangeEnd0, $pStyles); $oldXfIndexes = $this->getOldXfIndexes($selectionType, $rangeStartIndexes, $rangeEndIndexes, $columnStart, $columnEnd, $pStyles);
// clone each of the affected styles, apply the style array, and add the new styles to the workbook // clone each of the affected styles, apply the style array, and add the new styles to the workbook
$workbook = $this->getActiveSheet()->getParent(); $workbook = $this->getActiveSheet()->getParent();
@ -372,7 +371,7 @@ class Style extends Supervisor
// Loop through columns, rows, or cells again and update the XF index // Loop through columns, rows, or cells again and update the XF index
switch ($selectionType) { switch ($selectionType) {
case 'COLUMN': case 'COLUMN':
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) {
$columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col); $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
$oldXfIndex = $columnDimension->getXfIndex(); $oldXfIndex = $columnDimension->getXfIndex();
$columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]); $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
@ -380,7 +379,7 @@ class Style extends Supervisor
break; break;
case 'ROW': case 'ROW':
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) {
$rowDimension = $this->getActiveSheet()->getRowDimension($row); $rowDimension = $this->getActiveSheet()->getRowDimension($row);
// row without explicit style should be formatted based on default style // row without explicit style should be formatted based on default style
$oldXfIndex = $rowDimension->getXfIndex() ?? 0; $oldXfIndex = $rowDimension->getXfIndex() ?? 0;
@ -389,8 +388,8 @@ class Style extends Supervisor
break; break;
case 'CELL': case 'CELL':
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) {
for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) {
$cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row); $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
$oldXfIndex = $cell->getXfIndex(); $oldXfIndex = $cell->getXfIndex();
$cell->setXfIndex($newXfIndexes[$oldXfIndex]); $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
@ -427,7 +426,7 @@ class Style extends Supervisor
return $this; return $this;
} }
private function getOldXfIndexes(string $selectionType, array $rangeStart, array $rangeEnd, string $rangeStart0, string $rangeEnd0, array $pStyles): array private function getOldXfIndexes(string $selectionType, array $rangeStart, array $rangeEnd, string $columnStart, string $columnEnd, array $pStyles): array
{ {
$oldXfIndexes = []; $oldXfIndexes = [];
switch ($selectionType) { switch ($selectionType) {
@ -435,7 +434,7 @@ class Style extends Supervisor
for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
$oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true; $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
} }
foreach ($this->getActiveSheet()->getColumnIterator($rangeStart0, $rangeEnd0) as $columnIterator) { foreach ($this->getActiveSheet()->getColumnIterator($columnStart, $columnEnd) as $columnIterator) {
$cellIterator = $columnIterator->getCellIterator(); $cellIterator = $columnIterator->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true); $cellIterator->setIterateOnlyExistingCells(true);
foreach ($cellIterator as $columnCell) { foreach ($cellIterator as $columnCell) {

View File

@ -780,7 +780,7 @@ class AutoFilter
$ruleValues = []; $ruleValues = [];
$dataRowCount = $rangeEnd[1] - $rangeStart[1]; $dataRowCount = $rangeEnd[1] - $rangeStart[1];
$toptenRuleType = null; $toptenRuleType = null;
$ruleValue = null; $ruleValue = 0;
$ruleOperator = null; $ruleOperator = null;
foreach ($rules as $rule) { foreach ($rules as $rule) {
// We should only ever have one Dynamic Filter Rule anyway // We should only ever have one Dynamic Filter Rule anyway

View File

@ -96,14 +96,14 @@ class Worksheet implements IComparable
/** /**
* Collection of drawings. * Collection of drawings.
* *
* @var BaseDrawing[] * @var ArrayObject<BaseDrawing>
*/ */
private $drawingCollection; private $drawingCollection;
/** /**
* Collection of Chart objects. * Collection of Chart objects.
* *
* @var Chart[] * @var ArrayObject<Chart>
*/ */
private $chartCollection = []; private $chartCollection = [];
@ -180,7 +180,7 @@ class Worksheet implements IComparable
/** /**
* Collection of breaks. * Collection of breaks.
* *
* @var array * @var int[]
*/ */
private $breaks = []; private $breaks = [];
@ -534,7 +534,7 @@ class Worksheet implements IComparable
/** /**
* Get collection of drawings. * Get collection of drawings.
* *
* @return BaseDrawing[] * @return ArrayObject<BaseDrawing>
*/ */
public function getDrawingCollection() public function getDrawingCollection()
{ {
@ -544,7 +544,7 @@ class Worksheet implements IComparable
/** /**
* Get collection of charts. * Get collection of charts.
* *
* @return Chart[] * @return ArrayObject<Chart>
*/ */
public function getChartCollection() public function getChartCollection()
{ {
@ -1482,7 +1482,7 @@ class Worksheet implements IComparable
* Set conditional styles. * Set conditional styles.
* *
* @param string $pCoordinate eg: 'A1' * @param string $pCoordinate eg: 'A1'
* @param $pValue Conditional[] * @param Conditional[] $pValue
* *
* @return $this * @return $this
*/ */
@ -1640,7 +1640,7 @@ class Worksheet implements IComparable
/** /**
* Get breaks. * Get breaks.
* *
* @return array[] * @return int[]
*/ */
public function getBreaks() public function getBreaks()
{ {

View File

@ -453,10 +453,8 @@ class Html extends BaseWriter
// Get worksheet dimension // Get worksheet dimension
[$min, $max] = explode(':', $sheet->calculateWorksheetDataDimension()); [$min, $max] = explode(':', $sheet->calculateWorksheetDataDimension());
[$minCol, $minRow] = Coordinate::coordinateFromString($min); [$minCol, $minRow] = Coordinate::indexesFromString($min);
$minCol = Coordinate::columnIndexFromString($minCol); [$maxCol, $maxRow] = Coordinate::indexesFromString($max);
[$maxCol, $maxRow] = Coordinate::coordinateFromString($max);
$maxCol = Coordinate::columnIndexFromString($maxCol);
[$theadStart, $theadEnd, $tbodyStart] = $this->generateSheetStarts($sheet, $minRow); [$theadStart, $theadEnd, $tbodyStart] = $this->generateSheetStarts($sheet, $minRow);
@ -1703,11 +1701,11 @@ class Html extends BaseWriter
$first = $cells[0]; $first = $cells[0];
$last = $cells[1]; $last = $cells[1];
[$fc, $fr] = Coordinate::coordinateFromString($first); [$fc, $fr] = Coordinate::indexesFromString($first);
$fc = Coordinate::columnIndexFromString($fc) - 1; $fc = $fc - 1;
[$lc, $lr] = Coordinate::coordinateFromString($last); [$lc, $lr] = Coordinate::indexesFromString($last);
$lc = Coordinate::columnIndexFromString($lc) - 1; $lc = $lc - 1;
// loop through the individual cells in the individual merge // loop through the individual cells in the individual merge
$r = $fr - 1; $r = $fr - 1;

View File

@ -2,7 +2,6 @@
namespace PhpOffice\PhpSpreadsheet\Writer; namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Content; use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
@ -32,6 +31,41 @@ class Ods extends BaseWriter
*/ */
private $spreadSheet; private $spreadSheet;
/**
* @var Content
*/
private $writerPartContent;
/**
* @var Meta
*/
private $writerPartMeta;
/**
* @var MetaInf
*/
private $writerPartMetaInf;
/**
* @var Mimetype
*/
private $writerPartMimetype;
/**
* @var Settings
*/
private $writerPartSettings;
/**
* @var Styles
*/
private $writerPartStyles;
/**
* @var Thumbnails
*/
private $writerPartThumbnails;
/** /**
* Create a new Ods. * Create a new Ods.
*/ */
@ -39,35 +73,48 @@ class Ods extends BaseWriter
{ {
$this->setSpreadsheet($spreadsheet); $this->setSpreadsheet($spreadsheet);
$writerPartsArray = [ $this->writerPartContent = new Content($this);
'content' => Content::class, $this->writerPartMeta = new Meta($this);
'meta' => Meta::class, $this->writerPartMetaInf = new MetaInf($this);
'meta_inf' => MetaInf::class, $this->writerPartMimetype = new Mimetype($this);
'mimetype' => Mimetype::class, $this->writerPartSettings = new Settings($this);
'settings' => Settings::class, $this->writerPartStyles = new Styles($this);
'styles' => Styles::class, $this->writerPartThumbnails = new Thumbnails($this);
'thumbnails' => Thumbnails::class,
];
foreach ($writerPartsArray as $writer => $class) {
$this->writerParts[$writer] = new $class($this);
}
} }
/** public function getWriterPartContent(): Content
* Get writer part.
*
* @param string $pPartName Writer part name
*
* @return null|Ods\WriterPart
*/
public function getWriterPart($pPartName)
{ {
if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { return $this->writerPartContent;
return $this->writerParts[strtolower($pPartName)]; }
}
return null; public function getWriterPartMeta(): Meta
{
return $this->writerPartMeta;
}
public function getWriterPartMetaInf(): MetaInf
{
return $this->writerPartMetaInf;
}
public function getWriterPartMimetype(): Mimetype
{
return $this->writerPartMimetype;
}
public function getWriterPartSettings(): Settings
{
return $this->writerPartSettings;
}
public function getWriterPartStyles(): Styles
{
return $this->writerPartStyles;
}
public function getWriterPartThumbnails(): Thumbnails
{
return $this->writerPartThumbnails;
} }
/** /**
@ -88,13 +135,13 @@ class Ods extends BaseWriter
$zip = $this->createZip(); $zip = $this->createZip();
$zip->addFile('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest()); $zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
$zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail()); $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
$zip->addFile('content.xml', $this->getWriterPart('content')->write()); $zip->addFile('content.xml', $this->getWriterPartcontent()->write());
$zip->addFile('meta.xml', $this->getWriterPart('meta')->write()); $zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
$zip->addFile('mimetype', $this->getWriterPart('mimetype')->write()); $zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
$zip->addFile('settings.xml', $this->getWriterPart('settings')->write()); $zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
$zip->addFile('styles.xml', $this->getWriterPart('styles')->write()); $zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
// Close file // Close file
try { try {

View File

@ -39,7 +39,7 @@ class Content extends WriterPart
* *
* @return string XML Output * @return string XML Output
*/ */
public function write() public function write(): string
{ {
$objWriter = null; $objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) { if ($this->getParentWriter()->getUseDiskCaching()) {

View File

@ -3,22 +3,17 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Meta extends WriterPart class Meta extends WriterPart
{ {
/** /**
* Write meta.xml to XML format. * Write meta.xml to XML format.
* *
* @param Spreadsheet $spreadsheet
*
* @return string XML Output * @return string XML Output
*/ */
public function write(?Spreadsheet $spreadsheet = null) public function write(): string
{ {
if (!$spreadsheet) { $spreadsheet = $this->getParentWriter()->getSpreadsheet();
$spreadsheet = $this->getParentWriter()->getSpreadsheet();
}
$objWriter = null; $objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) { if ($this->getParentWriter()->getUseDiskCaching()) {

View File

@ -11,7 +11,7 @@ class MetaInf extends WriterPart
* *
* @return string XML Output * @return string XML Output
*/ */
public function writeManifest() public function write(): string
{ {
$objWriter = null; $objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) { if ($this->getParentWriter()->getUseDiskCaching()) {

View File

@ -2,18 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Mimetype extends WriterPart class Mimetype extends WriterPart
{ {
/** /**
* Write mimetype to plain text format. * Write mimetype to plain text format.
* *
* @param Spreadsheet $spreadsheet
*
* @return string XML Output * @return string XML Output
*/ */
public function write(?Spreadsheet $spreadsheet = null) public function write(): string
{ {
return 'application/vnd.oasis.opendocument.spreadsheet'; return 'application/vnd.oasis.opendocument.spreadsheet';
} }

View File

@ -23,11 +23,13 @@ class NamedExpressions
$this->formulaConvertor = $formulaConvertor; $this->formulaConvertor = $formulaConvertor;
} }
public function write(): void public function write(): string
{ {
$this->objWriter->startElement('table:named-expressions'); $this->objWriter->startElement('table:named-expressions');
$this->writeExpressions(); $this->writeExpressions();
$this->objWriter->endElement(); $this->objWriter->endElement();
return '';
} }
private function writeExpressions(): void private function writeExpressions(): void

View File

@ -4,18 +4,15 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Settings extends WriterPart class Settings extends WriterPart
{ {
/** /**
* Write settings.xml to XML format. * Write settings.xml to XML format.
* *
* @param Spreadsheet $spreadsheet
*
* @return string XML Output * @return string XML Output
*/ */
public function write(?Spreadsheet $spreadsheet = null) public function write(): string
{ {
if ($this->getParentWriter()->getUseDiskCaching()) { if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
@ -40,7 +37,7 @@ class Settings extends WriterPart
$objWriter->startElement('config:config-item-map-indexed'); $objWriter->startElement('config:config-item-map-indexed');
$objWriter->writeAttribute('config:name', 'Views'); $objWriter->writeAttribute('config:name', 'Views');
$objWriter->startElement('config:config-item-map-entry'); $objWriter->startElement('config:config-item-map-entry');
$spreadsheet = $spreadsheet ?? $this->getParentWriter()->getSpreadsheet(); $spreadsheet = $this->getParentWriter()->getSpreadsheet();
$objWriter->startElement('config:config-item'); $objWriter->startElement('config:config-item');
$objWriter->writeAttribute('config:name', 'ViewId'); $objWriter->writeAttribute('config:name', 'ViewId');

View File

@ -3,18 +3,15 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Styles extends WriterPart class Styles extends WriterPart
{ {
/** /**
* Write styles.xml to XML format. * Write styles.xml to XML format.
* *
* @param Spreadsheet $spreadsheet
*
* @return string XML Output * @return string XML Output
*/ */
public function write(?Spreadsheet $spreadsheet = null) public function write(): string
{ {
$objWriter = null; $objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) { if ($this->getParentWriter()->getUseDiskCaching()) {

View File

@ -2,18 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods; namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Thumbnails extends WriterPart class Thumbnails extends WriterPart
{ {
/** /**
* Write Thumbnails/thumbnail.png to PNG format. * Write Thumbnails/thumbnail.png to PNG format.
* *
* @param Spreadsheet $spreadsheet
*
* @return string XML Output * @return string XML Output
*/ */
public function writeThumbnail(?Spreadsheet $spreadsheet = null) public function write(): string
{ {
return ''; return '';
} }

View File

@ -30,4 +30,6 @@ abstract class WriterPart
{ {
$this->parentWriter = $writer; $this->parentWriter = $writer;
} }
abstract public function write(): string;
} }

View File

@ -23,6 +23,9 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
use PhpOffice\PhpSpreadsheet\Writer\Xls\Parser;
use PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook;
use PhpOffice\PhpSpreadsheet\Writer\Xls\Worksheet;
class Xls extends BaseWriter class Xls extends BaseWriter
{ {
@ -64,7 +67,7 @@ class Xls extends BaseWriter
/** /**
* Formula parser. * Formula parser.
* *
* @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Parser * @var Parser
*/ */
private $parser; private $parser;
@ -90,12 +93,12 @@ class Xls extends BaseWriter
private $documentSummaryInformation; private $documentSummaryInformation;
/** /**
* @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook * @var Workbook
*/ */
private $writerWorkbook; private $writerWorkbook;
/** /**
* @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Worksheet[] * @var Worksheet[]
*/ */
private $writerWorksheets; private $writerWorksheets;
@ -388,7 +391,7 @@ class Xls extends BaseWriter
} }
} }
private function processMemoryDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing, string $renderingFunctionx): void private function processMemoryDrawing(BstoreContainer &$bstoreContainer, MemoryDrawing $drawing, string $renderingFunctionx): void
{ {
switch ($renderingFunctionx) { switch ($renderingFunctionx) {
case MemoryDrawing::RENDERING_JPEG: case MemoryDrawing::RENDERING_JPEG:
@ -418,7 +421,7 @@ class Xls extends BaseWriter
$bstoreContainer->addBSE($BSE); $bstoreContainer->addBSE($BSE);
} }
private function processDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing): void private function processDrawing(BstoreContainer &$bstoreContainer, Drawing $drawing): void
{ {
$blipType = null; $blipType = null;
$blipData = ''; $blipData = '';

View File

@ -420,8 +420,8 @@ class Escher
$recType = 0xF010; $recType = 0xF010;
// start coordinates // start coordinates
[$column, $row] = Coordinate::coordinateFromString($this->object->getStartCoordinates()); [$column, $row] = Coordinate::indexesFromString($this->object->getStartCoordinates());
$c1 = Coordinate::columnIndexFromString($column) - 1; $c1 = $column - 1;
$r1 = $row - 1; $r1 = $row - 1;
// start offsetX // start offsetX
@ -431,8 +431,8 @@ class Escher
$startOffsetY = $this->object->getStartOffsetY(); $startOffsetY = $this->object->getStartOffsetY();
// end coordinates // end coordinates
[$column, $row] = Coordinate::coordinateFromString($this->object->getEndCoordinates()); [$column, $row] = Coordinate::indexesFromString($this->object->getEndCoordinates());
$c2 = Coordinate::columnIndexFromString($column) - 1; $c2 = $column - 1;
$r2 = $row - 1; $r2 = $row - 1;
// end offsetX // end offsetX

View File

@ -527,11 +527,11 @@ class Parser
} elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/mui', $token) && $this->spreadsheet->getDefinedName($token) !== null) { } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/mui', $token) && $this->spreadsheet->getDefinedName($token) !== null) {
return $this->convertDefinedName($token); return $this->convertDefinedName($token);
// commented so argument number can be processed correctly. See toReversePolish(). // commented so argument number can be processed correctly. See toReversePolish().
/*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token)) /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token))
{ {
return($this->convertFunction($token, $this->_func_args)); return($this->convertFunction($token, $this->_func_args));
}*/ }*/
// if it's an argument, ignore the token (the argument remains) // if it's an argument, ignore the token (the argument remains)
} elseif ($token == 'arg') { } elseif ($token == 'arg') {
return ''; return '';
} }
@ -597,10 +597,9 @@ class Parser
if ($args >= 0) { if ($args >= 0) {
return pack('Cv', $this->ptg['ptgFuncV'], $this->functions[$token][0]); return pack('Cv', $this->ptg['ptgFuncV'], $this->functions[$token][0]);
} }
// Variable number of args eg. SUM($i, $j, $k, ..). // Variable number of args eg. SUM($i, $j, $k, ..).
if ($args == -1) { return pack('CCv', $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]);
return pack('CCv', $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]);
}
} }
/** /**
@ -852,10 +851,10 @@ class Parser
* called by the addWorksheet() method of the * called by the addWorksheet() method of the
* \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook class. * \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook class.
* *
* @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::addWorksheet()
*
* @param string $name The name of the worksheet being added * @param string $name The name of the worksheet being added
* @param int $index The index of the worksheet being added * @param int $index The index of the worksheet being added
*
* @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::addWorksheet()
*/ */
public function setExtSheet($name, $index): void public function setExtSheet($name, $index): void
{ {
@ -1231,9 +1230,9 @@ class Parser
* This function just introduces a ptgParen element in the tree, so that Excel * This function just introduces a ptgParen element in the tree, so that Excel
* doesn't get confused when working with a parenthesized formula afterwards. * doesn't get confused when working with a parenthesized formula afterwards.
* *
* @see fact()
*
* @return array The parsed ptg'd tree * @return array The parsed ptg'd tree
*
* @see fact()
*/ */
private function parenthesizedExpression() private function parenthesizedExpression()
{ {
@ -1475,6 +1474,7 @@ class Parser
} else { } else {
$left_tree = ''; $left_tree = '';
} }
// add it's left subtree and return. // add it's left subtree and return.
return $left_tree . $this->convertFunction($tree['value'], $tree['right']); return $left_tree . $this->convertFunction($tree['value'], $tree['right']);
} }

View File

@ -678,13 +678,13 @@ class Workbook extends BIFFwriter
$formulaData = ''; $formulaData = '';
for ($j = 0; $j < $countPrintArea; ++$j) { for ($j = 0; $j < $countPrintArea; ++$j) {
$printAreaRect = $printArea[$j]; // e.g. A3:J6 $printAreaRect = $printArea[$j]; // e.g. A3:J6
$printAreaRect[0] = Coordinate::coordinateFromString($printAreaRect[0]); $printAreaRect[0] = Coordinate::indexesFromString($printAreaRect[0]);
$printAreaRect[1] = Coordinate::coordinateFromString($printAreaRect[1]); $printAreaRect[1] = Coordinate::indexesFromString($printAreaRect[1]);
$print_rowmin = $printAreaRect[0][1] - 1; $print_rowmin = $printAreaRect[0][1] - 1;
$print_rowmax = $printAreaRect[1][1] - 1; $print_rowmax = $printAreaRect[1][1] - 1;
$print_colmin = Coordinate::columnIndexFromString($printAreaRect[0][0]) - 1; $print_colmin = $printAreaRect[0][0] - 1;
$print_colmax = Coordinate::columnIndexFromString($printAreaRect[1][0]) - 1; $print_colmax = $printAreaRect[1][0] - 1;
// construct formula data manually because parser does not recognize absolute 3d cell references // construct formula data manually because parser does not recognize absolute 3d cell references
$formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax);
@ -756,7 +756,7 @@ class Workbook extends BIFFwriter
* Write a short NAME record. * Write a short NAME record.
* *
* @param string $name * @param string $name
* @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global * @param int $sheetIndex 1-based sheet index the defined name applies to. 0 = global
* @param int[][] $rangeBounds range boundaries * @param int[][] $rangeBounds range boundaries
* @param bool $isHidden * @param bool $isHidden
* *
@ -839,10 +839,9 @@ class Workbook extends BIFFwriter
/** /**
* Writes Excel BIFF BOUNDSHEET record. * Writes Excel BIFF BOUNDSHEET record.
* *
* @param Worksheet $sheet Worksheet name
* @param int $offset Location of worksheet BOF * @param int $offset Location of worksheet BOF
*/ */
private function writeBoundSheet($sheet, $offset): void private function writeBoundSheet(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet, $offset): void
{ {
$sheetname = $sheet->getTitle(); $sheetname = $sheet->getTitle();
$record = 0x0085; // Record identifier $record = 0x0085; // Record identifier

View File

@ -217,8 +217,8 @@ class Worksheet extends BIFFwriter
* *
* @param int $str_total Total number of strings * @param int $str_total Total number of strings
* @param int $str_unique Total number of unique strings * @param int $str_unique Total number of unique strings
* @param array &$str_table String Table * @param array $str_table String Table
* @param array &$colors Colour Table * @param array $colors Colour Table
* @param Parser $parser The formula parser created for the Workbook * @param Parser $parser The formula parser created for the Workbook
* @param bool $preCalculateFormulas Flag indicating whether formulas should be calculated or just written * @param bool $preCalculateFormulas Flag indicating whether formulas should be calculated or just written
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet The worksheet to write * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet The worksheet to write
@ -512,7 +512,7 @@ class Worksheet extends BIFFwriter
// Hyperlinks // Hyperlinks
foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) {
[$column, $row] = Coordinate::coordinateFromString($coordinate); [$column, $row] = Coordinate::indexesFromString($coordinate);
$url = $hyperlink->getUrl(); $url = $hyperlink->getUrl();
@ -526,7 +526,7 @@ class Worksheet extends BIFFwriter
$url = 'external:' . $url; $url = 'external:' . $url;
} }
$this->writeUrl($row - 1, Coordinate::columnIndexFromString($column) - 1, $url); $this->writeUrl($row - 1, $column - 1, $url);
} }
$this->writeDataValidity(); $this->writeDataValidity();
@ -587,10 +587,10 @@ class Worksheet extends BIFFwriter
$lastCell = $explodes[1]; $lastCell = $explodes[1];
} }
$firstCellCoordinates = Coordinate::coordinateFromString($firstCell); // e.g. [0, 1] $firstCellCoordinates = Coordinate::indexesFromString($firstCell); // e.g. [0, 1]
$lastCellCoordinates = Coordinate::coordinateFromString($lastCell); // e.g. [1, 6] $lastCellCoordinates = Coordinate::indexesFromString($lastCell); // e.g. [1, 6]
return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, Coordinate::columnIndexFromString($firstCellCoordinates[0]) - 1, Coordinate::columnIndexFromString($lastCellCoordinates[0]) - 1); return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, $firstCellCoordinates[0] - 1, $lastCellCoordinates[0] - 1);
} }
/** /**
@ -1455,10 +1455,10 @@ class Worksheet extends BIFFwriter
// extract the row and column indexes // extract the row and column indexes
$range = Coordinate::splitRange($mergeCell); $range = Coordinate::splitRange($mergeCell);
[$first, $last] = $range[0]; [$first, $last] = $range[0];
[$firstColumn, $firstRow] = Coordinate::coordinateFromString($first); [$firstColumn, $firstRow] = Coordinate::indexesFromString($first);
[$lastColumn, $lastRow] = Coordinate::coordinateFromString($last); [$lastColumn, $lastRow] = Coordinate::indexesFromString($last);
$recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, Coordinate::columnIndexFromString($firstColumn) - 1, Coordinate::columnIndexFromString($lastColumn) - 1); $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, $firstColumn - 1, $lastColumn - 1);
// flush record if we have reached limit for number of merged cells, or reached final merged cell // flush record if we have reached limit for number of merged cells, or reached final merged cell
if ($j == $maxCountMergeCellsPerRecord || $i == $countMergeCells) { if ($j == $maxCountMergeCellsPerRecord || $i == $countMergeCells) {
@ -1601,76 +1601,37 @@ class Worksheet extends BIFFwriter
*/ */
private function writePanes(): void private function writePanes(): void
{ {
$panes = []; if (!$this->phpSheet->getFreezePane()) {
if ($this->phpSheet->getFreezePane()) {
[$column, $row] = Coordinate::coordinateFromString($this->phpSheet->getFreezePane());
$panes[0] = Coordinate::columnIndexFromString($column) - 1;
$panes[1] = $row - 1;
[$leftMostColumn, $topRow] = Coordinate::coordinateFromString($this->phpSheet->getTopLeftCell());
//Coordinates are zero-based in xls files
$panes[2] = $topRow - 1;
$panes[3] = Coordinate::columnIndexFromString($leftMostColumn) - 1;
} else {
// thaw panes // thaw panes
return; return;
} }
$x = $panes[0] ?? null; [$column, $row] = Coordinate::indexesFromString($this->phpSheet->getFreezePane());
$y = $panes[1] ?? null; $x = $column - 1;
$rwTop = $panes[2] ?? null; $y = $row - 1;
$colLeft = $panes[3] ?? null;
if (count($panes) > 4) { // if Active pane was received [$leftMostColumn, $topRow] = Coordinate::indexesFromString($this->phpSheet->getTopLeftCell());
$pnnAct = $panes[4]; //Coordinates are zero-based in xls files
} else { $rwTop = $topRow - 1;
$pnnAct = null; $colLeft = $leftMostColumn - 1;
}
$record = 0x0041; // Record identifier $record = 0x0041; // Record identifier
$length = 0x000A; // Number of bytes to follow $length = 0x000A; // Number of bytes to follow
// Code specific to frozen or thawed panes.
if ($this->phpSheet->getFreezePane()) {
// Set default values for $rwTop and $colLeft
if (!isset($rwTop)) {
$rwTop = $y;
}
if (!$colLeft) {
$colLeft = $x;
}
} else {
// Set default values for $rwTop and $colLeft
if (!isset($rwTop)) {
$rwTop = 0;
}
if (!$colLeft) {
$colLeft = 0;
}
// Convert Excel's row and column units to the internal units.
// The default row height is 12.75
// The default column width is 8.43
// The following slope and intersection values were interpolated.
//
$y = 20 * $y + 255;
$x = 113.879 * $x + 390;
}
// Determine which pane should be active. There is also the undocumented // Determine which pane should be active. There is also the undocumented
// option to override this should it be necessary: may be removed later. // option to override this should it be necessary: may be removed later.
// $pnnAct = null;
if (!$pnnAct) { if ($x != 0 && $y != 0) {
if ($x != 0 && $y != 0) { $pnnAct = 0; // Bottom right
$pnnAct = 0; // Bottom right }
} if ($x != 0 && $y == 0) {
if ($x != 0 && $y == 0) { $pnnAct = 1; // Top right
$pnnAct = 1; // Top right }
} if ($x == 0 && $y != 0) {
if ($x == 0 && $y != 0) { $pnnAct = 2; // Bottom left
$pnnAct = 2; // Bottom left }
} if ($x == 0 && $y == 0) {
if ($x == 0 && $y == 0) { $pnnAct = 3; // Top left
$pnnAct = 3; // Top left
}
} }
$this->activePane = $pnnAct; // Used in writeSelection $this->activePane = $pnnAct; // Used in writeSelection
@ -4427,10 +4388,7 @@ class Worksheet extends BIFFwriter
$arrConditional[] = $conditional->getHashCode(); $arrConditional[] = $conditional->getHashCode();
} }
// Cells // Cells
$arrCoord = Coordinate::coordinateFromString($cellCoordinate); $arrCoord = Coordinate::indexesFromString($cellCoordinate);
if (!is_numeric($arrCoord[0])) {
$arrCoord[0] = Coordinate::columnIndexFromString($arrCoord[0]);
}
if ($numColumnMin === null || ($numColumnMin > $arrCoord[0])) { if ($numColumnMin === null || ($numColumnMin > $arrCoord[0])) {
$numColumnMin = $arrCoord[0]; $numColumnMin = $arrCoord[0];
} }

View File

@ -5,8 +5,13 @@ namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\HashTable; use PhpOffice\PhpSpreadsheet\HashTable;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Borders;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Font;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing as WorksheetDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing as WorksheetDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
@ -37,13 +42,6 @@ class Xlsx extends BaseWriter
*/ */
private $office2003compatibility = false; private $office2003compatibility = false;
/**
* Private writer parts.
*
* @var Xlsx\WriterPart[]
*/
private $writerParts = [];
/** /**
* Private Spreadsheet. * Private Spreadsheet.
* *
@ -61,49 +59,49 @@ class Xlsx extends BaseWriter
/** /**
* Private unique Conditional HashTable. * Private unique Conditional HashTable.
* *
* @var HashTable * @var HashTable<Conditional>
*/ */
private $stylesConditionalHashTable; private $stylesConditionalHashTable;
/** /**
* Private unique Style HashTable. * Private unique Style HashTable.
* *
* @var HashTable * @var HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
*/ */
private $styleHashTable; private $styleHashTable;
/** /**
* Private unique Fill HashTable. * Private unique Fill HashTable.
* *
* @var HashTable * @var HashTable<Fill>
*/ */
private $fillHashTable; private $fillHashTable;
/** /**
* Private unique \PhpOffice\PhpSpreadsheet\Style\Font HashTable. * Private unique \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
* *
* @var HashTable * @var HashTable<Font>
*/ */
private $fontHashTable; private $fontHashTable;
/** /**
* Private unique Borders HashTable. * Private unique Borders HashTable.
* *
* @var HashTable * @var HashTable<Borders>
*/ */
private $bordersHashTable; private $bordersHashTable;
/** /**
* Private unique NumberFormat HashTable. * Private unique NumberFormat HashTable.
* *
* @var HashTable * @var HashTable<NumberFormat>
*/ */
private $numFmtHashTable; private $numFmtHashTable;
/** /**
* Private unique \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable. * Private unique \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
* *
* @var HashTable * @var HashTable<BaseDrawing>
*/ */
private $drawingHashTable; private $drawingHashTable;
@ -114,6 +112,71 @@ class Xlsx extends BaseWriter
*/ */
private $zip; private $zip;
/**
* @var Chart
*/
private $writerPartChart;
/**
* @var Comments
*/
private $writerPartComments;
/**
* @var ContentTypes
*/
private $writerPartContentTypes;
/**
* @var DocProps
*/
private $writerPartDocProps;
/**
* @var Drawing
*/
private $writerPartDrawing;
/**
* @var Rels
*/
private $writerPartRels;
/**
* @var RelsRibbon
*/
private $writerPartRelsRibbon;
/**
* @var RelsVBA
*/
private $writerPartRelsVBA;
/**
* @var StringTable
*/
private $writerPartStringTable;
/**
* @var Style
*/
private $writerPartStyle;
/**
* @var Theme
*/
private $writerPartTheme;
/**
* @var Workbook
*/
private $writerPartWorkbook;
/**
* @var Worksheet
*/
private $writerPartWorksheet;
/** /**
* Create a new Xlsx Writer. * Create a new Xlsx Writer.
*/ */
@ -122,53 +185,93 @@ class Xlsx extends BaseWriter
// Assign PhpSpreadsheet // Assign PhpSpreadsheet
$this->setSpreadsheet($spreadsheet); $this->setSpreadsheet($spreadsheet);
$writerPartsArray = [ $this->writerPartChart = new Chart($this);
'stringtable' => StringTable::class, $this->writerPartComments = new Comments($this);
'contenttypes' => ContentTypes::class, $this->writerPartContentTypes = new ContentTypes($this);
'docprops' => DocProps::class, $this->writerPartDocProps = new DocProps($this);
'rels' => Rels::class, $this->writerPartDrawing = new Drawing($this);
'theme' => Theme::class, $this->writerPartRels = new Rels($this);
'style' => Style::class, $this->writerPartRelsRibbon = new RelsRibbon($this);
'workbook' => Workbook::class, $this->writerPartRelsVBA = new RelsVBA($this);
'worksheet' => Worksheet::class, $this->writerPartStringTable = new StringTable($this);
'drawing' => Drawing::class, $this->writerPartStyle = new Style($this);
'comments' => Comments::class, $this->writerPartTheme = new Theme($this);
'chart' => Chart::class, $this->writerPartWorkbook = new Workbook($this);
'relsvba' => RelsVBA::class, $this->writerPartWorksheet = new Worksheet($this);
'relsribbonobjects' => RelsRibbon::class,
];
// Initialise writer parts
// and Assign their parent IWriters
foreach ($writerPartsArray as $writer => $class) {
$this->writerParts[$writer] = new $class($this);
}
$hashTablesArray = ['stylesConditionalHashTable', 'fillHashTable', 'fontHashTable',
'bordersHashTable', 'numFmtHashTable', 'drawingHashTable',
'styleHashTable',
];
// Set HashTable variables // Set HashTable variables
foreach ($hashTablesArray as $tableName) { $this->bordersHashTable = new HashTable();
$this->$tableName = new HashTable(); $this->drawingHashTable = new HashTable();
} $this->fillHashTable = new HashTable();
$this->fontHashTable = new HashTable();
$this->numFmtHashTable = new HashTable();
$this->styleHashTable = new HashTable();
$this->stylesConditionalHashTable = new HashTable();
} }
/** public function getWriterPartChart(): Chart
* Get writer part.
*
* @param string $pPartName Writer part name
*
* @return \PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart
*/
public function getWriterPart($pPartName)
{ {
if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) { return $this->writerPartChart;
return $this->writerParts[strtolower($pPartName)]; }
}
return null; public function getWriterPartComments(): Comments
{
return $this->writerPartComments;
}
public function getWriterPartContentTypes(): ContentTypes
{
return $this->writerPartContentTypes;
}
public function getWriterPartDocProps(): DocProps
{
return $this->writerPartDocProps;
}
public function getWriterPartDrawing(): Drawing
{
return $this->writerPartDrawing;
}
public function getWriterPartRels(): Rels
{
return $this->writerPartRels;
}
public function getWriterPartRelsRibbon(): RelsRibbon
{
return $this->writerPartRelsRibbon;
}
public function getWriterPartRelsVBA(): RelsVBA
{
return $this->writerPartRelsVBA;
}
public function getWriterPartStringTable(): StringTable
{
return $this->writerPartStringTable;
}
public function getWriterPartStyle(): Style
{
return $this->writerPartStyle;
}
public function getWriterPartTheme(): Theme
{
return $this->writerPartTheme;
}
public function getWriterPartWorkbook(): Workbook
{
return $this->writerPartWorkbook;
}
public function getWriterPartWorksheet(): Worksheet
{
return $this->writerPartWorksheet;
} }
/** /**
@ -192,19 +295,19 @@ class Xlsx extends BaseWriter
// Create string lookup table // Create string lookup table
$this->stringTable = []; $this->stringTable = [];
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable); $this->stringTable = $this->getWriterPartStringTable()->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
} }
// Create styles dictionaries // Create styles dictionaries
$this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet)); $this->styleHashTable->addFromSource($this->getWriterPartStyle()->allStyles($this->spreadSheet));
$this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet)); $this->stylesConditionalHashTable->addFromSource($this->getWriterPartStyle()->allConditionalStyles($this->spreadSheet));
$this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet)); $this->fillHashTable->addFromSource($this->getWriterPartStyle()->allFills($this->spreadSheet));
$this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet)); $this->fontHashTable->addFromSource($this->getWriterPartStyle()->allFonts($this->spreadSheet));
$this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet)); $this->bordersHashTable->addFromSource($this->getWriterPartStyle()->allBorders($this->spreadSheet));
$this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet)); $this->numFmtHashTable->addFromSource($this->getWriterPartStyle()->allNumberFormats($this->spreadSheet));
// Create drawing dictionary // Create drawing dictionary
$this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet)); $this->drawingHashTable->addFromSource($this->getWriterPartDrawing()->allDrawings($this->spreadSheet));
$options = new Archive(); $options = new Archive();
$options->setEnableZip64(false); $options->setEnableZip64(false);
@ -213,7 +316,7 @@ class Xlsx extends BaseWriter
$this->zip = new ZipStream(null, $options); $this->zip = new ZipStream(null, $options);
// Add [Content_Types].xml to ZIP file // Add [Content_Types].xml to ZIP file
$this->addZipFile('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts)); $this->addZipFile('[Content_Types].xml', $this->getWriterPartContentTypes()->writeContentTypes($this->spreadSheet, $this->includeCharts));
//if hasMacros, add the vbaProject.bin file, Certificate file(if exists) //if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
if ($this->spreadSheet->hasMacros()) { if ($this->spreadSheet->hasMacros()) {
@ -225,7 +328,7 @@ class Xlsx extends BaseWriter
//signed macros ? //signed macros ?
// Yes : add the certificate file and the related rels file // Yes : add the certificate file and the related rels file
$this->addZipFile('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate()); $this->addZipFile('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
$this->addZipFile('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet)); $this->addZipFile('xl/_rels/vbaProject.bin.rels', $this->getWriterPartRelsVBA()->writeVBARelationships($this->spreadSheet));
} }
} }
} }
@ -240,43 +343,43 @@ class Xlsx extends BaseWriter
$this->addZipFile($tmpRootPath . $aPath, $aContent); $this->addZipFile($tmpRootPath . $aPath, $aContent);
} }
//the rels for files //the rels for files
$this->addZipFile($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet)); $this->addZipFile($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPartRelsRibbon()->writeRibbonRelationships($this->spreadSheet));
} }
} }
// Add relationships to ZIP file // Add relationships to ZIP file
$this->addZipFile('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet)); $this->addZipFile('_rels/.rels', $this->getWriterPartRels()->writeRelationships($this->spreadSheet));
$this->addZipFile('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet)); $this->addZipFile('xl/_rels/workbook.xml.rels', $this->getWriterPartRels()->writeWorkbookRelationships($this->spreadSheet));
// Add document properties to ZIP file // Add document properties to ZIP file
$this->addZipFile('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet)); $this->addZipFile('docProps/app.xml', $this->getWriterPartDocProps()->writeDocPropsApp($this->spreadSheet));
$this->addZipFile('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet)); $this->addZipFile('docProps/core.xml', $this->getWriterPartDocProps()->writeDocPropsCore($this->spreadSheet));
$customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet); $customPropertiesPart = $this->getWriterPartDocProps()->writeDocPropsCustom($this->spreadSheet);
if ($customPropertiesPart !== null) { if ($customPropertiesPart !== null) {
$this->addZipFile('docProps/custom.xml', $customPropertiesPart); $this->addZipFile('docProps/custom.xml', $customPropertiesPart);
} }
// Add theme to ZIP file // Add theme to ZIP file
$this->addZipFile('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet)); $this->addZipFile('xl/theme/theme1.xml', $this->getWriterPartTheme()->writeTheme($this->spreadSheet));
// Add string table to ZIP file // Add string table to ZIP file
$this->addZipFile('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable)); $this->addZipFile('xl/sharedStrings.xml', $this->getWriterPartStringTable()->writeStringTable($this->stringTable));
// Add styles to ZIP file // Add styles to ZIP file
$this->addZipFile('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet)); $this->addZipFile('xl/styles.xml', $this->getWriterPartStyle()->writeStyles($this->spreadSheet));
// Add workbook to ZIP file // Add workbook to ZIP file
$this->addZipFile('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas)); $this->addZipFile('xl/workbook.xml', $this->getWriterPartWorkbook()->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
$chartCount = 0; $chartCount = 0;
// Add worksheets // Add worksheets
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$this->addZipFile('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts)); $this->addZipFile('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPartWorksheet()->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
if ($this->includeCharts) { if ($this->includeCharts) {
$charts = $this->spreadSheet->getSheet($i)->getChartCollection(); $charts = $this->spreadSheet->getSheet($i)->getChartCollection();
if (count($charts) > 0) { if (count($charts) > 0) {
foreach ($charts as $chart) { foreach ($charts as $chart) {
$this->addZipFile('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas)); $this->addZipFile('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPartChart()->writeChart($chart, $this->preCalculateFormulas));
++$chartCount; ++$chartCount;
} }
} }
@ -287,7 +390,7 @@ class Xlsx extends BaseWriter
// Add worksheet relationships (drawings, ...) // Add worksheet relationships (drawings, ...)
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
// Add relationships // Add relationships
$this->addZipFile('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts)); $this->addZipFile('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPartRels()->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
// Add unparsedLoadedData // Add unparsedLoadedData
$sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName(); $sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
@ -312,13 +415,13 @@ class Xlsx extends BaseWriter
// Add drawing and image relationship parts // Add drawing and image relationship parts
if (($drawingCount > 0) || ($chartCount > 0)) { if (($drawingCount > 0) || ($chartCount > 0)) {
// Drawing relationships // Drawing relationships
$this->addZipFile('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); $this->addZipFile('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPartRels()->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
// Drawings // Drawings
$this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); $this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
} elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) { } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
// Drawings // Drawings
$this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); $this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
} }
// Add unparsed drawings // Add unparsed drawings
@ -335,10 +438,10 @@ class Xlsx extends BaseWriter
// Add comment relationship parts // Add comment relationship parts
if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) { if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
// VML Comments // VML Comments
$this->addZipFile('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i))); $this->addZipFile('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPartComments()->writeVMLComments($this->spreadSheet->getSheet($i)));
// Comments // Comments
$this->addZipFile('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); $this->addZipFile('xl/comments' . ($i + 1) . '.xml', $this->getWriterPartComments()->writeComments($this->spreadSheet->getSheet($i)));
} }
// Add unparsed relationship parts // Add unparsed relationship parts
@ -351,10 +454,10 @@ class Xlsx extends BaseWriter
// Add header/footer relationship parts // Add header/footer relationship parts
if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
// VML Drawings // VML Drawings
$this->addZipFile('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i))); $this->addZipFile('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPartDrawing()->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
// VML Drawing relationships // VML Drawing relationships
$this->addZipFile('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i))); $this->addZipFile('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPartRels()->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
// Media // Media
foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
@ -445,7 +548,7 @@ class Xlsx extends BaseWriter
/** /**
* Get Style HashTable. * Get Style HashTable.
* *
* @return HashTable * @return HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
*/ */
public function getStyleHashTable() public function getStyleHashTable()
{ {
@ -455,7 +558,7 @@ class Xlsx extends BaseWriter
/** /**
* Get Conditional HashTable. * Get Conditional HashTable.
* *
* @return HashTable * @return HashTable<Conditional>
*/ */
public function getStylesConditionalHashTable() public function getStylesConditionalHashTable()
{ {
@ -465,7 +568,7 @@ class Xlsx extends BaseWriter
/** /**
* Get Fill HashTable. * Get Fill HashTable.
* *
* @return HashTable * @return HashTable<Fill>
*/ */
public function getFillHashTable() public function getFillHashTable()
{ {
@ -475,7 +578,7 @@ class Xlsx extends BaseWriter
/** /**
* Get \PhpOffice\PhpSpreadsheet\Style\Font HashTable. * Get \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
* *
* @return HashTable * @return HashTable<Font>
*/ */
public function getFontHashTable() public function getFontHashTable()
{ {
@ -485,7 +588,7 @@ class Xlsx extends BaseWriter
/** /**
* Get Borders HashTable. * Get Borders HashTable.
* *
* @return HashTable * @return HashTable<Borders>
*/ */
public function getBordersHashTable() public function getBordersHashTable()
{ {
@ -495,7 +598,7 @@ class Xlsx extends BaseWriter
/** /**
* Get NumberFormat HashTable. * Get NumberFormat HashTable.
* *
* @return HashTable * @return HashTable<NumberFormat>
*/ */
public function getNumFmtHashTable() public function getNumFmtHashTable()
{ {
@ -505,7 +608,7 @@ class Xlsx extends BaseWriter
/** /**
* Get \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable. * Get \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
* *
* @return HashTable * @return HashTable<BaseDrawing>
*/ */
public function getDrawingHashTable() public function getDrawingHashTable()
{ {

View File

@ -129,7 +129,7 @@ class Chart extends WriterPart
if ((is_array($caption)) && (count($caption) > 0)) { if ((is_array($caption)) && (count($caption) > 0)) {
$caption = $caption[0]; $caption = $caption[0];
} }
$this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
$objWriter->endElement(); $objWriter->endElement();
$objWriter->endElement(); $objWriter->endElement();
@ -1040,9 +1040,9 @@ class Chart extends WriterPart
* @param DataSeries $plotGroup * @param DataSeries $plotGroup
* @param string $groupType Type of plot for dataseries * @param string $groupType Type of plot for dataseries
* @param XMLWriter $objWriter XML Writer * @param XMLWriter $objWriter XML Writer
* @param bool &$catIsMultiLevelSeries Is category a multi-series category * @param bool $catIsMultiLevelSeries Is category a multi-series category
* @param bool &$valIsMultiLevelSeries Is value set a multi-series set * @param bool $valIsMultiLevelSeries Is value set a multi-series set
* @param string &$plotGroupingType Type of grouping for multi-series values * @param string $plotGroupingType Type of grouping for multi-series values
*/ */
private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
{ {

View File

@ -79,7 +79,7 @@ class Comments extends WriterPart
// text // text
$objWriter->startElement('text'); $objWriter->startElement('text');
$this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $pComment->getText());
$objWriter->endElement(); $objWriter->endElement();
$objWriter->endElement(); $objWriter->endElement();
@ -165,8 +165,7 @@ class Comments extends WriterPart
private function writeVMLComment(XMLWriter $objWriter, $pCellReference, Comment $pComment): void private function writeVMLComment(XMLWriter $objWriter, $pCellReference, Comment $pComment): void
{ {
// Metadata // Metadata
[$column, $row] = Coordinate::coordinateFromString($pCellReference); [$column, $row] = Coordinate::indexesFromString($pCellReference);
$column = Coordinate::columnIndexFromString($column);
$id = 1024 + $column + $row; $id = 1024 + $column + $row;
$id = substr($id, 0, 4); $id = substr($id, 0, 4);

View File

@ -84,22 +84,22 @@ class Drawing extends WriterPart
public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1): void public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1): void
{ {
$tl = $pChart->getTopLeftPosition(); $tl = $pChart->getTopLeftPosition();
$tl['colRow'] = Coordinate::coordinateFromString($tl['cell']); $tlColRow = Coordinate::indexesFromString($tl['cell']);
$br = $pChart->getBottomRightPosition(); $br = $pChart->getBottomRightPosition();
$br['colRow'] = Coordinate::coordinateFromString($br['cell']); $brColRow = Coordinate::indexesFromString($br['cell']);
$objWriter->startElement('xdr:twoCellAnchor'); $objWriter->startElement('xdr:twoCellAnchor');
$objWriter->startElement('xdr:from'); $objWriter->startElement('xdr:from');
$objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($tl['colRow'][0]) - 1); $objWriter->writeElement('xdr:col', $tlColRow[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset'])); $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset']));
$objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); $objWriter->writeElement('xdr:row', $tlColRow[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset'])); $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset']));
$objWriter->endElement(); $objWriter->endElement();
$objWriter->startElement('xdr:to'); $objWriter->startElement('xdr:to');
$objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($br['colRow'][0]) - 1); $objWriter->writeElement('xdr:col', $brColRow[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset'])); $objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset']));
$objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); $objWriter->writeElement('xdr:row', $brColRow[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset'])); $objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset']));
$objWriter->endElement(); $objWriter->endElement();
@ -158,8 +158,7 @@ class Drawing extends WriterPart
// xdr:oneCellAnchor // xdr:oneCellAnchor
$objWriter->startElement('xdr:oneCellAnchor'); $objWriter->startElement('xdr:oneCellAnchor');
// Image location // Image location
$aCoordinates = Coordinate::coordinateFromString($pDrawing->getCoordinates()); $aCoordinates = Coordinate::indexesFromString($pDrawing->getCoordinates());
$aCoordinates[0] = Coordinate::columnIndexFromString($aCoordinates[0]);
// xdr:from // xdr:from
$objWriter->startElement('xdr:from'); $objWriter->startElement('xdr:from');
@ -433,7 +432,7 @@ class Drawing extends WriterPart
{ {
// Calculate object id // Calculate object id
preg_match('{(\d+)}', md5($pReference), $m); preg_match('{(\d+)}', md5($pReference), $m);
$id = 1500 + (substr($m[1], 0, 2) * 1); $id = 1500 + ((int) substr($m[1], 0, 2) * 1);
// Calculate offset // Calculate offset
$width = $pImage->getWidth(); $width = $pImage->getWidth();

View File

@ -291,7 +291,7 @@ class Rels extends WriterPart
/** /**
* Write drawing relationships to XML format. * Write drawing relationships to XML format.
* *
* @param int &$chartRef Chart ID * @param int $chartRef Chart ID
* @param bool $includeCharts Flag indicating if we should write charts * @param bool $includeCharts Flag indicating if we should write charts
* *
* @return string XML Output * @return string XML Output
@ -425,9 +425,7 @@ class Rels extends WriterPart
} }
/** /**
* @param $objWriter
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing
* @param $i
* *
* @return int * @return int
*/ */

View File

@ -784,13 +784,9 @@ class Theme extends WriterPart
/** /**
* Write fonts to XML format. * Write fonts to XML format.
* *
* @param XMLWriter $objWriter * @param string[] $fontSet
* @param string $latinFont
* @param array of string $fontSet
*
* @return string XML Output
*/ */
private function writeFonts($objWriter, $latinFont, $fontSet) private function writeFonts(XMLWriter $objWriter, string $latinFont, array $fontSet): void
{ {
// a:latin // a:latin
$objWriter->startElement('a:latin'); $objWriter->startElement('a:latin');
@ -817,12 +813,8 @@ class Theme extends WriterPart
/** /**
* Write colour scheme to XML format. * Write colour scheme to XML format.
*
* @param XMLWriter $objWriter
*
* @return string XML Output
*/ */
private function writeColourScheme($objWriter) private function writeColourScheme(XMLWriter $objWriter): void
{ {
foreach (self::$colourScheme as $colourName => $colourValue) { foreach (self::$colourScheme as $colourName => $colourValue) {
$objWriter->startElement('a:' . $colourName); $objWriter->startElement('a:' . $colourName);

View File

@ -1084,7 +1084,7 @@ class Worksheet extends WriterPart
private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable): void private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable): void
{ {
// Flipped stringtable, for faster index searching // Flipped stringtable, for faster index searching
$aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); $aFlippedStringTable = $this->getParentWriter()->getWriterPartstringtable()->flipStringTable($pStringTable);
// sheetData // sheetData
$objWriter->startElement('sheetData'); $objWriter->startElement('sheetData');
@ -1169,7 +1169,7 @@ class Worksheet extends WriterPart
$objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue))); $objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
} elseif ($cellValue instanceof RichText) { } elseif ($cellValue instanceof RichText) {
$objWriter->startElement('is'); $objWriter->startElement('is');
$this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue);
$objWriter->endElement(); $objWriter->endElement();
} }
} }

View File

@ -262,9 +262,6 @@ class AdvancedValueBinderTest extends TestCase
/** /**
* @dataProvider stringProvider * @dataProvider stringProvider
*
* @param mixed $value
* @param mixed $wrapped
*/ */
public function testStringWrapping(string $value, bool $wrapped): void public function testStringWrapping(string $value, bool $wrapped): void
{ {

View File

@ -96,6 +96,20 @@ class CoordinateTest extends TestCase
return require 'tests/data/CellCoordinates.php'; return require 'tests/data/CellCoordinates.php';
} }
/**
* @dataProvider providerIndexesFromString
*/
public function testIndexesFromString(array $expectedResult, string $rangeSet): void
{
$result = Coordinate::indexesFromString($rangeSet);
self::assertSame($expectedResult, $result);
}
public function providerIndexesFromString(): array
{
return require 'tests/data/Cell/IndexesFromString.php';
}
public function testCoordinateFromStringWithRangeAddress(): void public function testCoordinateFromStringWithRangeAddress(): void
{ {
$cellAddress = 'A1:AI2012'; $cellAddress = 'A1:AI2012';

View File

@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder; use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class DefaultValueBinderTest extends TestCase class DefaultValueBinderTest extends TestCase
@ -15,7 +16,7 @@ class DefaultValueBinderTest extends TestCase
private function createCellStub() private function createCellStub()
{ {
// Create a stub for the Cell class. // Create a stub for the Cell class.
/** @var Cell $cellStub */ /** @var Cell&MockObject $cellStub */
$cellStub = $this->getMockBuilder(Cell::class) $cellStub = $this->getMockBuilder(Cell::class)
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();

View File

@ -135,6 +135,7 @@ class DefinedNameTest extends TestCase
DefinedName::createInstance('xyz', $this->spreadsheet->getActiveSheet(), 'A1') DefinedName::createInstance('xyz', $this->spreadsheet->getActiveSheet(), 'A1')
); );
/** @var NamedRange $namedRange */
$namedRange = $this->spreadsheet->getDefinedName('XYZ'); $namedRange = $this->spreadsheet->getDefinedName('XYZ');
self::assertInstanceOf(NamedRange::class, $namedRange); self::assertInstanceOf(NamedRange::class, $namedRange);
self::assertEquals('A1', $namedRange->getRange()); self::assertEquals('A1', $namedRange->getRange());

View File

@ -15,8 +15,6 @@ class ColumnWidthTest extends AbstractFunctional
/** /**
* @dataProvider providerFormats * @dataProvider providerFormats
*
* @param $format
*/ */
public function testReadColumnWidth($format): void public function testReadColumnWidth($format): void
{ {

View File

@ -21,8 +21,6 @@ class CommentsTest extends AbstractFunctional
* count of comments in correct coords. * count of comments in correct coords.
* *
* @dataProvider providerFormats * @dataProvider providerFormats
*
* @param $format
*/ */
public function testComments($format): void public function testComments($format): void
{ {

View File

@ -23,8 +23,8 @@ class CsvContiguousTest extends TestCase
// Tell the Reader that we want to use the Read Filter that we've Instantiated // Tell the Reader that we want to use the Read Filter that we've Instantiated
// and that we want to store it in contiguous rows/columns // and that we want to store it in contiguous rows/columns
self::assertFalse($reader->getContiguous()); self::assertFalse($reader->getContiguous());
$reader->setReadFilter($chunkFilter) $reader->setReadFilter($chunkFilter);
->setContiguous(true); $reader->setContiguous(true);
// Instantiate a new PhpSpreadsheet object manually // Instantiate a new PhpSpreadsheet object manually
$spreadsheet = new Spreadsheet(); $spreadsheet = new Spreadsheet();
@ -65,8 +65,8 @@ class CsvContiguousTest extends TestCase
// Tell the Reader that we want to use the Read Filter that we've Instantiated // Tell the Reader that we want to use the Read Filter that we've Instantiated
// and that we want to store it in contiguous rows/columns // and that we want to store it in contiguous rows/columns
$reader->setReadFilter($chunkFilter) $reader->setReadFilter($chunkFilter);
->setContiguous(true); $reader->setContiguous(true);
// Instantiate a new PhpSpreadsheet object manually // Instantiate a new PhpSpreadsheet object manually
$spreadsheet = new Spreadsheet(); $spreadsheet = new Spreadsheet();

View File

@ -23,7 +23,6 @@ class XmlScannerTest extends TestCase
* *
* @param mixed $filename * @param mixed $filename
* @param mixed $expectedResult * @param mixed $expectedResult
* @param $libxmlDisableEntityLoader
*/ */
public function testValidXML($filename, $expectedResult, $libxmlDisableEntityLoader): void public function testValidXML($filename, $expectedResult, $libxmlDisableEntityLoader): void
{ {
@ -59,7 +58,6 @@ class XmlScannerTest extends TestCase
* @dataProvider providerInvalidXML * @dataProvider providerInvalidXML
* *
* @param mixed $filename * @param mixed $filename
* @param $libxmlDisableEntityLoader
*/ */
public function testInvalidXML($filename, $libxmlDisableEntityLoader): void public function testInvalidXML($filename, $libxmlDisableEntityLoader): void
{ {

View File

@ -250,7 +250,6 @@ class XlsxTest extends TestCase
* Test if all whitespace is removed from a style definition string. * Test if all whitespace is removed from a style definition string.
* This is needed to parse it into properties with the correct keys. * This is needed to parse it into properties with the correct keys.
* *
* @param $string
* @dataProvider providerStripsWhiteSpaceFromStyleString * @dataProvider providerStripsWhiteSpaceFromStyleString
*/ */
public function testStripsWhiteSpaceFromStyleString($string): void public function testStripsWhiteSpaceFromStyleString($string): void

View File

@ -10,8 +10,6 @@ class XmlTest extends TestCase
{ {
/** /**
* @dataProvider providerInvalidSimpleXML * @dataProvider providerInvalidSimpleXML
*
* @param $filename
*/ */
public function testInvalidSimpleXML($filename): void public function testInvalidSimpleXML($filename): void
{ {

View File

@ -44,9 +44,6 @@ class SpreadsheetTest extends TestCase
} }
/** /**
* @param $index
* @param $sheetName
*
* @dataProvider dataProviderForSheetNames * @dataProvider dataProviderForSheetNames
*/ */
public function testGetSheetByName($index, $sheetName): void public function testGetSheetByName($index, $sheetName): void

View File

@ -0,0 +1,74 @@
<?php
return [
[
[
1,
1,
],
'A1',
],
[
[
1,
12,
],
'A12',
],
[
[
10,
1,
],
'J1',
],
[
[
10,
20,
],
'J20',
],
[
[
35,
1,
],
'AI1',
],
[
[
35,
2012,
],
'AI2012',
],
[
[
2,
3,
],
'B3',
],
[
[
2,
3,
],
'$B3',
],
[
[
2,
3,
],
'B$3',
],
[
[
2,
3,
],
'$B$3',
],
];

View File

@ -43,4 +43,32 @@ return [
], ],
'AI2012', 'AI2012',
], ],
[
[
'B',
3,
],
'B3',
],
[
[
'$B',
3,
],
'$B3',
],
[
[
'B',
'$3',
],
'B$3',
],
[
[
'$B',
'$3',
],
'$B$3',
],
]; ];