5 min leestijdFuncties

QR-codes in bulk genereren: van CSV naar drukklare bestanden

QR-codes in bulk uit een spreadsheet: maak per rij een korte link, render SVG en PNG via een API en test een steekproef voor het drukken.

Ana Kowalska
Marketing solutions engineering

QR-codes in bulk genereren zijn twee API-aanroepen per rij en aan het eind een map. Maak voor elke bestemming een korte link, render een QR-code voor die korte link en schrijf de SVG en PNG weg. Een spreadsheet met 5.000 producten wordt in een paar minuten 5.000 drukklare bestanden.

Niet de tooling is de beslissing, maar wat de code codeert. Codeer je de bestemming direct, dan ligt de code vast zodra hij naar de drukker gaat. Eén verkeerde URL in een oplage van 5.000 stickers maakt dan de hele oplage waardeloos. Codeer je een korte link die je zelf beheert, dan blijft de bestemming voor altijd aanpasbaar en rapporteert elke code ongemerkt zijn eigen scans.

Maak je één code in plaats van duizenden? QR-code maken is de eenvoudigere stap-voor-stap, en een QR-codecampagne vanaf nul behandelt plaatsing en meting.

De pijplijn in vier stappen

Een bulk-QR-codepijplijn in vier stappen: lees een CSV met bestemmingen, maak per rij een korte link, render de QR-code als SVG en PNG en controleer een gedrukte steekproef door te scannen

Houd een kolom id in de CSV, ook als die overbodig lijkt. Het wordt de bestandsnaam, de idempotency key en datgene waarop je matcht als het designteam terugmeldt dat "code 412 fout is". Zonder id match je op URL's, en die zijn lang en makkelijk te verkeerd te typen.

import csv, base64, hashlib, pathlib, os, requests

API = "https://api.elido.app"
HEAD = {"Authorization": f"Bearer {os.environ['ELIDO_API_KEY']}"}
out = pathlib.Path("qr-out")
out.mkdir(exist_ok=True)

with open("products.csv") as f:
    for row in csv.DictReader(f):        # columns: id, destination
        key = hashlib.sha256(row["destination"].encode()).hexdigest()

        link = requests.post(
            f"{API}/v1/links",
            headers={**HEAD, "Idempotency-Key": key},
            json={"destination_url": row["destination"]},
            timeout=10,
        )
        link.raise_for_status()
        short_url = link.json()["short_url"]

        qr = requests.post(
            f"{API}/v1/qr/generate",
            headers=HEAD,
            json={
                "content": short_url,          # the short link, never the destination
                "formats": ["svg", "png"],
                "size": 1024,
                "error_correction": "M",
            },
            timeout=20,
        )
        qr.raise_for_status()
        payload = qr.json()

        (out / f"{row['id']}.svg").write_text(payload["svg"])
        (out / f"{row['id']}.png").write_bytes(base64.b64decode(payload["png"]))
        print(row["id"], short_url)

De idempotency key wordt afgeleid van de bestemming. Draai je het bestand opnieuw nadat je drie rijen hebt gecorrigeerd, dan wordt niets dubbel aangemaakt en kost het niets. Die eigenschap maakt een bulkjob veilig herhaalbaar, en het loont om haar goed te begrijpen voordat je dit op 5.000 rijen loslaat: rate limits en idempotency behandelt de werking.

De lus hierboven is sequentieel, en dat is prima tot een paar honderd rijen. Daarboven draai je er ongeveer acht parallel. De gidsen voor Python en JavaScript bevatten allebei een patroon met begrensde concurrency dat je zo kunt overnemen.

Wil je het proberen? Maak een sleutel aan op het gratis abonnement, exporteer ELIDO_API_KEY en richt het script eerst op een CSV van vijf rijen voordat je het op de echte loslaat.

Statisch of dynamisch, op schaal

Statische QR-codes die de bestemming coderen vergeleken met dynamische QR-codes die een korte link coderen, voor een bulkoplage waarvan de bestemmingen kunnen veranderen

Een statische code heeft precies één voordeel: hij hangt van niets af. Geen domein om in leven te houden, geen dienst om voor te blijven betalen. Dat telt bij een code die in een machine wordt gegraveerd die je leverancierscontract overleeft, en bijna nergens anders.

Al het andere pleit voor dynamisch. Scanaantallen per code, de enige manier om schapplaatsingen of winkellocaties te vergelijken. Een bestemming die je kunt corrigeren als de campagnepagina verhuist. En kleinere, ijlere codes, omdat een korte link maar een fractie van de tekens van een getagde product-URL heeft. Dynamische versus statische QR-codes bevat de volledige vergelijking.

Printinstellingen die er echt toe doen

Drie parameters bepalen of de batch in de praktijk scant.

Foutcorrectie. Niveau M herstelt ruwweg 15 procent schade en houdt de code ijl. Ga naar Q wanneer een logo in het midden staat of de code veel wordt aangeraakt, bekrast raakt of op iets gebogens wordt gedrukt. H klinkt veiliger en is dat meestal niet: de extra redundantie propt meer modules in de code, en dichtere codes scannen bij kleine formaten moeilijker. De QR-standaard beschrijft alle vier de niveaus.

Formaat. SVG voor druk, omdat het tot een poster schaalt zonder dat de randen van de modules zachter worden. PNG voor slides, marktplaatsen en alles wat vectoren weigert. Vraag beide in één verzoek op en je slaat de extra ronde over wanneer iemand het andere formaat nodig heeft.

