Skip to content

Commit

Permalink
Merge branch 'master' into issue3754
Browse files Browse the repository at this point in the history
  • Loading branch information
oleibman authored Nov 7, 2023
2 parents 86031b3 + 98b5c77 commit 3d00d2b
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 62 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Break Some Circular References. [PR #3716](https://github.com/PHPOffice/PhpSpreadsheet/pull/3716) [PR #3707](https://github.com/PHPOffice/PhpSpreadsheet/pull/3707)
- Missing Font Index in Some Xls. [PR #3734](https://github.com/PHPOffice/PhpSpreadsheet/pull/3734)
- Load Tables even with READ_DATA_ONLY. [PR #3726](https://github.com/PHPOffice/PhpSpreadsheet/pull/3726)
- Theme File Missing but Referenced in Spreadsheet. [Issue #3770](https://github.com/PHPOffice/PhpSpreadsheet/issues/3770) [PR #3772](https://github.com/PHPOffice/PhpSpreadsheet/pull/3772)
- Slk Shared Formulas. [Issue #2267](https://github.com/PHPOffice/PhpSpreadsheet/issues/2267) [PR #3776](https://github.com/PHPOffice/PhpSpreadsheet/pull/3776)

## 1.29.0 - 2023-06-15

Expand Down
51 changes: 23 additions & 28 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion samples/Chart/33_Chart_create_line_dateaxis.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ function dateRange(int $nrows, Spreadsheet $wrkbk): array
$lastYr = (int) $lastDate->format('Y');
$qtr = intdiv($lastMonth, 3) + (($lastMonth % 3 > 0) ? 1 : 0);
$qtrEndMonth = 3 + (($qtr - 1) * 3);
$lastDOM = cal_days_in_month(CAL_GREGORIAN, $qtrEndMonth, $lastYr);
$qtrEndMonth = sprintf('%02d', $qtrEndMonth);
$lastDOM = DateTime::createFromFormat('Y-m-d', "$lastYr-$qtrEndMonth-01")->format('t');
$qtrEndStr = "$lastYr-$qtrEndMonth-$lastDOM";
$ExcelQtrEndDateVal = SharedDate::convertIsoDate($qtrEndStr);

Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Calculation/Calculation.php
Original file line number Diff line number Diff line change
Expand Up @@ -4409,7 +4409,7 @@ private function internalParseFormula($formula, ?Cell $cell = null): bool|array
[$rangeWS2, $val] = Worksheet::extractSheetTitle($val, true);
if ($rangeWS2 !== '') {
$rangeWS2 .= '!';
} else { // @phpstan-ignore-line
} else {
$rangeWS2 = $rangeWS1;
}

Expand Down
55 changes: 37 additions & 18 deletions src/PhpSpreadsheet/Reader/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class Csv extends BaseReader
Expand Down Expand Up @@ -102,6 +101,14 @@ class Csv extends BaseReader
/** @var bool */
private $sheetNameIsFileName = false;

private string $getTrue = 'true';

private string $getFalse = 'false';

private string $thousandsSeparator = ',';

private string $decimalSeparator = '.';

/**
* Create a new CSV Reader instance.
*/
Expand Down Expand Up @@ -234,13 +241,14 @@ public function listWorksheetInfo(string $filename): array
$worksheetInfo[0]['lastColumnIndex'] = 0;
$worksheetInfo[0]['totalRows'] = 0;
$worksheetInfo[0]['totalColumns'] = 0;
$delimiter = $this->delimiter ?? '';

// Loop through each line of the file in turn
$rowData = fgetcsv($fileHandle, 0, $this->delimiter ?? '', $this->enclosure, $this->escapeCharacter);
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
while (is_array($rowData)) {
++$worksheetInfo[0]['totalRows'];
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
$rowData = fgetcsv($fileHandle, 0, $this->delimiter ?? '', $this->enclosure, $this->escapeCharacter);
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
}

$worksheetInfo[0]['lastColumnLetter'] = Coordinate::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex'] + 1);
Expand Down Expand Up @@ -386,15 +394,24 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
$outRow = 0;

// Loop through each line of the file in turn
$rowData = fgetcsv($fileHandle, 0, $this->delimiter ?? '', $this->enclosure, $this->escapeCharacter);
$delimiter = $this->delimiter ?? '';
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
$valueBinder = Cell::getValueBinder();
$preserveBooleanString = method_exists($valueBinder, 'getBooleanConversion') && $valueBinder->getBooleanConversion();
$this->getTrue = Calculation::getTRUE();
$this->getFalse = Calculation::getFALSE();
$this->thousandsSeparator = StringHelper::getThousandsSeparator();
$this->decimalSeparator = StringHelper::getDecimalSeparator();
while (is_array($rowData)) {
$noOutputYet = true;
$columnLetter = 'A';
foreach ($rowData as $rowDatum) {
$this->convertBoolean($rowDatum, $preserveBooleanString);
$numberFormatMask = $this->convertFormattedNumber($rowDatum);
if ($preserveBooleanString) {
$rowDatum = $rowDatum ?? '';
} else {
$this->convertBoolean($rowDatum);
}
$numberFormatMask = $this->castFormattedNumberToNumeric ? $this->convertFormattedNumber($rowDatum) : '';
if (($rowDatum !== '' || $this->preserveNullString) && $this->readFilter->readCell($columnLetter, $currentRow)) {
if ($this->contiguous) {
if ($noOutputYet) {
Expand All @@ -405,15 +422,17 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
$outRow = $currentRow;
}
// Set basic styling for the value (Note that this could be overloaded by styling in a value binder)
$sheet->getCell($columnLetter . $outRow)->getStyle()
->getNumberFormat()
->setFormatCode($numberFormatMask);
if ($numberFormatMask !== '') {
$sheet->getStyle($columnLetter . $outRow)
->getNumberFormat()
->setFormatCode($numberFormatMask);
}
// Set cell value
$sheet->getCell($columnLetter . $outRow)->setValue($rowDatum);
}
++$columnLetter;
}
$rowData = fgetcsv($fileHandle, 0, $this->delimiter ?? '', $this->enclosure, $this->escapeCharacter);
$rowData = fgetcsv($fileHandle, 0, $delimiter, $this->enclosure, $this->escapeCharacter);
++$currentRow;
}

Expand All @@ -429,12 +448,12 @@ private function loadStringOrFile(string $filename, Spreadsheet $spreadsheet, bo
/**
* Convert string true/false to boolean, and null to null-string.
*/
private function convertBoolean(mixed &$rowDatum, bool $preserveBooleanString): void
private function convertBoolean(mixed &$rowDatum): void
{
if (is_string($rowDatum) && !$preserveBooleanString) {
if (strcasecmp(Calculation::getTRUE(), $rowDatum) === 0 || strcasecmp('true', $rowDatum) === 0) {
if (is_string($rowDatum)) {
if (strcasecmp($this->getTrue, $rowDatum) === 0 || strcasecmp('true', $rowDatum) === 0) {
$rowDatum = true;
} elseif (strcasecmp(Calculation::getFALSE(), $rowDatum) === 0 || strcasecmp('false', $rowDatum) === 0) {
} elseif (strcasecmp($this->getFalse, $rowDatum) === 0 || strcasecmp('false', $rowDatum) === 0) {
$rowDatum = false;
}
} else {
Expand All @@ -447,18 +466,18 @@ private function convertBoolean(mixed &$rowDatum, bool $preserveBooleanString):
*/
private function convertFormattedNumber(mixed &$rowDatum): string
{
$numberFormatMask = NumberFormat::FORMAT_GENERAL;
$numberFormatMask = '';
if ($this->castFormattedNumberToNumeric === true && is_string($rowDatum)) {
$numeric = str_replace(
[StringHelper::getThousandsSeparator(), StringHelper::getDecimalSeparator()],
[$this->thousandsSeparator, $this->decimalSeparator],
['', '.'],
$rowDatum
);

if (is_numeric($numeric)) {
$decimalPos = strpos($rowDatum, StringHelper::getDecimalSeparator());
$decimalPos = strpos($rowDatum, $this->decimalSeparator);
if ($this->preserveNumericFormatting === true) {
$numberFormatMask = (str_contains($rowDatum, StringHelper::getThousandsSeparator()))
$numberFormatMask = (str_contains($rowDatum, $this->thousandsSeparator))
? '#,##0' : '0';
if ($decimalPos !== false) {
$decimals = strlen($rowDatum) - $decimalPos - 1;
Expand Down
32 changes: 30 additions & 2 deletions src/PhpSpreadsheet/Reader/Slk.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
Expand Down Expand Up @@ -269,14 +270,14 @@ private function processCRecord(array $rowData, Spreadsheet &$spreadsheet, strin
$hasCalculatedValue = false;
$tryNumeric = false;
$cellDataFormula = $cellData = '';
$sharedColumn = $sharedRow = -1;
$sharedFormula = false;
foreach ($rowData as $rowDatum) {
switch ($rowDatum[0]) {
case 'C':
case 'X':
$column = substr($rowDatum, 1);

break;
case 'R':
case 'Y':
$row = substr($rowDatum, 1);

Expand All @@ -298,9 +299,36 @@ private function processCRecord(array $rowData, Spreadsheet &$spreadsheet, strin
->getText()
->createText($comment);

break;
case 'C':
$sharedColumn = (int) substr($rowDatum, 1);

break;
case 'R':
$sharedRow = (int) substr($rowDatum, 1);

break;
case 'S':
$sharedFormula = true;

break;
}
}
if ($sharedFormula === true && $sharedRow >= 0 && $sharedColumn >= 0) {
$thisCoordinate = Coordinate::stringFromColumnIndex((int) $column) . $row;
$sharedCoordinate = Coordinate::stringFromColumnIndex($sharedColumn) . $sharedRow;
$formula = $spreadsheet->getActiveSheet()->getCell($sharedCoordinate)->getValue();
$spreadsheet->getActiveSheet()->getCell($thisCoordinate)->setValue($formula);
$referenceHelper = ReferenceHelper::getInstance();
$newFormula = $referenceHelper->updateFormulaReferences($formula, 'A1', (int) $column - $sharedColumn, (int) $row - $sharedRow, '', true, false);
$spreadsheet->getActiveSheet()->getCell($thisCoordinate)->setValue($newFormula);
//$calc = $spreadsheet->getActiveSheet()->getCell($thisCoordinate)->getCalculatedValue();
//$spreadsheet->getActiveSheet()->getCell($thisCoordinate)->setCalculatedValue($calc);
$cellData = Calculation::unwrapResult($cellData);
$spreadsheet->getActiveSheet()->getCell($thisCoordinate)->setCalculatedValue($cellData, $tryNumeric);

return;
}
$columnLetter = Coordinate::stringFromColumnIndex((int) $column);
$cellData = Calculation::unwrapResult($cellData);

Expand Down
3 changes: 3 additions & 0 deletions src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
}
switch ($rel['Type']) {
case "$xmlNamespaceBase/theme":
if (!$this->fileExistsInArchive($zip, "xl/{$relTarget}")) {
break; // issue3770
}
$themeOrderArray = ['lt1', 'dk1', 'lt2', 'dk2'];
$themeOrderAdditional = count($themeOrderArray);

Expand Down
3 changes: 1 addition & 2 deletions src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ public function stream_seek($offset, $whence): bool // @codingStandardsIgnoreLin
$this->pos = $offset;
} elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {
$this->pos += $offset;
// @phpstan-ignore-next-line
} elseif ($whence == SEEK_END && -$offset <= count($this->data)) {
} elseif ($whence == SEEK_END && -$offset <= count($this->data)) { // @phpstan-ignore-line
$this->pos = strlen($this->data) + $offset;
} else {
return false;
Expand Down
Loading

0 comments on commit 3d00d2b

Please sign in to comment.