Worth thirty seconds before you upload. Knowing the edges up front beats finding them afterwards.
Every job here starts by cleaning the file — the shapes below are what that step can and can't read, so they apply just as much to a Xero conversion or a dashboard as to a tidy-up.
| A list with column names | The ordinary case. A header row, then one row per thing that happened — transactions, sales, invoices, timesheets, hours. |
| A list with no column names | Fine. The columns get numbered in the order they appear, and the report says so rather than inventing names for them. |
| Periods across the top | Budgets and forecasts laid out as a grid — categories down the side, months or years across the top. You get the trend, and a tidy one-row-per-month tab in the download. |
| Many sheets in one file | Every sheet is read, not just the first. Any we can't read is named with its row count, so nothing disappears quietly. |
| A proper mess | Merged cells, three date formats in one column, currency symbols, bracketed negatives, totals pretending to be data, blank spacer rows, headers buried under a title banner. That's the job. |
| Dashboards and summaries | A page of labels and formulas pointing at other cells isn't a table. We'd rather say we can't read it than turn a layout into a confident-looking table of nonsense. |
| Several tables on one sheet | Two blocks side by side read as one wide table, and the second block turns up as extra columns. Visible and imperfect, which beats invisible. |
| Files over 10MB | The cap is what lets us promise nothing is stored — see Privacy. A bigger cap would mean real storage, and a different answer on that page. |
If your file is sales — a booking system export, a POS report, a spreadsheet you keep by hand — Convert builds a CSV in Xero's invoice import format. Supplier bills too, against their own template: a bill is not an invoice with the direction flipped, and a file built on that assumption is one Xero rejects outright. Give us the account code and tax rate from your own Xero, because those live in your chart of accounts and we won't guess at them.
Better still, export your chart of accounts from Xero (Accounting → Chart of accounts → Export) and attach it. Then a code stops being something only you can check: we name the account back to you — 429 — General Expenses — and refuse the export outright if the code isn't in your chart. That last part matters, because Xero silently discards an account code it doesn't recognise and imports the file anyway. Right totals, correct grouping, and bills nobody can approve. It's optional, and without one we say we couldn't check rather than letting an absence look like a tick.
Rows sharing an order or reference number become one invoice, and we tell you which rule we used rather than deciding quietly. Your own invoice numbers pass through untouched; anything we generate carries a prefix you choose, so it can't collide with numbering you already use. They arrive in Xero as drafts, so nothing reaches your ledger until you approve it.
There's no connection to your Xero and no login — we never see your account. You download a file and import it yourself.
Twelve monthly exports are one year's data in twelve files. Merge stacks them into one, matching the columns by name so Invoice Date and InvoiceDate are the same column, and every row carries the file it came from.
What it will not do quietly is the point. A column only some of your files carry is kept, blank on the rest, and named — dropping it is exactly the silent loss this is built against. A row that turns up in two files is reported and never removed, because two overlapping exports stack into a file that balances perfectly and states the same money twice, and only you know whether that repeat was deliberate.
Cleaning proves nothing was lost from one file. Compare says where two disagree — a statement against a ledger, a payout report against your own sales. Every row on both sides lands in exactly one bucket, and the money in the buckets is the money each file arrived with.
The result is stated as a signed sum — −25.00 − 180.00 + 90.00 =
−115.00 — because that's checkable on a calculator, and "25 short,
180 missing, 90 extra" hides the signs. Columns are paired by which
values actually overlap, never by name, since one system's
Invoice Number is another's Ref. Only the first sheet
of each file is compared: pairing nine sheets against seven would be a
guess about which goes with which.
De-identify swaps names, emails and phone numbers for sequential labels, so a CRM export can go to an AI or outside the business without your customers going with it. Dates, amounts and reference numbers are left alone — they're the reason the file is going anywhere, and your own invoice numbers mean nothing to an AI while letting you join any answer back against the copy you kept.
Labels are obviously synthetic — Customer 001, never a realistic-looking fake, because a plausible name gets acted on downstream. Nothing is hashed: an Australian mobile number can be enumerated in seconds, so a hash of one matches straight back. A name in a notes column is as identifying as one in a customer column, so every replaced value is hunted down across every other column, and so are its parts.
What we won't tell you is that the result is anonymous, safe, or "PII compliant". There's no such standard to be compliant with, and de-identified data becomes personal information again the moment someone can re-identify it. We'll tell you what was done, column by column, and name what we couldn't check.
Everything above works on whatever spreadsheet you have. Dashboards and Investor statements are the two that don't: each needs a particular file from a particular kind of business, and in exchange each knows what the columns mean rather than inferring it.
Dashboards covers gyms, cafes, trades and hair and beauty. Pick yours and you get a finished dashboard on invented numbers before uploading anything — then your own export redraws it. Investor statements takes a fund's workbook and returns a statement per investor for the month, plus the interest as a Xero bills CSV and a mail-merge file to send them from your own email. We never send anything on your behalf.
Both are free, like the rest of it, and neither stores your file.
It won't quietly drop a row. Every run tells you how many rows were read, how many were cleaned, how many were rejected and why — and the rejected ones come back in your download exactly as you sent them, so you can fix them and try again.
It won't guess at meaning either. Numbers that aren't quantities — invoice numbers, postcodes, years, percentages, unit prices — are never summed. Balances and running totals aren't summed either, because each row already contains the ones above it. If a column has no name in your file, it doesn't get one here.
And it won't tell you a story. Inspect is only arithmetic you could check by hand: totals, month-on-month change, share by category, outlier fences. Never a reason, never a cause, never a sentence explaining why a month was down — a confident line under a chart is more persuasive than anything we could justify from a spreadsheet. Every chart has a table beside it, and the bars have to add up to the table or it's a bug.
DataNinja is built and run by one person in Australia — a data analyst who spent too many years re-typing other people's spreadsheets, and got tired of tools that cleaned data without ever showing their working.
That's why every report leads with the reconciliation rather than the charts. If a number here is wrong, you should be able to catch it, and then tell me so I can fix it. hello@dataninja.au reaches me directly.