Stille zone. De lege marge rond de code hoort bij de code. Vier modules is het voorgeschreven minimum, en ontwerpers snijden die betrouwbaar af omdat het verspilde ruimte lijkt. Een code met een krappe rand scant slecht op goedkope telefooncamera's en niemand legt ooit het verband.

Nog één ding om te weten voordat je één formaat voor de hele batch vastlegt: de hoeveelheid data bepaalt de versie, en de versie bepaalt hoeveel modules de code heeft. Denso Wave, de bedenker van het formaat, publiceert de tabel met versies en capaciteit. Een korte link van 30 tekens zit onderin die tabel. Een getagde product-URL van 180 tekens niet, en het verschil zie je terug als een zichtbaar dichtere code bij hetzelfde gedrukte formaat.

Het formaat in het bestand doet minder ertoe dan het formaat op het object. Hoe groot moet een QR-code zijn bevat de regel over scanafstand die de fysieke afmeting bepaalt.

Controleer voordat iets naar de drukker gaat

Genereer een batch en controleer dan vijf willekeurige codes. Niet aan je bureau op volle schermhelderheid: druk ze af op het formaat waarop ze echt komen, plak er een op het schap of de verpakking en scan vanaf de plek waar een klant zou staan.

Controleer daarna de redirect zelf. Met curl -sI op drie van de korte links bevestig je dat ze een redirect naar de juiste bestemming teruggeven. Zo vang je de klassieke off-by-one waarbij kolom twee van de CSV als kolom drie is gelezen en elke code naar het naastliggende product wijst. Die fout is stil, overleeft elke visuele controle en is alleen zichtbaar in de bestemming.

Bewaar de CSV waarmee de batch is gemaakt, met id, bestemming, korte link en bestandsnaam erin. Vraagt iemand over zes maanden welke code op welke pallet zit, dan is dat bestand het antwoord, en het opnieuw genereren vanuit het dashboard is veel meer werk dan het bewaren.

Waar de scans verschijnen

Zodra de codes live zijn, rapporteert elke code apart. Dat is de hele reden voor één code per item in plaats van één gedeelde code: één code vertelt dat de campagne werkte, codes per item vertellen welke winkel, welk schap of welke SKU werkte.

QR-codescans volgen behandelt het lezen van die data, en webhooks voor linkevents behandelt het doorsturen van scans naar je eigen systemen in plaats van een dashboard te raadplegen. Voor fysieke producten specifiek behandelen QR-codes voor het digitaal productpaspoort de wettelijke variant van dezelfde pijplijn.

Lees de cornerstone-serie

Dit hoort bij het cluster Functies. Begin met QR-code maken voor de variant met één code, daarna een QR-codecampagne vanaf nul voor het campagneontwerp. De functiepagina over QR-codes behandelt de stylingopties die dit script overslaat.

Gerelateerd op de blog

Veelgestelde vragen

Hoe genereer ik QR-codes in bulk?

Loop over een CSV, maak voor elke rij een korte link, render via de API een QR-code voor elke korte link en schrijf de bestanden weg. Twee aanroepen per rij en aan het eind een map. Door de korte link te coderen in plaats van de bestemming blijft elke code ook na het drukken aanpasbaar.

Moeten bulk-QR-codes statisch of dynamisch zijn?

Dynamisch, in bijna elk bulkgeval. Een statische code codeert de bestemming direct, dus één verkeerde URL in een oplage van 5.000 betekent opnieuw drukken. Een dynamische code codeert een korte link die je zelf beheert, waardoor de bestemming achteraf te corrigeren is en elke code zijn eigen scans rapporteert.

Welk foutcorrectieniveau gebruik ik voor gedrukte QR-codes?

Niveau M is de verstandige standaard: het herstelt ruwweg 15 procent schade en houdt de code ijl genoeg om snel te scannen. Kies Q wanneer een logo het midden bedekt of de code ergens komt te hangen waar hij beschadigd raakt. H is zelden de moeite waard, omdat de extra dichtheid de code bij kleine formaten lastiger scanbaar maakt.

In welk bestandsformaat moeten bulk-QR-codes komen?

SVG voor alles wat wordt gedrukt, omdat het naar elk formaat schaalt zonder dat de randen van de modules zachter worden. PNG voor schermen, slides en marktplaatsuploads die vectoren weigeren. Beide tegelijk genereren kost één verzoek en bespaart de extra ronde wanneer het designteam om het andere formaat vraagt.

Hoeveel QR-codes kan ik tegelijk genereren?

Zoveel als de rate limit toestaat, en dat is een kwestie van doorvoer en geen harde limiet. Draai ongeveer acht verzoeken parallel, stuur een idempotency key mee die je van elke rij afleidt zodat een herhaalde run niets dubbel aanmaakt, en een batch van enkele duizenden is in minuten klaar.

Heb ik voor elk product of elke locatie een aparte QR-code nodig?

Ja, als je wilt weten welke is gescand. Eén gedeelde code vertelt dat de campagne werkte. Eén code per item vertelt welk schap, welke winkel of welke SKU werkte. De variant per item kost niets extra om te genereren en is de enige manier om plaatsingen te vergelijken.

Probeer Elido

Plak een URL, krijg een werkende korte link

Geen aanmelding nodig. Link blijft 30 dagen actief. Meld je aan om hem voor altijd te bewaren.

Geen account nodig. Meld je gratis aan voor 50 links per maand.

Probeer Elido

In de EU gehoste URL-shortener met aangepaste domeinen, uitgebreide analyses en een open API. Gratis abonnement - geen creditcard nodig.

Tags
bulk qr code generation
generate qr codes from csv
bulk qr code generator api
qr codes at scale
dynamic qr codes bulk
qr code print files

Verder lezen