PhpSpreadsheet provides a powerful calculation engine that can evaluate Excel formulas. Formulas are stored as strings beginning with = and can reference other cells, use Excel functions, and perform complex calculations.
// Set a simple formula$sheet->setCellValue('A1', 10);$sheet->setCellValue('A2', 20);$sheet->setCellValue('A3', '=SUM(A1:A2)');// Formula with multiple functions$sheet->setCellValue('B1', '=IF(A1>5, A1*2, A1/2)');// Formula referencing other sheets$sheet->setCellValue('C1', '=Sheet2!A1 + Sheet2!B1');
$sheet->setCellValue('A1', 10);$sheet->setCellValue('A2', 20);$sheet->setCellValue('A3', '=SUM(A1:A2)');// Get the formula itself$formula = $sheet->getCell('A3')->getValue();// Returns: "=SUM(A1:A2)"// Calculate and get the result$result = $sheet->getCell('A3')->getCalculatedValue();// Returns: 30// Get as string$resultString = $sheet->getCell('A3')->getCalculatedValueString();// Returns: "30"
The calculation engine evaluates formulas when you call getCalculatedValue():
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;$sheet->setCellValue('E11', '=SUM(E4:E9)');// Calculate the formula$total = $sheet->getCell('E11')->getCalculatedValue();// Get calculation instance$calculation = Calculation::getInstance($spreadsheet);
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;// Disable calculation cache (forces recalculation every time)Calculation::getInstance($spreadsheet)->disableCalculationCache();// Clear cache without disablingCalculation::getInstance($spreadsheet)->clearCalculationCache();// Re-enable cacheCalculation::getInstance($spreadsheet)->enableCalculationCache();
The cache improves performance by storing calculated results, but you may need to clear it if underlying data changes.
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;$calculation = Calculation::getInstance($spreadsheet);// Get array formulas as arrays$calculation->setInstanceArrayReturnType( Calculation::RETURN_ARRAY_AS_ARRAY);// Get first value only (default)$calculation->setInstanceArrayReturnType( Calculation::RETURN_ARRAY_AS_VALUE);
PhpSpreadsheet automatically adjusts formulas when you insert or delete rows/columns:
$sheet->setCellValue('E4', 10);$sheet->setCellValue('E5', 20);$sheet->setCellValue('E6', 30);$sheet->setCellValue('E7', 40);$sheet->setCellValue('E8', 50);$sheet->setCellValue('E9', 60);$sheet->setCellValue('E11', '=SUM(E4:E9)');// Insert 2 new rows before row 7$sheet->insertNewRowBefore(7, 2);// Formula is now automatically adjusted to: =SUM(E4:E11)echo $sheet->getCell('E13')->getValue();
PhpSpreadsheet supports array formulas that return multiple values:
// Set an array formula$sheet->setCellValue('A1', '{=TRANSPOSE(B1:B5)}');// Set formula attributes for array formulas$cell = $sheet->getCell('A1');$cell->setFormulaAttributes([ 't' => 'array', 'ref' => 'A1:E1']);
Array formulas are enclosed in curly braces {} in Excel, but you set them without the braces in PhpSpreadsheet.
To store text beginning with = without treating it as a formula:
$sheet->setCellValue('A1', '=This is not a formula');// Mark as quote prefix to prevent evaluation$sheet->getCell('A1')->getStyle()->setQuotePrefix(true);// Now calling getCalculatedValue() returns the string as-isecho $sheet->getCell('A1')->getCalculatedValue();// Returns: "=This is not a formula"
use PhpOffice\PhpSpreadsheet\Calculation\Functions;// Return as PHP timestamp (default)Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);// Return as PHP DateTime objectFunctions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);// Return as Excel timestampFunctions::setReturnDateType(Functions::RETURNDATE_EXCEL);// Example usage$sheet->setCellValue('A1', '=TODAY()');$result = $sheet->getCell('A1')->getCalculatedValue();// Type depends on the return date type setting
use PhpOffice\PhpSpreadsheet\Shared\Date;// Set date values$sheet->setCellValue('A1', '2024-01-01');$sheet->setCellValue('A2', '2024-12-31');// Calculate difference in days$sheet->setCellValue('A3', '=DATEDIF(A1, A2, "d")');// Add months to a date $sheet->setCellValue('A4', '=EDATE(A1, 6)');// Extract date parts$sheet->setCellValue('A5', '=YEAR(A1)');$sheet->setCellValue('A6', '=MONTH(A1)');$sheet->setCellValue('A7', '=DAY(A1)');
When writing files, you can choose whether to calculate formulas:
use PhpOffice\PhpSpreadsheet\IOFactory;$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');// Calculate all formulas before saving (slower but ensures values are current)$writer->setPreCalculateFormulas(true);// Don't calculate (default) - Excel will calculate when file is opened$writer->setPreCalculateFormulas(false);$writer->save('output.xlsx');
If setPreCalculateFormulas(false), Excel will show “Calculating…” when opening the file as it recalculates all formulas.