I did not set out to write a script. I set out to personalize a few hundred jerseys and assumed Illustrator could already do it. This article is what I learned on the way - including one thing I got badly wrong myself and reported to Adobe as an Illustrator bug.
What the Variables panel actually does
Window → Variables supports four kinds of variable: text string, linked file, visibility (an object is shown or hidden on TRUE/FALSE) and graph data. You bind them to objects, load a variable library and switch between datasets; switching a dataset updates the artwork on screen. With the free VariableImporter script by Vasily Hall you can also compose the dataset name out of your own column values - which matters in a moment. Since CC 22.1 (March 2018) the panel imports CSV on its own, before that it was XML only.
For a handful of variants that you preview by hand, this is genuinely fine and you do not need anything else.
Four limits you hit in production
1. Batch export only runs through Actions
Nothing in the panel says “export one PDF per dataset”. The standard route is to record an Action and run File → Automate → Batch with Data Sets as the source. It works reliably. The price is that a recorded Action drives the export: one PDF preset for the whole run, no way to vary it per row, and a failure halfway through a long batch is easy to miss.
2. File names work - folder structures do not
Production wants Smith_10_XL.pdf, not Batch_0001.pdf. Illustrator names datasets imported from a CSV “Data Set 1, 2, 3” and cannot bind that name to a column on its own - an open request on Illustrator UserVoice. Batch then offers three naming schemes, all derived from the dataset name. The free route does exist, though: VariableImporter builds the dataset name from up to six fields, your own column values among them, so Smith_10_XL.pdf is reachable without paying for anything. What stays out of reach either way is a folder structure driven by the data - Batch writes into a single destination folder, so sorting by order, product and size is left to you.
3. The API is easy to get wrong - and the documentation will not save you
This is where I lost the most time, and it ended differently than I expected. Reading values back out of a dataset in ExtendScript kept returning empty strings, so I concluded the API was broken and posted a detailed report with a sample file, CSV and test script on the Adobe forums in May 2025.
It turned out to be my mistake, not a bug. CarlosCanto answered with the correct syntax: address the dataset through doc.activeDataSet = doc.dataSets[i], read doc.variables instead of the dataset’s own collection, and take the value from variable.pageItems[0].contents. The thread is public and his reply is there for anyone to read: Issue with Reading Variable Data from DataSet in Illustrator 29.5. Credit where it is due.
What that episode did not change is the conclusion. By the point where you are writing ExtendScript that switches datasets, reads values back and drives the PDF export itself, you are no longer using a built-in feature - you are writing your own exporter. The limits above and below stay exactly where they were.
4. Variables substitute content - they never create it
What all four variable types share is that they place content you prepared in advance. Visibility can show or hide an object that is already in the document, so a sponsor logo can be toggled - provided you built every variant beforehand. What none of them does is create new artwork: build a number out of graphic digit symbols, fit a sponsor logo inside a digit and scale it to match, add a caron to a font that has no caron, or impose 17 keychains on one press sheet. Those are the jobs that actually eat the day.
An honest comparison
The free tools genuinely work. Each one just hits its limit somewhere different - this table shows where.
|
Variables + Actions |
VariableImporter |
InDesign Data Merge |
exportPDF |
| Import a CSV |
✓ since CC 22.1 |
✓ |
✓ |
✓ |
| One PDF per row without Actions |
✗ |
✗ |
partly |
✓ |
| File names from data |
dataset names |
✓ |
✗ |
✓ |
| Folder structure from data |
✗ |
✗ |
✗ |
✓ |
| Numbers from graphic symbols |
✗ |
✗ |
✗ |
✓ |
| Logo inside the number |
✗ |
✗ |
✗ |
✓ |
| Diacritics for non-localised fonts |
✗ |
✗ |
✗ |
✓ 10 languages |
| Sheet layout for small items |
✗ |
✗ |
manual |
✓ |
| Missing-glyph check |
✗ |
✗ |
✗ |
✓ |
| Duplicate detection |
✗ |
✗ |
✗ |
✓ |
| Log and post-export summary |
✗ |
✗ |
✗ |
✓ |
| Named product profiles |
✗ |
✗ |
✗ |
✓ |
| Two products from one table |
✗ |
✗ |
✗ |
✓ |
| Stays in Illustrator |
✓ |
✓ |
✗ |
✓ |
| Price |
free |
free |
CC subscription |
free demo, paid license |
When the free route is enough
Occasional jobs, plain text substitution, a few dozen files, no special typography - set up VariableImporter and an export Action and you are done. Genuinely. If your work looks like that, the rest of this page is not for you.
Where exportPDF picks up
exportPDF is a JSX script for Adobe Illustrator CS4 and newer. It skips Variables and Datasets entirely: it reads the CSV itself, fills the named text fields in your template and exports one print-ready PDF per row, with file and folder names built from your data. On top of that it assembles numbers from graphic digit symbols, places a club or sponsor logo inside the digit, composes diacritics for fonts that lack them (10 languages, including Nordic Å, Ø, Æ, Ð, Þ), handles multi-line text and indices, scales everything per product size, and can impose small items on a single sheet. What the table cannot show is the work nobody wants to do by hand. When a font has no glyph for a foreign name, Illustrator’s Missing Glyph Protection quietly switches that text to the default font - on screen it looks almost right and you find out on the printed sheet. exportPDF checks glyphs up front, substitutes a space so your font is preserved, and after the export lists which rows and which characters were affected, so you know to add the diacritic or the glyph. It watches duplicates the same way: identical products are skipped and colliding file names are renamed automatically, both counted in the log and in the summary. Your CSV columns do not have to be named the way the script wants: as soon as the file is loaded it tries to match them to the name, number, nickname and size fields on its own, and whatever does not match or is missing you fill in by hand. One table can drive two independent products, settings can be saved as a named profile you switch between in one dialog, and extra sizes (30x50 for towels, 42/44/46 for caps) go in as a comma-separated list.
The last dialog before the export is also the last check. You assign named artboards to a product and to a size from the CSV - the artboard dresy-XL belongs to the product Dresy at size XL. Named correctly, they pair up on their own; if a typo slips in or you name your artboards your own way, you pair them here by hand. You pick the destination folder and a PDF preset from a list the script reads out of Illustrator itself. Names are then composed from six placeholders - {cislo}, {jmeno}, {prezdivka}, {velikost}, {kod} and {docName} - separately for the folder template and the file name, and separately for each of the two products. The order is yours: whether a name starts with the size, the number or the name is purely a matter of how you write the template. A preview built from the first CSV row shows the result before anything is exported.
It was written in our own graphics department and is used there daily since 2025. A 200-jersey order that used to take four hours of copy-paste takes about ten minutes. The demo is free and full-featured: 30 runs, 20 CSV rows. exportPDF for Illustrator · pricing · support and FAQ. Working in CorelDRAW instead? There is a version for that.