Sample Submitted by @jr212

Address sample code submitted by @jr212 which was not working correctly.
This commit is contained in:
oleibman
2024-04-19 00:04:27 -07:00
parent b53a4b7602
commit 61f24ca099
3 changed files with 46 additions and 4 deletions
+12
View File
@@ -361,6 +361,18 @@ class Cell implements Stringable
$result = array_shift($result);
}
}
// if return_as_array for formula like '=sheet!cell'
if (is_array($result) && count($result) === 1) {
$resultKey = array_keys($result)[0];
$resultValue = $result[$resultKey];
if (is_int($resultKey) && is_array($resultValue) && count($resultValue) === 1) {
$resultKey2 = array_keys($resultValue)[0];
$resultValue2 = $resultValue[$resultKey2];
if (is_string($resultKey2) && !is_array($resultValue2) && preg_match('/[a-zA-Z]{1,3}/', $resultKey2) === 1) {
$result = $resultValue2;
}
}
}
} catch (SpreadsheetException $ex) {
if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) {
return $this->calculatedValue; // Fallback for calculations referencing external files.
@@ -107,7 +107,7 @@ class Formatter extends BaseFormatter
/**
* Convert a value in a pre-defined format to a PHP string.
*
* @param null|bool|float|int|RichText|string $value Value to format
* @param null|array|bool|float|int|RichText|string $value Value to format
* @param string $format Format code: see = self::FORMAT_* for predefined values;
* or can be any valid MS Excel custom format string
* @param ?array $callBack Callback function for additional formatting of string
@@ -116,6 +116,9 @@ class Formatter extends BaseFormatter
*/
public static function toFormattedString($value, string $format, ?array $callBack = null): string
{
while (is_array($value)) {
$value = array_shift($value);
}
if (is_bool($value)) {
return $value ? Calculation::getTRUE() : Calculation::getFALSE();
}
+30 -3
View File
@@ -1402,7 +1402,12 @@ class Worksheet extends WriterPart
}
$attributes = $cell->getFormulaAttributes() ?? [];
$ref = array_key_exists('ref', $attributes) ? $attributes['ref'] : $cell->getCoordinate();
$coordinate = $cell->getCoordinate();
if (isset($attributes['ref'])) {
$ref = $this->parseRef($coordinate, $attributes['ref']);
} else {
$ref = $coordinate;
}
if (is_array($calculatedValue)) {
$attributes['t'] = 'array';
$rows = max(1, count($calculatedValue));
@@ -1410,11 +1415,11 @@ class Worksheet extends WriterPart
foreach ($calculatedValue as $row) {
$cols = max($cols, is_array($row) ? count($row) : 1);
}
$firstCellArray = Coordinate::indexesFromString($ref);
$firstCellArray = Coordinate::indexesFromString($coordinate);
$lastRow = $firstCellArray[1] + $rows - 1;
$lastColumn = $firstCellArray[0] + $cols - 1;
$lastColumnString = Coordinate::stringFromColumnIndex($lastColumn);
$ref .= ":$lastColumnString$lastRow";
$ref = "$coordinate:$lastColumnString$lastRow";
}
if (($attributes['t'] ?? null) === 'array') {
$objWriter->startElement('f');
@@ -1449,6 +1454,28 @@ class Worksheet extends WriterPart
}
}
private function parseRef(string $coordinate, string $ref): string
{
if (preg_match('/^([A-Z]{1,3})([0-9]{1,7})(:([A-Z]{1,3})([0-9]{1,7}))?$/', $ref, $matches) !== 1) {
return $ref;
}
if (!isset($matches[3])) { // single cell, not range
return $coordinate;
}
$minRow = (int) $matches[2];
$maxRow = (int) $matches[5];
$rows = $maxRow - $minRow + 1;
$minCol = Coordinate::columnIndexFromString($matches[1]);
$maxCol = Coordinate::columnIndexFromString($matches[4]);
$cols = $maxCol - $minCol + 1;
$firstCellArray = Coordinate::indexesFromString($coordinate);
$lastRow = $firstCellArray[1] + $rows - 1;
$lastColumn = $firstCellArray[0] + $cols - 1;
$lastColumnString = Coordinate::stringFromColumnIndex($lastColumn);
return "$coordinate:$lastColumnString$lastRow";
}
/**
* Write Cell.
*