Back to Top

How to Import CSV & XLSX Files into Pimcore 12

Getting a catalog into Pimcore 12 usually means recreating a spreadsheet by hand — object by object, field by field, in the DataObject editor. It does not scale, it drifts from the source file, and it is impossible to repeat when that file changes.

The Pimcore CSV/XLSX Import Connector removes that step. Upload a CSV, XLSX or ZIP, point each column at a field in a mapping wizard, and the bundle writes real Pimcore DataObjects for you — in the background, with a live progress log, and without duplicating anything on the next run. No CSV middleware, no external ETL tool, no custom scripts. This guide walks the whole flow: install the bundle, grant the permission, then upload, map and import from inside Pimcore Studio.

Pimcore CSV/XLSX Import Connector
image-1

Pimcore CSV/XLSX Import Connector: Key Features

  • Import into any DataObject class — columns are matched to fields in a mapping wizard, read live from the class definition. Nothing is hardcoded.
  • Create a class from the file — no class fits yet? The bundle builds one from the file’s headings: a field per column, the type proposed from the values, one column marked the identifier.
  • CSV, XLSX and ZIP — a ZIP bundles a sheet together with a media folder, so images import alongside the data. The reader streams rows via OpenSpout, so a large file never loads whole into memory.
  • Images from files or URLs — reference a bundled file, an existing asset, or a remote image URL; downloads are streamed and de-duplicated by content, so the same image is never stored twice.
  • Every mappable field type — localized fields, relations, assets and images, and quantity values with a per-field unit picker.
  • Compound fields by header convention — classification store, object bricks and field collections, named in the column header — and localized sub-fields inside them.
  • Smart column detection — unit, brick, classification and collection columns are recognised automatically and kept out of the manual mapping grid.
  • Real variants and nesting — native Pimcore variants (blank cells inherit from the master), and parent nesting for tree-structured classes.
  • Saved mappings (Templates) — create a new template from scratch without uploading a file, edit one without a file, duplicate, fork mid-edit, or retire from suggestions without deleting; the next upload ranks them by how many columns they cover.
  • One value separator per import (comma, semicolon or pipe) — so any other punctuation stays part of a value. CSV delimiters and a UTF-8 BOM are detected for you.
  • Background jobs with a per-job error log — live progress, a cooperative Stop that keeps rows already written, and failed rows downloaded in the original file format with an _error column for fix-and-reupload.
  • In-Studio guide — with downloadable sample files.

Before You Start

You will need:

  • A running Pimcore 12 instance (2026.1 or newer) with Studio, and the CSV/XLSX Import Connector installed.
  • PHP 8.4 or 8.5.
  • background worker running. Every import is queued through Symfony Messenger — without a consumer, jobs stay pending forever. The connector wires one into supervisord under Docker.
  • Node 22 — only if you want to rebuild the Studio UI. The bundle ships it pre-built, so most installs never touch Node.

Once installed, a Data Import section appears in the Studio left nav with ImportTemplatesHistory and Guide.

Step 1 — Upload a File and Choose the Target

On the Import page:

  1. Upload your CSV, XLSX or ZIP file.
  2. Choose the DataObject class the rows become.
  3. Choose the folder the new objects land in.

No class fits yet? Click Create class and the bundle builds one from the file’s headings — a field per column, the type proposed from the values, and one column marked the identifier. It covers text, long text, number, checkbox, date, select, object relations, images and assets, and any column can be marked required.

image-4

Step 2 — Map Columns to Fields

Each row pairs a column from your file with a field on the class. Match them, then pick the identifier — the field that decides whether a row is a new object or an update to an existing one. This is what keeps re-imports from duplicating. Columns that follow a header convention — units, bricks, classification keys, collection items — are detected automatically and shown separately, so you never map them by hand.

Quantity fields get a unit picker — choose a fixed unit per field, or let a field.unit column set it per row.

On the Options step, set the Value separator: the single character that separates several values inside one cell — relations, images, multi-select. Pick comma, semicolon or pipe; it defaults to a comma, is saved with the template, and every other character then stays part of the value.

image-5

Step 3 — Run the Import

Before anything runs, a job that cannot succeed fails up front with a clear reason instead of importing zero rows. Then the run happens in the background and opens its own tab with live progress and a per-job error log.

  • One bad row never kills the run. A failed row is counted and logged with a plain reason (it names the field and value at fault, not a raw database error); the rest of the file still imports.
  • Stop safely — a running import can be stopped at any batch boundary; rows already written are kept.
  • Failed rows download in the original file format (XLSX in → XLSX out) with a trailing _error column — fix them in place and re-import just those.
  • After the run, imported objects are re-indexed so they show up immediately in Studio search.
image-7

Working with Templates

A mapping saved during an import becomes a template.

  • Create one from scratch — build a brand-new template right on the Templates page, choosing class, folder, columns, bindings and identifier, without uploading a file at all. It is ready for the next matching upload.
  • Templates lists them and opens one for editing — class, folder, bindings, identifier — without needing a file, because the columns are stored with the template.
  • Duplicate a template from the list, or fork one while editing with Save as new template.
  • Deactivate a template to retire it from suggestions without deleting it.
  • On the next upload, every template is offered closest first, each showing how many of the file’s columns it covers.
image-9

Watching, Stopping & Re-running an Import

Every import runs in the background and is tracked on the History page — each run with its IDTypeStart timeUserStatus and row counters. Status reads StartedIn ProgressCompletedFailed or Stopped.

  • Open a run — the job opens in its own tab with a progress bar, the Read / Created / Updated / Skipped / Failed counters, and an activity log that explains, in plain language, anything that went wrong.
  • Stop a run — while it is running, click Stop. The current row finishes first, and every object already written is kept — a stop is graceful, never a kill.
  • Re-run safely — just import the file again. Because the identifier decides create-vs-update, a second run updates the matching objects instead of duplicating them.
  • Fix and re-import — download the failed rows in the original file format, correct them, and import just those.

Field Type Support

Scalar fields, relations, assets and images, quantity values, and localized fields map directly in the wizard.

Compound fields are imported by naming the column, not by picking them in the grid:

Field typeColumn headerExample
Classification storefield.group.keyattributes.technical.processor
Object brickBrickType.subFieldproductTypeData.electronics.wattage
Field collectionCollectionType[index].subFieldspecifications[0].label
Quantity unitfield.unitweight.unit

Not imported (columns for these are ignored): calculatedValuehotspotimageurlSlugtablestructuredTablelinkvideoblock, the geo types and the range types.

Troubleshooting

  • The wizard will not move on — something required is unfilled. Nothing is greyed out: press the action and each unfinished field turns red and says what it needs.
  • “… is not an existing …” on every relation row — the cell holds several values but the wrong separator is chosen. Set Value separator to the one the file uses.
  • Studio shows no new objects — Studio reads the search index. If objects were created outside a normal import, reindex with bin/console generic-data-index:update:index -r.
  • Localized columns land in the wrong language — one language is imported per run. Run the file again, choosing the other language.

Try the Pimcore CSV/XLSX Import Connector

Ready to bulk-import your catalog into Pimcore 12? Get the CSV/XLSX Import Connector from the Webkul Store, or reach out for a live demo and help fitting it to your data model. Browse all of Webkul’s Pimcore extensions.

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home