提交的内容

This commit is contained in:
2025-05-12 15:45:02 +08:00
parent 629c4750da
commit b48c692775
3043 changed files with 34732 additions and 60810 deletions

View File

@ -75,14 +75,11 @@ class ReferenceHelper
*
* @return int
*/
public static function columnReverseSort($a, $b)
public static function columnReverseSort(string $a, string $b)
{
return -strcasecmp(strlen($a) . $a, strlen($b) . $b);
}
/** @var int */
private static $scrutinizer0 = 0;
/**
* Compare two cell addresses
* Intended for use as a Callback function for sorting cell addresses by column and row.
@ -92,16 +89,16 @@ class ReferenceHelper
*
* @return int
*/
public static function cellSort($a, $b)
public static function cellSort(string $a, string $b)
{
$ac = $bc = '';
$ar = self::$scrutinizer0;
$br = 0;
/** @scrutinizer be-damned */
sscanf($a, '%[A-Z]%d', $ac, $ar);
/** @var int $ar */
/** @var string $ac */
/** @scrutinizer be-damned */
sscanf($b, '%[A-Z]%d', $bc, $br);
$ac = (string) $ac;
$bc = (string) $bc;
/** @var int $br */
/** @var string $bc */
if ($ar === $br) {
return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);
}
@ -118,16 +115,16 @@ class ReferenceHelper
*
* @return int
*/
public static function cellReverseSort($a, $b)
public static function cellReverseSort(string $a, string $b)
{
$ac = $bc = '';
$ar = self::$scrutinizer0;
$br = 0;
/** @scrutinizer be-damned */
sscanf($a, '%[A-Z]%d', $ac, $ar);
/** @var int $ar */
/** @var string $ac */
/** @scrutinizer be-damned */
sscanf($b, '%[A-Z]%d', $bc, $br);
$ac = (string) $ac;
$bc = (string) $bc;
/** @var int $br */
/** @var string $bc */
if ($ar === $br) {
return -strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);
}
@ -142,7 +139,7 @@ class ReferenceHelper
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
*/
protected function adjustPageBreaks(Worksheet $worksheet, $numberOfColumns, $numberOfRows): void
protected function adjustPageBreaks(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
{
$aBreaks = $worksheet->getBreaks();
($numberOfColumns > 0 || $numberOfRows > 0)
@ -171,7 +168,7 @@ class ReferenceHelper
*
* @param Worksheet $worksheet The worksheet that we're editing
*/
protected function adjustComments($worksheet): void
protected function adjustComments(Worksheet $worksheet): void
{
$aComments = $worksheet->getComments();
$aNewComments = []; // the new array of all comments
@ -195,7 +192,7 @@ class ReferenceHelper
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
*/
protected function adjustHyperlinks($worksheet, $numberOfColumns, $numberOfRows): void
protected function adjustHyperlinks(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
{
$aHyperlinkCollection = $worksheet->getHyperlinkCollection();
($numberOfColumns > 0 || $numberOfRows > 0)
@ -220,7 +217,7 @@ class ReferenceHelper
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
*/
protected function adjustConditionalFormatting($worksheet, $numberOfColumns, $numberOfRows): void
protected function adjustConditionalFormatting(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
{
$aStyles = $worksheet->getConditionalStylesCollection();
($numberOfColumns > 0 || $numberOfRows > 0)
@ -259,7 +256,7 @@ class ReferenceHelper
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
*/
protected function adjustDataValidations(Worksheet $worksheet, $numberOfColumns, $numberOfRows): void
protected function adjustDataValidations(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
{
$aDataValidationCollection = $worksheet->getDataValidationCollection();
($numberOfColumns > 0 || $numberOfRows > 0)
@ -299,7 +296,7 @@ class ReferenceHelper
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
*/
protected function adjustProtectedCells(Worksheet $worksheet, $numberOfColumns, $numberOfRows): void
protected function adjustProtectedCells(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
{
$aProtectedCells = $worksheet->getProtectedCells();
($numberOfColumns > 0 || $numberOfRows > 0)
@ -412,7 +409,7 @@ class ReferenceHelper
$cellCollection = $worksheet->getCellCollection();
$missingCoordinates = array_filter(
array_map(function ($row) use ($highestColumn) {
return $highestColumn . $row;
return "{$highestColumn}{$row}";
}, range(1, $highestRow)),
function ($coordinate) use ($cellCollection) {
return $cellCollection->has($coordinate) === false;
@ -453,9 +450,9 @@ class ReferenceHelper
if ($cell->getDataType() === DataType::TYPE_FORMULA) {
// Formula should be adjusted
$worksheet->getCell($newCoordinate)
->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle()));
->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle(), true));
} else {
// Formula should not be adjusted
// Cell value should not be adjusted
$worksheet->getCell($newCoordinate)->setValueExplicit($cell->getValue(), $cell->getDataType());
}
@ -463,10 +460,10 @@ class ReferenceHelper
$worksheet->getCellCollection()->delete($coordinate);
} else {
/* We don't need to update styles for rows/columns before our insertion position,
but we do still need to adjust any formulae in those cells */
but we do still need to adjust any formulae in those cells */
if ($cell->getDataType() === DataType::TYPE_FORMULA) {
// Formula should be adjusted
$cell->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle()));
$cell->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle(), true));
}
}
}
@ -609,7 +606,7 @@ class ReferenceHelper
// 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;
$row = 10000000 + (int) trim($match[3], '$');
$cellIndex = $column . $row;
$cellIndex = "{$column}{$row}";
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
$cellTokens[$cellIndex] = '/(?<!\d\$\!)' . preg_quote($fromString, '/') . '(?!\d)/i';
@ -634,7 +631,7 @@ class ReferenceHelper
// 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($match[3], '$')) + 100000;
$row = 10000000;
$cellIndex = $column . $row;
$cellIndex = "{$column}{$row}";
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
$cellTokens[$cellIndex] = '/(?<![A-Z\$\!])' . preg_quote($fromString, '/') . '(?![A-Z])/i';
@ -660,7 +657,7 @@ class ReferenceHelper
// 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;
$row = (int) trim($row, '$') + 10000000;
$cellIndex = $column . $row;
$cellIndex = "{$column}{$row}";
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
$cellTokens[$cellIndex] = '/(?<![A-Z]\$\!)' . preg_quote($fromString, '/') . '(?!\d)/i';
@ -916,21 +913,35 @@ class ReferenceHelper
{
$cellAddress = $definedName->getValue();
$asFormula = ($cellAddress[0] === '=');
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) {
/**
* If we delete the entire range that is referenced by a Named Range, MS Excel sets the value to #REF!
* PhpSpreadsheet still only does a basic adjustment, so the Named Range will still reference Cells.
* Note that this applies only when deleting columns/rows; subsequent insertion won't fix the #REF!
* TODO Can we work out a method to identify Named Ranges that cease to be valid, so that we can replace
* them with a #REF!
*/
if ($asFormula === true) {
$formula = $this->updateFormulaReferences($cellAddress, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$formula = $this->updateFormulaReferences($cellAddress, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle(), true);
$definedName->setValue($formula);
} else {
$definedName->setValue($this->updateCellReference(ltrim($cellAddress, '=')));
$definedName->setValue($this->updateCellReference(ltrim($cellAddress, '='), true));
}
}
}
private function updateNamedFormula(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) {
/**
* If we delete the entire range that is referenced by a Named Formula, MS Excel sets the value to #REF!
* PhpSpreadsheet still only does a basic adjustment, so the Named Formula will still reference Cells.
* Note that this applies only when deleting columns/rows; subsequent insertion won't fix the #REF!
* TODO Can we work out a method to identify Named Ranges that cease to be valid, so that we can replace
* them with a #REF!
*/
$formula = $definedName->getValue();
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle(), true);
$definedName->setValue($formula);
}
}