All posts
How-to

Map your spreadsheet to a template, column by column

Hau · July 12, 2026 · 8 min read
Map your spreadsheet to a template, column by column

*Cover photo by Carlos Muza on *Unsplash

A conference sends you a registration export on Wednesday. Five hundred rows: first name, last name, company, ticket tier, a QR string. Every badge for Saturday is already in that file. The design was signed off weeks ago. What stands between the sheet and 500 finished badges isn't design work. It's a mapping: telling the template which column fills which field, once, so every row renders the same way.

That mapping is the whole job. Get it right and the five-hundredth badge is laid out exactly like the first. Get it wrong and you find out at row 300, after the print run.

This guide walks through how to map a spreadsheet to a template, column by column, so a batch renders cleanly the first time.

💡 The short version: A template holds the design. A spreadsheet holds the values. Mapping is the contract between them. Name the fields, match the headers, clean the data, preview one row, render the rest.

Quick reference for what maps to what:

Column in your sheetTemplate field typeWhat it controls
first_name, tier, dateText fieldThe words that get swapped in
logo_url, product_shotImage fieldA picture pulled from a URL or file
qr_stringImage or code fieldA generated QR or barcode
show_discountVisibility fieldWhether a layer appears at all

Start with the sheet, not the design

The instinct is to open the design first. Resist it. The design is already done, and the sheet is what decides whether the batch works.

One row, one output

The rule that governs everything downstream: one row produces one rendered output. Row 1 is the first badge, row 12 is the twelfth. If a single badge needs a name, a company, a tier, and a QR code, then that row needs four values in four columns. Anything the template shows has to come from somewhere in that row.

This is why a stray blank row or a merged cell causes trouble later. The renderer reads top to bottom and treats every row as a job. An empty row in the middle is an empty badge in the stack.

Columns are fields, not decoration

A column header stops being a label the moment you map it. first_name isn't a description of the data, it's the address the template reads from. Treat headers as machine-facing names from the start: short, lowercase, no spaces, no punctuation. ticket_tier survives the trip. Ticket Tier (2026!) tends not to.

A computer screen showing rows of data
A computer screen showing rows of data

*Photo by 1981 Digital on *Unsplash


Name your template fields before you touch the data

A template is a design with named holes in it. Before mapping, give every hole a name you'll recognize when you see it next to a column.

Text, image, and visibility fields

Most fields fall into three kinds. Text fields swap words: a name, a price, a date, a score. Image fields pull a picture from a URL or an uploaded file: a logo, a product shot, an avatar. Visibility fields are the quiet ones. They show or hide a whole layer based on a value, which is how one template can cover "on sale" and "full price" without becoming two templates.

Naming them well is half the battle. A field called name_text sitting next to a column called first_name tells you at a glance that the wiring is right.

Match the header to the field name

The single most common failure in a batch is a mismatch between a column header and a field name. The renderer looks for the value under the name it was given. If the field expects company and the column says company_name, the field comes back empty and you get a badge with a blank where the company should be.

⚠️ The rename trap: Changing a column header after you've mapped it silently breaks the link. If a field goes empty across every row, a renamed or misspelled header is the first place to look.


Map it column by column

With fields named and headers clean, the mapping itself is short.

  1. Open the template and list its fields. Note the type of each: text, image, or visibility.
  2. Open the sheet and confirm one column exists for each field. Add the missing ones.
  3. Point each field at its column by name. name_text reads first_name, logo reads logo_url, and so on.
  4. For image fields, make sure the column holds a reachable URL or file reference, not a picture pasted into a cell.
  5. For visibility fields, decide what value means "show." A common pattern is a column that holds yes or true.

A dashboard of charts and analytics on a laptop
A dashboard of charts and analytics on a laptop

*Photo by Luke Chesser on *Unsplash

That's the contract. From here, the same sheet and the same template produce the same output on every run, whether you trigger it by hand today or a webhook fires it a thousand times next month.


Clean the data so the render doesn't surprise you

Most "the template is broken" moments are data problems wearing a costume. Four issues cause the majority of them.

ProblemWhat you seeFix
Blank rowsEmpty outputs in the batchDelete the gaps before rendering
Header in the wrong rowNothing mapsKeep headers in row one only
Punctuation in headersField can't find its columnLowercase, underscores, no symbols
Image pasted in a cellBlank image fieldUse a URL or file reference instead

The four things that break a batch

Blank rows come first because they're invisible until you scroll. Headers below the first row are next, since most renderers only read row one for names. Punctuation in headers is quieter but just as fatal: a colon or a stray emoji can make a column unfindable. And an image dropped into a cell looks fine to a human and means nothing to a renderer, which wants a path it can fetch.

📋 Two-minute pre-flight: Headers in row one, lowercase with underscores. No blank rows. Image columns hold URLs. One column per template field. Clear this list and the batch almost always renders on the first pass.

A tidy laptop workspace on a white desk
A tidy laptop workspace on a white desk

*Photo by Surja Sen Das Raj on *Unsplash


Preview one row, then render the whole file

Never send 500 rows on faith. Render row one and hold it up against the design. Is the name in the right place? Does the logo load? Does the discount layer hide when it should? One rendered row confirms the entire contract, because every other row travels the same path through the same template.

Once that single output looks right, the batch is a formality. Same data in, same pixels out, five hundred times. The moment you'd normally start the copy-paste marathon is the moment you're already done.

This is also where a spreadsheet beats a design tool's built-in bulk feature. Canva's Bulk Create caps at 300 rows and 150 columns, which is fine right up until the row that matters is 301. Past that ceiling the job stops being design and becomes rendering, and rendering is exactly what a data-to-template mapping is for.

A team working together around laptops
A team working together around laptops

*Photo by Annie Spratt on *Unsplash


FAQ

What if my template needs a field my sheet doesn't have?

Add the column. Every field on the template has to read from somewhere in the row. If there's no column for it, the field renders empty on every output.

Do column headers have to match field names exactly?

The value has to reach the field by name, so the safest path is to make the header and the field name identical: lowercase, no spaces, no punctuation. Even a trailing space can break the link.

How do I put a logo or product photo in each render?

Use an image field mapped to a column that holds a URL or file reference. Don't paste the picture into the cell. The renderer fetches the image from the path, it doesn't read pixels out of the spreadsheet.

Can one template handle "on sale" and "full price" from the same sheet?

Yes, with a visibility field. Map a column like show_discount to the discount layer and let each row decide whether that layer appears. One template, two outcomes, no duplicate design.

Why does my batch have blank outputs in the middle?

Almost always a blank row in the sheet. The renderer treats every row as a job, including the empty ones. Delete the gaps and the blanks disappear.

How big can the batch be?

That depends on the renderer, but a data-to-template setup is built for the volume that design tools cap out on. If you're hitting a 300-row wall, you've outgrown bulk-design features and want a rendering workflow instead.

Do I have to re-map every time the data changes?

No. The mapping is tied to column names, not to the specific rows. Swap in a new sheet with the same headers and the same template renders the new batch unchanged.


The design was done the first time. The spreadsheet is just the same artifact again with the values changed. Map the columns once and Lemtika renders the whole file on every trigger, on-brand and identical, whether you press the button or an event does.

Make your next post look designed

Be first in line when we open up.

Join the waitlist