Automated Invoice & Delivery-Note PDFs — Documents as Code

Breaking free from template files: generating invoice and delivery-note PDFs in code, from Japanese text support to storage

請求書PDF生成pdf-lib帳票自動化
6 min read

Introduction

Invoices, delivery notes, debit notes — plenty of teams still produce these by hand, opening an Excel or Word template and typing numbers into the cells one by one. Sound familiar?

The import wholesale operation I worked on was exactly like that. For every transaction, you opened a template, copied over the amounts, and exported a PDF. The more transactions you handle, the more this routine wears you down like body blows.

This article walks through the overall approach we took to break free from that template-based workflow and generate documents mechanically from data instead. The tool of choice was a JavaScript library called pdf-lib.

The Limits of Template-Based Workflows

Tribal knowledge and transcription errors

Template-based workflows are easy to start. But as you keep at it, problems quietly pile up.

The scariest one is transcription errors. You paste the amount into a cell that's off by one, the tax formula quietly breaks, or the recipient's company name is left over from the previous customer. On financial documents, mistakes like these are fatal.

The other is tribal knowledge — the state where "only that one person knows how to touch that file." The moment they take a day off, the work grinds to a halt.

The "sediment" that copy-based workflows create

Another trap of template workflows is that file copies multiply without end.

Template workflow vs. code generation
BEFORE
Copy a template each time

Files proliferate per transaction. You lose track of which is the latest, and sometimes send an outdated format by accident.

Break free
AFTER
Generate from data every time

The document is really just data. The format lives in code, so every document comes out at consistent quality.

Keep piling on copies — "let me base this on last month's invoice..." — and you end up with a "sediment" of mismatched format versions. Getting out required a shift in thinking.

The Idea of Generating Documents in Code

Separating "format" from "data"

The heart of this approach is to think of a document as format plus data.

In an Excel template, the format and the data are mixed into a single file. That's exactly why it breaks every time you touch it. With code generation, the format lives in code (a layout definition) and the data lives in a database — kept separate.

To produce a document, you simply combine the two and emit a PDF. Want to change the format? Fix one place in the code, and it applies to every document from then on. That's the decisive difference from a manual workflow.

Rendering with pdf-lib

For the actual generation we used pdf-lib, a library that builds PDFs directly and runs both in the browser and on the server (Node.js).

Document generation flow
Gather the data

Prepare transaction data, line items (SKU, quantity, unit price), and recipient info.

Pour it into the layout

Place the title, recipient, line-item table, totals, and bank details by coordinates in code.

Generate the PDF bytes

pdf-lib assembles the PDF binary.

Store and send

Save the generated PDF and download or send it as needed.

Since you specify text positions and rules by coordinate, the initial setup takes effort — but once it's built, you only change the data. You can emit hundreds of documents at identical quality.

Making line-item entry efficient

The most laborious part of a document's contents is building the line items — filling in "which product, how many, at what price" row by row.

Here we introduced a SKU lookup cache. Once a product code (SKU) has been looked up, its details are kept on hand, so entering the same SKU again pulls it up instantly without another search. Assembling line items got faster, and it reduced stress for the person doing the entry.

Document Types and the Payoff of Automation

Invoices, delivery notes, and debit notes

In import wholesale, you don't deal with just one kind of document.

Produce these separately by hand and the line items tend to diverge. Generate them from the same data, and the invoice and delivery note automatically match.

The "consistency" that pays off

The obvious payoff of automation is time saved, but the one I felt most strongly was consistency.

Humans inevitably make mistakes. That's exactly why I believe in shifting toward mechanisms where mistakes simply can't happen.

Conclusion

From manual template work to mechanical generation from data. This shift wiped out, all at once, the chronic pains of document workflows: transcription errors, tribal knowledge, and format drift.

That said, generating documents in code means clearing a few hurdles. Each is explored in its own article, so do read on.