Excel in PHP: read, write, or fill templates — how to choose the right tool
You opened a ticket that says “export to Excel” (or “accept an Excel file from the user”), went searching,
and the very first answer was PhpSpreadsheet. It can do everything at once, which makes it look like the
obvious choice. The trouble is that “can do everything” here means “loads the entire file into an object
model in memory” — and on real-world volumes, or inside a loop, that quickly turns into
Allowed memory size exhausted.
Before picking a library, it helps to realize that “working with Excel” is not one task but three. And each of them calls for a different tool.
Three different tasks that everyone calls “Excel in PHP”
1. Read someone else's file
A user uploaded a price list, an export from an accounting system, or a report — and you need to get the data out: walk the rows, put them in the database, validate them. What matters here is speed and memory: the file may run to hundreds of thousands of rows, and all you want are the values.
You do not need the whole workbook in memory — you need streaming, row-by-row parsing.
2. Create a file from scratch
You have an array of data from the database and need to lay it out as a table: headers, rows, a bit of styling, auto-width, maybe formulas and a chart. You define the structure yourself, from code — “writing top to bottom.”
Streaming matters here too: a million-row report must not kill the process on memory.
3. Fill in a ready-made form
This one is a separate case that people often try to solve with the wrong tool. You have a ready XLSX form (an invoice, a statement, a contract, a certificate) drawn by an accountant or a designer: with a logo, borders, merged cells, number formats, and formulas. You do not need to build the document — you need to put data into it without breaking any of the formatting.
If you try to solve that by “creating a file from scratch,” you will end up rewriting in code all the formatting that is already drawn in the file. That is slow, fragile, and pointless.
The FastExcelPhp family: one tool per task
Instead of a single combine harvester, there are three lightweight libraries here, each sharpened for its own task and built around streaming (never keeping the whole sheet in memory):
- FastExcelReader — task #1, reading. Streaming parsing of XLSX (and, in recent versions, of legacy
.xlsand CSV as well). - FastExcelWriter — task #2, writing from scratch. Styles, formulas, charts, autofilters — all from code.
- FastExcelTemplator — task #3, filling templates. Our protagonist in this article.
(There is also FastExcelLaravel — a wrapper around the family for Laravel: facades, import and export of models and collections.)
When your task is a template
Signs that what you need is Templator rather than Writer:
- the document has a fixed corporate look, and that look is easier to draw in Excel than to describe in code;
- the formatting is owned by someone who is not a programmer — an accountant, an analyst — and they must be able to edit the form themselves, without a release;
- the document has a logo, notes, tricky borders, merged cells — the kind of thing that is tedious to reproduce in code;
- you need many identical documents from one form (invoices, certificates, contracts).
The idea is simple: the form is an ordinary XLSX that you draw by hand and mark up with placeholders. The code only substitutes values:
use avadim\FastExcelTemplator\Excel;
// Open the template and say where to write the result
$excel = Excel::template('invoice-tpl.xlsx', 'invoice-out.xlsx');
$sheet = $excel->sheet();
// Substitute data for the placeholders in the header
$sheet->fill([
'{{COMPANY}}' => 'Acme Ltd',
'{{NUMBER}}' => 128,
]);
// Transfer the template rows into the output and save
$sheet->transferRows();
$excel->save();
All of the formatting — fonts, borders, logo, number formats — is carried over from the template by the library itself, because it keeps the original file and merely replaces the values inside it.
An honest fork in the road: what to pick
To keep you from choosing wrong, here is a short checklist:
- You need to read data out of someone else's file →
fast-excel-reader. Templator does not do that. - You need to build the whole table from code, with no ready-made form →
fast-excel-writer. That is its job, not Templator's. - You have a ready XLSX form and need to put data into it →
fast-excel-templator. - You need a legacy
.xlsas the template → that will not work: Templator handles XLSX only (Office 2007+). Re-save the source as.xlsx. - The project runs on Laravel and you want model import/export → have a look at
fast-excel-laravelon top of whichever library fits.
The key thought: do not haul in a combine harvester where a screwdriver will do. If you catch yourself reproducing in code the formatting of a file that already exists, what you need is the template approach — and from there it is worth looking at FastExcelTemplator. How it fills a form step by step is a topic for a separate walkthrough.