Data validation controls what users can enter into cells, helping prevent errors and standardize data entry. PhpSpreadsheet supports all Excel data validation types including dropdown lists, number ranges, date restrictions, and custom formulas.
Get the data validation object for a cell and configure its properties:
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;$worksheet->setCellValue('B3', 10);$validation = $worksheet->getCell('B3')->getDataValidation();$validation->setType(DataValidation::TYPE_WHOLE);$validation->setErrorStyle(DataValidation::STYLE_STOP);$validation->setAllowBlank(true);$validation->setShowInputMessage(true);$validation->setShowErrorMessage(true);$validation->setErrorTitle('Input error');$validation->setError('Only numbers between 10 and 20 are allowed!');$validation->setPromptTitle('Allowed input');$validation->setPrompt('Only numbers between 10 and 20 are allowed.');$validation->setFormula1('10'); // Minimum$validation->setFormula2('20'); // Maximum
$validation->setType(DataValidation::TYPE_WHOLE);$validation->setOperator(DataValidation::OPERATOR_BETWEEN);$validation->setFormula1('1'); // Minimum$validation->setFormula2('100'); // Maximum
$validation->setType(DataValidation::TYPE_DECIMAL);$validation->setOperator(DataValidation::OPERATOR_BETWEEN);$validation->setFormula1('0');$validation->setFormula2('1');$validation->setPrompt('Enter a number between 0 and 1');
$validation->setType(DataValidation::TYPE_LIST);$validation->setErrorStyle(DataValidation::STYLE_INFORMATION);$validation->setAllowBlank(false);$validation->setShowDropDown(true);$validation->setShowInputMessage(true);$validation->setShowErrorMessage(true);$validation->setErrorTitle('Input error');$validation->setError('Value is not in list.');$validation->setPromptTitle('Pick from list');$validation->setPrompt('Please pick a value from the drop-down list.');// IMPORTANT: Wrap the list in quotes$validation->setFormula1('"Item A,Item B,Item C"');
// First, set up the list values in cells$worksheet->setCellValue('D2', 'Item #1');$worksheet->setCellValue('D3', 'Item #2');$worksheet->setCellValue('D4', 'Item #3');$worksheet->setCellValue('D5', 'Item #4');$worksheet->setCellValue('D6', 'Item #5');// Reference the range (no quotes!)$validation->setType(DataValidation::TYPE_LIST);$validation->setShowDropDown(true);$validation->setFormula1('$D$2:$D$6');
use PhpOffice\PhpSpreadsheet\NamedRange;// Create named range$spreadsheet->addNamedRange( new NamedRange('StatusList', $worksheet, '=$D$2:$D$6'));// Use in validation$validation->setType(DataValidation::TYPE_LIST);$validation->setShowDropDown(true);$validation->setFormula1('StatusList');
When using a comma-separated list, you must wrap it in quotes: '"Item A,Item B,Item C"'When using a cell range or named range, do not use quotes: '$D$2:$D$6'
$validation->setType(DataValidation::TYPE_DATE);$validation->setOperator(DataValidation::OPERATOR_BETWEEN);$validation->setFormula1('2024-01-01');$validation->setFormula2('2024-12-31');$validation->setErrorTitle('Invalid Date');$validation->setError('Please enter a date in 2024.');
$validation->setType(DataValidation::TYPE_TIME);$validation->setOperator(DataValidation::OPERATOR_BETWEEN);$validation->setFormula1('09:00');$validation->setFormula2('17:00');$validation->setPrompt('Enter a time between 9 AM and 5 PM.');
$validation->setType(DataValidation::TYPE_TEXTLENGTH);$validation->setOperator(DataValidation::OPERATOR_LESSTHANOREQUAL);$validation->setFormula1('10');$validation->setError('Text must be 10 characters or less.');
// Validate that cell is unique in column$validation->setType(DataValidation::TYPE_CUSTOM);$validation->setFormula1('=COUNTIF($A:$A,A1)=1');$validation->setError('Value must be unique in this column.');// Validate that cell starts with specific text$validation->setType(DataValidation::TYPE_CUSTOM);$validation->setFormula1('=LEFT(A1,3)="SKU"');$validation->setError('Value must start with "SKU".');
$validation->setShowInputMessage(true);$validation->setPromptTitle('Enter Your Age');$validation->setPrompt('Please enter your age as a whole number.');
$validation->setShowErrorMessage(true);$validation->setErrorTitle('Invalid Input');$validation->setError('The value you entered is not valid. Please try again.');
// Set validation on first cell$validation = $worksheet->getCell('A1')->getDataValidation();$validation->setType(DataValidation::TYPE_WHOLE);$validation->setFormula1('1');$validation->setFormula2('100');// Copy to other cellsfor ($row = 2; $row <= 10; $row++) { $worksheet->getCell("A{$row}") ->setDataValidation(clone $validation);}
Or use the worksheet method:
$validation = new DataValidation();$validation->setType(DataValidation::TYPE_LIST);$validation->setFormula1('"Yes,No,Maybe"');// Apply to range$worksheet->setDataValidation('B2:B100', $validation);
use PhpOffice\PhpSpreadsheet\Cell\DataValidator;$cell = $worksheet->getCell('B3');if ($cell->hasValidValue()) { echo "Cell value is valid";} else { echo "Cell value is invalid";}// Or use DataValidator directly$validator = new DataValidator();if ($validator->isValid($cell)) { echo "Valid";}
$validation = $worksheet->getCell('A1')->getDataValidation();$validation->setType(DataValidation::TYPE_CUSTOM);$validation->setFormula1('=AND(FIND("@",A1)>0, FIND(".",A1)>FIND("@",A1))');$validation->setErrorStyle(DataValidation::STYLE_STOP);$validation->setError('Please enter a valid email address.');
// List expands as you add items$validation = $worksheet->getCell('A1')->getDataValidation();$validation->setType(DataValidation::TYPE_LIST);$validation->setFormula1('=OFFSET($D$1,0,0,COUNTA($D:$D),1)');
$validation = $worksheet->getCell('A1')->getDataValidation();$validation->setType(DataValidation::TYPE_DECIMAL);$validation->setOperator(DataValidation::OPERATOR_BETWEEN);$validation->setFormula1('0');$validation->setFormula2('1');$validation->setPrompt('Enter a value between 0% and 100%');// Format cell as percentage$worksheet->getStyle('A1') ->getNumberFormat() ->setFormatCode('0%');
Always set both prompt and error messages to guide users:
$validation->setShowInputMessage(true);$validation->setPromptTitle('Date Required');$validation->setPrompt('Please enter a date in the format YYYY-MM-DD');$validation->setShowErrorMessage(true);$validation->setErrorTitle('Invalid Date');$validation->setError('The date must be in YYYY-MM-DD format.');
2
Choose Appropriate Error Styles
Use STYLE_STOP for critical validations (IDs, required fields)
Use STYLE_WARNING for important but not critical validations
Use STYLE_INFORMATION for suggestions and optional guidelines
3
Use Cell Ranges for Long Lists
Instead of hardcoding long lists in Formula1, maintain them in cells:
// Better: maintainable list$validation->setFormula1('$Z$1:$Z$100');// Avoid: hardcoded long list$validation->setFormula1('"Item1,Item2,Item3,Item4,...,Item100"');
4
Test Validation Rules
After creating validation rules, test them:
$cell = $worksheet->getCell('A1');$cell->setValue('test value');if (!$cell->hasValidValue()) { echo "Validation rule is working correctly!";}