A Named Range assigns a name to a cell or range of cells:
use PhpOffice\PhpSpreadsheet\NamedRange;$worksheet->setCellValue('B1', 0.19) // Tax rate: 19% ->setCellValue('B3', 12.99); // Net price// Define named ranges$spreadsheet->addNamedRange( new NamedRange('TAX_RATE', $worksheet, '=$B$1'));$spreadsheet->addNamedRange( new NamedRange('PRICE', $worksheet, '=$B$3'));// Use in formulas$worksheet->setCellValue('B4', '=PRICE*TAX_RATE') ->setCellValue('B5', '=PRICE*(1+TAX_RATE)');
Named ranges make formulas self-documenting. =PRICE*TAX_RATE is much clearer than =B3*B1.
Global named ranges are accessible from any worksheet:
// First worksheet$sheet1 = $spreadsheet->getActiveSheet();$sheet1->setCellValue('B1', 7.50);// Global named range (4th parameter is false or omitted)$spreadsheet->addNamedRange( new NamedRange('CHARGE_RATE', $sheet1, '=$B$1', false));// Second worksheet can use the same name$sheet2 = $spreadsheet->addSheet(new Worksheet($spreadsheet));$sheet2->setCellValue('A1', '=CHARGE_RATE*5');// This references Sheet1!B1
Local named ranges are only accessible from their specific worksheet:
$clients = ['Client A', 'Client B', 'Client C'];foreach ($clients as $clientName) { $sheet = $spreadsheet->addSheet(new Worksheet($spreadsheet, $clientName)); $sheet->setCellValue('B1', 7.50); // Default rate // Local scope (4th parameter is true) $spreadsheet->addNamedRange( new NamedRange('RATE', $sheet, '=$B$1', true) );}// Now each sheet has its own 'RATE' that points to its own B1$spreadsheet->getSheetByName('Client A') ->setCellValue('B1', 10.00); // Premium rate// Formulas on each sheet reference their sheet's own RATE
When resolving names, PhpSpreadsheet first looks for locally scoped names, then falls back to global names.
use PhpOffice\PhpSpreadsheet\NamedFormula;// Store tax rate as a formula$spreadsheet->addNamedFormula( new NamedFormula('TAX_RATE', $worksheet, '=19%'));// Store tax calculation$spreadsheet->addNamedFormula( new NamedFormula('TAX', $worksheet, '=PRICE*TAX_RATE'));// Define the price as a named range$spreadsheet->addNamedRange( new NamedRange('PRICE', $worksheet, '=$B$3'));// Use named formula in cells$worksheet->setCellValue('B1', '=TAX_RATE'); // Display rate$worksheet->setCellValue('B4', '=TAX'); // Calculate tax$worksheet->setCellValue('B5', '=PRICE+TAX'); // Total with tax
// Formula to get next month$spreadsheet->addNamedFormula( new NamedFormula('NEXT_MONTH', $worksheet, '=EDATE(OFFSET($A1,-1,0),1)'));// Formula to calculate growth between sheets$spreadsheet->addNamedFormula( new NamedFormula( 'GROWTH', $worksheet, "=IF('2024'!\$B1=\"\",\"-\",(('2024'!\$B1/'2023'!\$B1)-1))" ));// Use in cells$worksheet->setCellValue('A2', '2024-01-01');for ($row = 3; $row <= 13; $row++) { $worksheet->setCellValue("A{$row}", '=NEXT_MONTH');}
Generally, specify null for the worksheet parameter when creating Named Formulas. Specifying a worksheet can lead to Excel errors when the file is opened.
// Define supporting named ranges$spreadsheet->addNamedRange( new NamedRange('CHARGE_RATE', $worksheet, '=$B$1'));$spreadsheet->addNamedRange( new NamedRange('HOURS_PER_DAY', $worksheet, '=$B1') // Relative);$spreadsheet->addNamedRange( new NamedRange('COLUMN_DATA_VALUES', $worksheet, "=A\$4:A\$8"));// Define named formulas that use the ranges$spreadsheet->addNamedFormula( new NamedFormula('DAILY_CHARGE', null, '=HOURS_PER_DAY*CHARGE_RATE'));$spreadsheet->addNamedFormula( new NamedFormula('COLUMN_TOTALS', null, '=SUM(COLUMN_DATA_VALUES)'));// Use the formulas$worksheet->setCellValue('C4', '=DAILY_CHARGE');$worksheet->setCellValue('B9', '=COLUMN_TOTALS');
You can define Named Ranges and Formulas in any order. They only need to exist before you save the file or calculate cell values.
Use the DefinedName::createInstance() helper to automatically determine if a value is a range or formula:
use PhpOffice\PhpSpreadsheet\DefinedName;// Automatically determines this is a range$spreadsheet->addDefinedName( DefinedName::createInstance('PRICE', $spreadsheet, $sheet, '=$B$3', true));// Automatically determines this is a formula$spreadsheet->addDefinedName( DefinedName::createInstance('TAX_RATE', $spreadsheet, $sheet, '=19%', false));
While you can name something SUM, it’s confusing. Use names like SUM_OF_HOURS instead.
3
Use Local Scope Strategically
Use global scope for values used across multiple sheets
Use local scope when different sheets need different values for the same name
4
Document Complex Formulas
Use named formulas to break complex calculations into understandable pieces:
// Instead of one complex formula$sheet->setCellValue('D1', '=IF(B1>0,(C1/B1-1)*100,0)');// Use named formulas$spreadsheet->addNamedFormula( new NamedFormula('HAS_LAST_YEAR', null, '=LAST_YEAR>0'));$spreadsheet->addNamedFormula( new NamedFormula('GROWTH_PCT', null, '=(THIS_YEAR/LAST_YEAR-1)*100'));$sheet->setCellValue('D1', '=IF(HAS_LAST_YEAR, GROWTH_PCT, 0)');