mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-16 13:06:31 +00:00
String Value Binder Allow Setting "Ignore Number Stored As Text"
When String Value Binder converts a numeric value to text, the resulting spreadsheet will be full of little green triangles to indicate to the end user that something might be wrong. It is unlikely that a spreadsheet created in this manner needs that visual clutter. This PR adds a property and setter (I can't really think of a good use case for a getter) to suppress it. Suppression should arguably be the default, but, for now, I will avoid any BC problems by leaving non-suppression as the default.
This commit is contained in:
@@ -551,6 +551,7 @@ By default, the StringValueBinder will cast any datatype passed to it into a str
|
||||
// Set value binder
|
||||
$stringValueBinder = new \PhpOffice\PhpSpreadsheet\Cell\StringValueBinder();
|
||||
$stringValueBinder->setNumericConversion(false)
|
||||
->setSetIgnoredErrors(true) // suppresses "number stored as text" indicators
|
||||
->setBooleanConversion(false)
|
||||
->setNullConversion(false)
|
||||
->setFormulaConversion(false);
|
||||
|
||||
@@ -18,6 +18,15 @@ class StringValueBinder extends DefaultValueBinder implements IValueBinder
|
||||
|
||||
protected bool $convertFormula = true;
|
||||
|
||||
protected bool $setIgnoredErrors = false;
|
||||
|
||||
public function setSetIgnoredErrors(bool $setIgnoredErrors = false): self
|
||||
{
|
||||
$this->setIgnoredErrors = $setIgnoredErrors;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNullConversion(bool $suppressConversion = false): self
|
||||
{
|
||||
$this->convertNull = $suppressConversion;
|
||||
@@ -90,6 +99,9 @@ class StringValueBinder extends DefaultValueBinder implements IValueBinder
|
||||
} elseif (is_string($value) && strlen($value) > 1 && $value[0] === '=' && $this->convertFormula === false && parent::dataTypeForValue($value) === DataType::TYPE_FORMULA) {
|
||||
$cell->setValueExplicit($value, DataType::TYPE_FORMULA);
|
||||
} else {
|
||||
if ($this->setIgnoredErrors && is_numeric($value)) {
|
||||
$cell->getIgnoredErrors()->setNumberStoredAsText(true);
|
||||
}
|
||||
$cell->setValueExplicit((string) $value, DataType::TYPE_STRING);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\IValueBinder;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\StringValueBinder;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StringValueBinder2Test extends TestCase
|
||||
{
|
||||
private IValueBinder $valueBinder;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->valueBinder = Cell::getValueBinder();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Cell::setValueBinder($this->valueBinder);
|
||||
}
|
||||
|
||||
public function testStringValueBinderIgnoredErrorsDefault(): void
|
||||
{
|
||||
$valueBinder = new StringValueBinder();
|
||||
Cell::setValueBinder($valueBinder);
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->fromArray([
|
||||
[1, 'x', 3.2],
|
||||
['y', -5, 'z'],
|
||||
]);
|
||||
$ignoredCells = [];
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$coordinate = $cell->getCoordinate();
|
||||
self::assertSame(DataType::TYPE_STRING, $cell->getDataType(), "not string for cell $coordinate");
|
||||
if ($cell->getIgnoredErrors()->getNumberStoredAsText()) {
|
||||
$ignoredCells[] = $coordinate;
|
||||
}
|
||||
}
|
||||
}
|
||||
self::assertSame([], $ignoredCells);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testStringValueBinderIgnoredErrorsTrue(): void
|
||||
{
|
||||
$valueBinder = new StringValueBinder();
|
||||
$valueBinder->setSetIgnoredErrors(true);
|
||||
Cell::setValueBinder($valueBinder);
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->fromArray([
|
||||
[1, 'x', 3.2],
|
||||
['y', -5, 'z'],
|
||||
]);
|
||||
$ignoredCells = [];
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$coordinate = $cell->getCoordinate();
|
||||
self::assertSame(DataType::TYPE_STRING, $cell->getDataType(), "not string for cell $coordinate");
|
||||
if ($cell->getIgnoredErrors()->getNumberStoredAsText()) {
|
||||
$ignoredCells[] = $coordinate;
|
||||
}
|
||||
}
|
||||
}
|
||||
self::assertSame(['A1', 'C1', 'B2'], $ignoredCells);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testStringValueBinderPreserveNumeric(): void
|
||||
{
|
||||
$valueBinder = new StringValueBinder();
|
||||
$valueBinder->setNumericConversion(false);
|
||||
$valueBinder->setSetIgnoredErrors(true);
|
||||
Cell::setValueBinder($valueBinder);
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->fromArray([
|
||||
[1, 'x', 3.2],
|
||||
['y', -5, 'z'],
|
||||
]);
|
||||
$ignoredCells = [];
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$coordinate = $cell->getCoordinate();
|
||||
$expected = is_numeric($cell->getValue()) ? DataType::TYPE_NUMERIC : DataType::TYPE_STRING;
|
||||
self::assertSame($expected, $cell->getDataType(), "wrong type for cell $coordinate");
|
||||
if ($cell->getIgnoredErrors()->getNumberStoredAsText()) {
|
||||
$ignoredCells[] = $coordinate;
|
||||
}
|
||||
}
|
||||
}
|
||||
self::assertSame([], $ignoredCells);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user