directus-extension-parse-xlsx
v1.0.1
Published
Parse uploaded XLSX files into a Repeater field via a Flows operation, with automatic column mapping
Downloads
21
Maintainers
Readme
Parse XLSX for Directus
Import Excel files straight into your records. This extension adds a Parse XLSX
operation to Directus Flows that reads an uploaded .xlsx file and fills a
Repeater field with its rows — perfect for price lists, catalogs, inventory,
or any tabular data your team uploads as spreadsheets.
No coding required to use it: you configure everything with dropdowns in the Flow editor.
Installation
Note: the API part of this operation uses Directus services directly and is not sandboxed. It can be installed from the Marketplace only on self-hosted instances that set the
MARKETPLACE_TRUST=allenvironment variable. It is not available on Directus Cloud.
Directus Marketplace (self-hosted, MARKETPLACE_TRUST=all)
Open Settings → Marketplace, search for "Parse XLSX", and click Install.
Manual
Self-hosted admins can install it with:
npm install directus-extension-parse-xlsxor drop the built extension folder into the instance's extensions/ directory
and restart Directus.
Once installed, "Parse XLSX" appears in the operation list when you build a Flow.
Before you start
You need two fields on your collection:
- A file field — where the user uploads the spreadsheet (e.g.
price_file). - A Repeater field — where the parsed rows will be stored (e.g.
price_list).
The Repeater's sub-fields decide how the spreadsheet is read. Their order matches the spreadsheet columns left to right:
| Repeater sub-field | Reads spreadsheet column |
| --- | --- |
| 1st sub-field (e.g. name) | Column A |
| 2nd sub-field (e.g. unit) | Column B |
| 3rd sub-field (e.g. price) | Column C |
So if your file has Name, Unit, Price in columns A, B, C — create a Repeater with sub-fields in that same order. Column headers in the file can be named anything; they're skipped by default.
Setting up the Flow
Create a new Flow with a Manual trigger.
- Collection: your collection (e.g.
Company) - Location: Item Page
- Button label: e.g.
Import price list
- Collection: your collection (e.g.
Add the Parse XLSX operation and fill in:
| Field | What to enter | | --- | --- | | Collection | Same collection as the trigger | | File field | The field with the uploaded file (e.g.
price_file) | | Target (Repeater) | The Repeater to fill (e.g.price_list) | | Item ID |{{$trigger.body.keys[0]}}| | Start row |2if row 1 is a header, otherwise1| | End row | Leave empty to read to the end |A preview table appears showing exactly how each column maps to your fields.
Add an Update Data operation to save the result:
- Collection: your collection
- IDs:
{{$trigger.body.keys[0]}} - Payload (replace
parse_xlsxwith your operation's key if different):{ "price_list": "{{parse_xlsx.rows}}", "price_file": null }
(Optional) Add a Delete Data operation to remove the file after import:
- Collection:
directus_files - IDs:
{{parse_xlsx.file_id}}
- Collection:
Using it
- Open a record and upload your
.xlsxfile into the file field. - Save the record.
- Click the flow button (e.g. Import price list).
- The Repeater fills with the spreadsheet rows. Done.
Supported data
- Format:
.xlsx(the first worksheet is used). - Numbers: understands both
1,234.56and1 234,56styles. - Types: text, whole numbers, decimals, true/false, and dates are converted automatically based on your Repeater sub-field types.
- Empty rows are skipped automatically.
Troubleshooting
"item_id is required" — the Item ID field is empty. Type
{{$trigger.body.keys[0]}} into it (the grey text is only a placeholder).
"Field … is empty — no file uploaded" — no file was uploaded to the file field on that record. Upload one and save before clicking the button.
"File … is not an .xlsx spreadsheet" — the uploaded file is not an Excel
file. Re-export it as .xlsx and upload again.
"Field … doesn't look like a Repeater — no sub-field definition found" — the Target field you selected isn't a Repeater. Pick the correct field.
Data saved but the Repeater looks empty — the sub-field keys don't match. Check that your Repeater's sub-fields exist and are in the right order; the preview table in the operation shows the mapping being used.
Nothing happens / wrong values — open the Flow's Logs panel to see what each step returned, including the exact column mapping that was applied.
Need different columns?
Just change the sub-fields of your Repeater — add, remove, or reorder them. The importer follows the Repeater definition automatically, so there's no separate mapping to maintain.
License
Note on the xlsx dependency
The SheetJS library is installed from the official
SheetJS CDN (https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz) because
recent versions are not published to the public npm registry. The dependency is
bundled into dist at build time, so end users don't fetch it at runtime.
SheetJS Community Edition is licensed under the
Apache License 2.0,
Copyright (C) 2012-present SheetJS LLC. Its attribution notice is preserved in
the NOTICES file, which is distributed with this package.
This extension's own code remains under the MIT License.
