Data Extraction in n8n with changing layouts: lessons from multiple purchase order formats

:waving_hand: Hey n8n community,

Quick follow up to my Purchase Order extractor post (that one here). It worked great on the two POs I built it against. Then my friend forwarded three more from different suppliers and things got interesting.

This is the part of document processing nobody warns you about. Your pipeline isn’t done when it works on your test files. It’s done when it survives the next layout you’ve never seen. And in a real business, new layouts arrive constantly, every supplier, every hotel group, every ERP exports its own thing. One PO has the number in a top-right box labelled “PO Number”. The next calls it “Order Number” in a completely different table. One has a Net column, another calls it Cost, another calls it Total. Same information, nothing in the same place, nothing with the same label.

Here’s what surprised me though: the extraction itself never broke. Not once across four layouts. That’s because the easybits extractor works off context rather than coordinates, so I describe what the field is (“the order number in the header, not the requisition number below it”) instead of where it sits. Move it, rename it, restyle it, it still finds it. If I’d built this with positional templates I’d have needed a new template per supplier, which is exactly the maintenance treadmill I was trying to avoid.

What did break was my own code downstream. Every single time. Two examples:

The apostrophe. One supplier writes 1’550.00 for one thousand five hundred fifty. My parser saw the apostrophe, choked, and mangled the number. The extractor read it perfectly, I just couldn’t parse what it handed me.

The dot. This one nearly got me. Another PO showed quantities as 5.000 and I was convinced it meant five thousand, so I “fixed” my parser to strip the dot as a thousands separator. Wrong. It was SAP-style formatting and it meant five. The giveaway was the document’s own arithmetic: 5 x 105 = 525, which matched the printed line total and the net total at the bottom. Read as thousands, nothing added up. Lesson: when a number looks ambiguous, the document usually tells you the answer somewhere, check the totals before you touch the code.

So my takeaway from the whole exercise: with context-based extraction, layout variation is mostly a solved problem. The fragile part moves downstream to the boring stuff, number formats, separators, currency prefixes. That’s where I’d spend the hardening time on your next build.

Sanitised workflow JSON is on GitHub if you want to try the Purchase Order extractor yourself, feel free to grab it here:

I’ve attached shots of the different layouts (anonymized, of course), so you can see how little they have in common. How are you handling layout drift on your document workflows?

Best,
Felix

1 „Gefällt mir“

the extractor is only half the system. the safer pattern is to normalize every returned value before it reaches business logic, especially numbers, dates, and currency symbols. i would keep the raw extraction beside the normalized record, then run validation rules for required fields, plausible ranges, and supplier specific formats. anything that fails should enter a review queue instead of being silently corrected. for numbers, store the original string and the parsed decimal so you can trace a bad conversion later. a small fixture set with one document per supplier is also useful for regression testing when the parser changes.

1 „Gefällt mir“

Hey @Long_Vu_Nguyen, thanks so much for the feedback!

I don’t know if you’ve seen my latest post yet, but I’ve already released a second version of the PO workflow. It now includes improved validation for fields that couldn’t be extracted correctly, duplicate PO number detection to prevent the same document from being processed twice, and I’m currently collaborating with another builder who created a tool for logging extracted values before they reach downstream business systems. That makes it much easier to trace where every piece of data originated if something ever needs to be audited or debugged.

If you’re interested, feel free to check it out here: