CSV to QR Codes

Drop a CSV, pick the column to encode, and every row becomes a QR code. Take them as a zip of individually named SVG or PNG files, as a printable A4 sheet you can put on label stock, or as a CSV with an SVG column. File names come from a label column, so you get sku-A1043.svg rather than qr-17.svg.

No file handy? The Try with sample data button above loads a small product list and encodes it.

The file names are the feature

Generating a hundred QR codes is the easy half. The half that decides whether the output is usable is what the files are called, because a zip of qr-1.svg through qr-100.svg is a zip you have to open and inspect one file at a time to use.

So there are two column pickers. One says what to encode, usually a URL or a product code. The other says what to label with, and that column becomes both the caption under each code on the printed sheet and the file name inside the zip:

sku-A1043.svg
sku-A1044.svg
sku-B2210.svg
Widget-Blue.svg
Widget-Red.svg

Names are made filesystem-safe, so spaces and punctuation become hyphens and the result is under eighty characters. Two rows with the same label would silently overwrite each other inside a zip, so repeats get a numeric suffix instead. That is a small thing that turns a corrupt-looking archive into a correct one.

Four ways to take the result

DeliveryWhat you getUse it for
Zip of SVG filesone scalable vector file per rowa design tool, a print house, anything that will be resized
Zip of PNG filesone raster image per row, at your chosen module sizea slide deck, a web page, a system that will not take SVG
Printable sheetan A4 PDF, codes in a grid with their labels under themlabel stock, a shelf-edge print run, a warehouse
CSV with an SVG columnyour labels alongside the markupa mail merge, a template engine, a database column

The zip and the PDF are built when you click, not on every keystroke, because assembling a thousand-file archive on each character typed would make the page unusable. The button says what it is doing while it works.

On the printable sheet you choose how many codes go across the page, from one to ten. Fewer and larger is right for shelf labels; more and smaller for a sheet of asset tags. The grid is sized to the page margins automatically and it paginates.

Worked example

The sample is a small product list, deliberately including a value with a comma in it:

sku,name,url
A1043,"Widget, Blue",https://example.com/p/A1043
A1044,"Widget, Red",https://example.com/p/A1044
B2210,Gadget Mk II,https://example.com/p/B2210

Encode url, label with sku, and you get three codes named A1043.svg, A1044.svg and B2210.svg, each pointing at its own product page. Label with name instead and they become Widget-Blue.svg, Widget-Red.svg and Gadget-Mk-II.svg.

The quoted comma inside Widget, Blue is read correctly as part of one field. That is the case that breaks a naive split-on-comma reader, and it is in the sample deliberately so you can see it handled rather than take it on trust.

Picking the error correction level for print

The default of M is right for a screen. For anything printed and handled, go up. A shelf label gets scuffed, a shipping label gets rain on it, an asset tag gets a thumb over the corner, and each of those destroys modules that error correction has to replace.

  • Q, about 25% is the usual choice for printed labels. It survives ordinary wear and does not inflate the code much.
  • H, about 30% for an industrial setting, or where you will overlay anything.
  • L only when you have a long payload and a screen. On paper it is a false economy.

Module size matters as much as the level. On the printable sheet the codes are sized to the grid, so fewer per row gives larger modules and a code that scans from further away. A very long URL at level H across ten columns produces something too dense to read at arm's length; the fix is a shorter URL, not a higher level.

Limits, and what happens at them

Two thousand codes in one run. Past that the tab spends longer drawing than anyone waits, so the first two thousand rows are encoded and a note names the total your file had. Splitting the file and running it twice is the answer, and it is faster than waiting.

A row whose encoded cell is empty produces no code, and the count of skipped rows is reported. So does a row whose value is too long to fit in any QR code at the chosen error correction level, which happens with very long URLs at level H. The gallery on the page shows the first twenty-four codes so you can eyeball them before committing to the download.

Frequently Asked Questions

How are the files inside the zip named?

From the label column you pick. Spaces and punctuation become hyphens, the name is capped at eighty characters, and two rows sharing a label get a numeric suffix rather than overwriting each other. Pick Row number as the label to fall back to a simple index.

SVG or PNG?

SVG for anything that will be printed or resized, because it is geometry rather than pixels and stays sharp at any size. PNG for a slide deck, a web page or a system that will not accept SVG. The PNGs are rasterized at the module size you set, so raise it if they are going anywhere large.

What size is the printable sheet?

A4, with the codes in a grid you size by setting how many go across the page, from one to ten. The label from your label column is printed under each code, and the sheet paginates automatically for as many rows as you have.

How many codes can it do at once?

Two thousand in a single run. Above that the first two thousand rows are encoded and a note tells you the total, because a browser tab drawing more than that spends longer than anyone will wait. Split the file and run it twice.

Which error correction level should I use for labels?

Q, about 25%, for most printed labels. H, about 30%, for an industrial setting or if anything will be overlaid on the code. L only for a screen. Printed codes get scuffed and covered, and the redundancy is what makes them still work.

Does it handle quoted fields with commas in them?

Yes. The reader follows RFC 4180 quoting, so "Widget, Blue" is one field rather than two. The sample deliberately contains such a value so you can confirm it before trusting your own file to it.

Does anything I paste leave my computer?

No. There is no upload endpoint on this page and no network request in the code that does the work. JavaScript in your own tab reads the text, processes it and hands back the result. Nothing is stored between visits either, so reloading gives you an empty box again. You can confirm it by opening your browser's network panel and watching it stay quiet while you work.

A hundred codes, correctly named

Free, no account, nothing transmitted. A zip, a printable sheet, or a CSV with the markup in it.

Back to the generator