Numeric strings → TYPE_NUMERIC (unless they have leading zeros)
Error codes → TYPE_ERROR
Everything else → TYPE_STRING
use PhpOffice\PhpSpreadsheet\Cell\Cell;use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;// This is the default, no need to set explicitlyCell::setValueBinder(new DefaultValueBinder());$sheet->setCellValue('A1', 42); // TYPE_NUMERIC$sheet->setCellValue('A2', '42'); // TYPE_NUMERIC$sheet->setCellValue('A3', '042'); // TYPE_STRING (leading zero)$sheet->setCellValue('A4', '=SUM(A1:A2)'); // TYPE_FORMULA
Percentages: Converts “10%” to 0.1 with percentage format
Fractions: Converts “3/4” to 0.75 with fraction format
Dates: Converts date strings to Excel timestamps with date format
Times: Converts “9:45” to time values with time format
Currency: Detects currency symbols and applies currency format
Scientific notation: Handles exponential format
Newlines: Applies wrap text style when \n is detected
use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;use PhpOffice\PhpSpreadsheet\Spreadsheet;$spreadsheet = new Spreadsheet();$spreadsheet->setValueBinder(new AdvancedValueBinder());// These are automatically converted:$sheet = $spreadsheet->getActiveSheet();$sheet->setCellValue('A1', '10%'); // → 0.1 with format "0%"$sheet->setCellValue('A2', '3/4'); // → 0.75 with format "?/?" $sheet->setCellValue('A3', '21 December 1983'); // → 30676 with date format$sheet->setCellValue('A4', '9:45'); // → 0.40625 with time format$sheet->setCellValue('A5', '$1,234.56'); // → 1234.56 with currency format$sheet->setCellValue('A6', "Line1\nLine2"); // String with wrap text enabled
The AdvancedValueBinder mimics MS Excel’s behavior for automatic data type detection.
The static Cell::setValueBinder() method is deprecated. Use the instance method instead.
// Old method (still works but deprecated)use PhpOffice\PhpSpreadsheet\Cell\Cell;use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;Cell::setValueBinder(new AdvancedValueBinder());$spreadsheet = new Spreadsheet();
Set the value binder per spreadsheet (available since 3.4.0):
use PhpOffice\PhpSpreadsheet\Spreadsheet;use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;$spreadsheet = new Spreadsheet();$spreadsheet->setValueBinder(new AdvancedValueBinder());
Override the value binder for individual cell operations:
use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;use PhpOffice\PhpSpreadsheet\Cell\StringValueBinder;$spreadsheet = new Spreadsheet();$spreadsheet->setValueBinder(new AdvancedValueBinder());$sheet = $spreadsheet->getActiveSheet();// This cell uses AdvancedValueBinder$sheet->getCell('A1')->setValue('12.5%');// Result: 0.125 with format mask '0.00%'// This cell overrides with StringValueBinder$sheet->getCell('A2')->setValue('12.5%', new StringValueBinder());// Result: '12.5%' as string with format mask 'General'
Implement the IValueBinder interface to create custom value binding logic:
use PhpOffice\PhpSpreadsheet\Cell\IValueBinder;use PhpOffice\PhpSpreadsheet\Cell\Cell;use PhpOffice\PhpSpreadsheet\Cell\DataType;use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;class MyCustomValueBinder extends DefaultValueBinder implements IValueBinder{ public function bindValue(Cell $cell, mixed $value): bool { // Custom logic here if (is_string($value) && str_starts_with($value, 'SKU-')) { // Treat SKUs as strings $cell->setValueExplicit($value, DataType::TYPE_STRING); return true; } // Fall back to parent for other types return parent::bindValue($cell, $value); }}// Use the custom binder$spreadsheet = new Spreadsheet();$spreadsheet->setValueBinder(new MyCustomValueBinder());
$cell = $sheet->getCell('A1');// Get the data type$dataType = $cell->getDataType();// Returns one of: 's', 'n', 'b', 'null', 'f', 'e', 'inlineStr'// Check if cell contains a formulaif ($cell->isFormula()) { echo "Cell contains a formula";}// Check if cell has data validationif ($cell->hasDataValidation()) { $validation = $cell->getDataValidation();}// Check if cell has a hyperlinkif ($cell->hasHyperlink()) { $hyperlink = $cell->getHyperlink();}
use PhpOffice\PhpSpreadsheet\RichText\RichText;$richText = new RichText();$richText->createText('This is ');$bold = $richText->createTextRun('bold');$bold->getFont()->setBold(true);$richText->createText(' and this is ');$italic = $richText->createTextRun('italic');$italic->getFont()->setItalic(true);$sheet->setCellValue('A1', $richText);// Get plain text from rich text cell$cell = $sheet->getCell('A1');if ($cell->getValue() instanceof RichText) { $plainText = $cell->getValue()->getPlainText();}