Generate PDFs from Excel: Turn Every Row into a Branded Document
"Save as PDF" turns one spreadsheet into one ugly printout. What most teams actually need is the opposite: two hundred rows in, two hundred personalized documents out — invoices, certificates, letters, contracts. Here are the three ways to do it, from zero-code to fully automated, with a worked example.
Why the built-in options fall short
Excel's own PDF export prints the sheet — gridlines, cell references and all. It answers "how do I share this spreadsheet?", not "how do I turn each row into a document?". The classic workaround is Word mail merge: link a Word template to the sheet, merge, then print to PDF. It works, and it's also where the pain starts:
- Mail merge outputs one giant merged file by default — splitting it into per-recipient PDFs with correct filenames requires macros or paid add-ins.
- Layout control is Word's: fine for letters, fragile for anything designed — invoices with line-item tables, certificates, branded proposals.
- Nothing is automated. Every batch is a manual session of clicking through the merge wizard, and the person who knows the steps becomes the bottleneck.
- Data hygiene is on you: number formats, dates, and currency symbols come across raw, and a mis-mapped column goes unnoticed until a client replies.
The template-based approach flips the model: design the document once in a proper editor, treat the spreadsheet as pure data, and let the tool handle merging, splitting, naming, and delivery. In GJSDocs that looks like the following — the same template works for a single document, and for a batch of thousands via bulk generation.
Step 1: Build the template and map your columns
Create the document in the visual editor — or import an existing DOCX/PDF and make it editable. Everywhere a spreadsheet value belongs, insert a variable: type { and pick or create one. A typical invoice template ends up with a variable set like this:
- Client block: {client.name}, {client.email}, {client.address} — mapped from the "Name", "Email", "Address" columns.
- Invoice block: {invoice.number}, {invoice.date}, {invoice.due_date} — one column each; keep dates formatted as text in the sheet or format at generation time.
- Money block: {invoice.subtotal}, {invoice.tax}, {invoice.total} — computed in the spreadsheet (that's what it's good at), rendered by the template.
The convention to adopt on day one: one row = one document, one column = one variable, header row = variable names. If your sheet has merged cells, subtotals mixed into the data, or two tables side by side, spend ten minutes normalizing it first — every path below assumes a clean table.
Step 2: Pick your path from spreadsheet to PDFs
Path A — Google Sheets connection (zero code, live data)
If the workbook can live in Google Sheets (File → Import in Sheets takes .xlsx directly), connect it as a data source: map columns to template variables once, then generate from any row, selection, or the full sheet on demand. The connection stays live — next month's batch is the same two clicks against updated rows. Full walkthrough: auto-generate documents from Google Sheets.
Path B — Bulk generation from the file (best for one-off batches)
For a self-contained batch — export from an accounting system, a registration list, a year-end statement run — feed the tabular data to bulk generation directly: pick the template, match columns to variables (auto-matched when headers equal variable names), and run. Each row becomes its own finished PDF, named by a field you choose (invoice-{invoice.number}.pdf), ready to download or send.
Path C — REST API (for recurring pipelines)
When the spreadsheet is really an export from another system, skip the file and post the data. Any script that can read your rows (a few lines of Python or Node with a CSV/XLSX library) can call the generation endpoint per row:
POST /api/documents/generate
Authorization: Bearer YOUR_API_KEY
{
"templateId": "tpl_invoice_2026",
"format": "pdf",
"variables": {
"client.name": "Acme GmbH",
"invoice.number": "INV-2026-0142",
"invoice.date": "2026-07-07",
"invoice.total": "€2,340.00"
}
}Loop over rows, collect the returned PDFs, done — the API is available on every paid plan. Auth, error handling, and full request/response shapes are in the document generation API guide.
Worked example: 200 invoices from one workbook
A bookkeeping service invoices ~200 clients monthly from an Excel workbook: one row per client, columns for name, email, address, service lines, and formula-computed totals. Their old process — mail merge, manual PDF split, attach-and-send — took the better part of a day and produced a wrong-amount incident often enough to be a standing joke.
- One-time setup (~an hour): imported their existing invoice DOCX as a template, replaced 11 details with variables, moved the workbook to Google Sheets, and mapped columns.
- Monthly run now: update the sheet, select the month's rows, generate. Two hundred correctly named PDFs in minutes, each pixel-identical to the designed template.
- Errors dropped to spreadsheet-error level: since nobody retypes anything between the sheet and the PDF, the document is exactly as right as the data — and the data gets reviewed once, in one place.
The same pattern covers certificates from an attendee list, offer letters from an HR sheet, or policy renewals from a broker export — anything where the spreadsheet already knows everything the document needs to say. (More invoice-specific setups, including delivery automation, in the invoice automation guide.)
Excel mail merge vs. template-based generation
| Word mail merge | GJSDocs | |
|---|---|---|
| Separate PDF per row | Macros or add-ins | Built in, named by field |
| Design control | Word layout | Full visual editor |
| Repeat runs | Manual wizard each time | Reconnect & regenerate |
| Automation / API | None | REST API, Zapier, Make |
| Live data source | Static file link | Google Sheets, Airtable, CRM |
| Cost | Included with Office | Free plan; paid from $39/mo |
Honest bottom line: for a once-a-year batch of simple letters, mail merge you already own is fine. The switch pays for itself when batches recur, documents carry your brand, or the words "can we automate this?" have been said in a meeting.
FAQ
Can I upload an .xlsx file directly?
The most reliable route is through Google Sheets (which imports .xlsx natively) or CSV for bulk runs — both preserve the one-row-one-document model. If your workbook has formulas, they're computed in the spreadsheet before generation, so the template only ever sees final values.
How do line items work — multiple rows per invoice?
Two workable patterns: flatten line items into columns (item1, qty1, price1…) for a fixed maximum of lines, or pre-join them into a single formatted block per row. For fully dynamic tables, send line items as structured data via the API path, where the template can render repeating rows.
Can the PDFs be emailed out automatically?
Yes — pair generation with Zapier or Make.com: a scenario watches for new documents (or drives generation itself) and sends each PDF to the email address from its own row. The pattern is covered in the Zapier and Make.com guides.
What about DOCX output instead of PDF?
Every paid plan exports DOCX alongside PDF (plus HTML, Markdown, and JSON), so batches that need post-editing in Word — negotiated contracts, letters with manual additions — can generate as DOCX from the same template and data.
Related reading:
Turn your spreadsheet into documents
Build the template once, connect your rows, and generate the whole batch in minutes. Free plan — no credit card.
Start free