Core concepts
Cell Values and PHP Types
Write intentional text, numbers, booleans, dates, formulas, and blanks without losing meaning.
MnbExcel::text()number()bool()date()formula()blank()Choose the cell type from what the value means, not what the string happens to look like.
Explicit typed values are most useful at ambiguous boundaries: identifiers that contain digits, date-like strings, formulas, booleans, and intentional blanks.
text()'00123'Identifiers, postal codes, SKUs, and other strings whose characters must be preserved.number()12 / 249.95Quantities, amounts, measurements, and values intended for numeric operations.bool()true / falseFlags and yes/no state that should remain boolean rather than text labels.date()DateTimeInterfaceDates or date-times that should retain date meaning and accept spreadsheet date formatting.formula()=B2*C2Trusted formulas created by application logic, optionally with a cached result.blank()blankAn intentionally empty cell rather than an empty-looking text value.Make the boundary explicit before writing the workbook.
A spreadsheet can display several different underlying meanings in similar-looking ways. Resolve that ambiguity in application code instead of asking Excel to guess.
00123TextLeading zeroes are part of the identifier.12NumberThe application intends arithmetic or numeric comparison.2026-07-26DateUse a date value when date semantics matter; do not rely on a date-looking string alone.=B2*C2FormulaOnly when the expression is trusted application logic.=HYPERLINK(...)Text for untrusted inputUser-controlled formula-like text should pass through the export safety policy.use Mnb\PHPExcel\MnbExcel;
$row = [
'Postal Code' => MnbExcel::text('00123'),
'Quantity' => MnbExcel::number(12),
'Active' => MnbExcel::bool(true),
'Joined At' => MnbExcel::date(new DateTimeImmutable('2026-07-26')),
'Total' => MnbExcel::formula('=B2*C2', 249.95),
'Notes' => MnbExcel::blank(),
];Keep the semantic value intact. Use formatting only to control presentation.
Currency symbols, percentage presentation, and date patterns belong to the display layer. They should not turn numeric or date values into presentation strings.
- Value layer
- Choose text, number, boolean, date, formula, or blank from the business meaning.
- Display layer
- Apply number/date styles after the value type is correct.
- Review rule
- If changing a display format changes the business meaning, the underlying value type is probably wrong.
MnbExcel::report($rows)
->currencyColumns(['Amount'], '$')
->percentageColumns(['Completion'])
->dateStyleColumns(['Order Date'], 'yyyy-mm-dd')
->save('report.xlsx');Treat trusted formulas and untrusted formula-like text as different data.
Application-authored formulas are intentional workbook logic. User-controlled strings require an export safety policy so spreadsheet software does not reinterpret them as executable formulas.
Write an explicit formula value.
Use the formula helper for expressions created and controlled by your application.
$total = MnbExcel::formula('=B2*C2', 249.95);Escape formula-like export values.
Apply the safety policy to user-controlled exports, especially values beginning with =, +, -, or @.
MnbExcel::fromArray($rows)
->escapeFormulaLikeText()
->save('safe-export.xlsx');Security boundary: presentation formatting does not make untrusted formula-like text safe. Handle formula interpretation explicitly at the export boundary.