limitColumns() and onlyColumns()
Imports can now be trimmed by column, not just by row.
limitColumns() truncates each row after a given column, taking either a column reference or a count:
$collection = (new FastExcel)->limitColumns('H')->import('file.xlsx');
$collection = (new FastExcel)->limitColumns(8)->import('file.xlsx');This is aimed at files where formatting has been applied to entire rows. The spreadsheet then reports thousands of trailing cells that look like real columns, and every imported row comes back padded with empty column_9, column_10… entries.
onlyColumns() keeps an explicit allowlist and drops everything else, including empty columns in the middle. Letters and 1-based indexes can be mixed, and the order you pass is the order you get:
$collection = (new FastExcel)->onlyColumns(['A', 'B', 'H'])->import('file.xlsx');
$collection = (new FastExcel)->onlyColumns([1, 2, 8])->import('file.xlsx');The two are mutually exclusive — setting one clears the other, while passing null clears only that setter. Both work with import and importLazy.
Thanks to @dannyyol, who opened #419 with the implementation and 346 lines of tests, then worked through a round of requested changes on onlyColumns() input validation without complaint. The request came from @chan15 in #370, asking for "something like an end column" — an accurate description of the problem that turned out to need two methods rather than one.
OpenSpout Cell instances as export values
A row value may now be an OpenSpout\Common\Entity\Cell, for full control over a single cell's type or style. The pre-built cell is written through as-is while the other scalar values in the row keep their normal handling and per-column styles:
use OpenSpout\Common\Entity\Cell;
use OpenSpout\Common\Entity\Style\Style;
$users = collect([
['name' => 'John', 'note' => Cell::fromValue('paid', (new Style())->setFontBold())],
['name' => 'Jane', 'note' => 'pending'],
]);
(new FastExcel($users))->export('users.xlsx');Previously a Cell value was silently dropped by transformRow() and would have broken Row::fromValues(), which expects scalars.
Thanks to @kusab85, who proposed this in #306 and stayed in the thread through the discussion that shaped the final version; the merged commit carries their co-authorship. Thanks also to @duypdx for adding weight to the request.
Column widths are documented
Explicit column widths have worked all along through OpenSpout's writer options and configureOptionsUsing() — they were simply never written down, so #213 sat since 2021 with the answer "not possible", which was only half true.
(new FastExcel($list))
->configureOptionsUsing(function ($options) {
$options->setColumnWidth(40, 1); // first column
$options->setColumnWidth(15, 2, 3); // second and third
$options->setColumnWidthForRange(20, 1, 4); // or a contiguous span
})
->export('file.xlsx');The new section covers 1-based column numbers, streaming exports (widths are written when the file is finalized, not per row), and the csv caveat: OpenSpout\Writer\CSV\Options does not define setColumnWidth() at all, so calling it on a csv export raises Error: Call to undefined method rather than being quietly ignored.
Automatic sizing to fit content is still unavailable, so #213 stays open for that.
Thanks to @hemasharshar for raising it, and to everyone who kept the thread alive over four years with the real-world need behind it: @yybawang, @allanvb, @tanvir-retailai, @humbertleonardo and @tajweb. Thanks to @dannyyol for reviewing the docs PR, and to @rap2hpoutre for the earlier answers on the issue.
Full changelog: v5.15.0...v5.16.0