Skip to content
All guides

Administration · Updated August 31, 2026

Data Export

Three different ways a file leaves Bohari, what each one contains, and the rules that keep a spreadsheet from mangling or executing what's in it.


Three exports, not one

People say "export" about three different things here, and it helps to know which you're reaching for:

  1. The Export button on a list screen builds a CSV in your browser from the rows in front of you. No round trip, nothing queued.
  2. Two report screens ask the server for a file, in CSV or Excel, because the server holds totals and rows the page doesn't.
  3. The Data Export page queues a request, a background worker builds a bundle, and you download it when it's done. It exists for data-subject and record-keeping requests rather than day-to-day work.

The Export button on list screens

Eleven list screens carry it: Items, Stock on hand, Movements, Recipes, Stock counts, Transfers, Waste notes, Purchase orders, Suppliers, the Invoice queue and Outstanding.

What you get is what you see. The rows are the same filtered set the table is showing, in the same order, with the columns declared for that screen, so the file matches the filters in front of you without an endpoint re-implementing each screen's logic. Hover the button and the tooltip tells you the count before you click ("Download the 42 rows shown, as CSV"). With nothing to show, the button is disabled and pressing it would say "Nothing to export". The file is named after the screen and the day, such as stock-on-hand-2026-08-31.csv.

The file itself follows a few rules worth knowing when you open it:

  • It's UTF-8 with a byte-order mark at the front. Without that mark, Excel on Windows reads the file in the system codepage and mangles every accented item name.
  • Lines end in CRLF and quoting follows RFC 4180, so anything containing a comma, quote or newline is wrapped and inner quotes are doubled.
  • A cell beginning with =, +, -, @, a tab or a carriage return is prefixed with an apostrophe, which Excel strips on display. Spreadsheets execute such cells as formulas, and item and supplier names are typed by people; a supplier called =cmd|... is an attack on whoever opens the file.
  • Plain numbers are left alone, including negative ones, which begin with -. A variance is negative exactly when stock went missing, and turning -1234.5 into text would break the arithmetic the export exists for.

Nothing is forced to text with ="...", so the file stays readable to every other tool, including this app's own importers. The obvious use of an export here is to edit it and import it back.

One honest cost of the design: each screen's export columns are declared beside its table, so a column newly added to a screen doesn't automatically join its file. If a figure you can see on screen is missing from the download, that's why, and it's worth reporting rather than working around.

The Audit Log has its own Export CSV with the same apostrophe rule; see Audit Log.

Server-built report exports

The Variance report and the Reports overview use a different button that offers CSV or Excel (.xlsx). The server renders these because it owns things the page doesn't: a coverage footer, a valued-rows total, a second table stacked under the first. In Excel each table becomes its own sheet with a header row, an autofilter and the totals under the last one; in CSV the tables stack with a blank line between them.

The same defusing and byte-order-mark rules apply. A file is capped at 50,000 rows, and a bigger request is refused up front: "Export limited to 50,000 rows. Narrow your date range or filters." A format the endpoint doesn't offer is refused the same way, at the moment of asking. PDF is deliberately not on the list until a screen offers one whose output someone has actually looked at.

The Data Export page

Under Settings you'll find Data Export. The page opens for someone holding both export_reports and manage_users; the API behind it needs export_reports and the Data Export module, which the Professional and Enterprise plans include.

New Export asks two questions. The type is compliance, and today that's the only choice: it bundles your compliance documents (id, holder, type, name, status, issued and expiry dates). Other subjects were removed when the tables behind them went. The format is CSV, JSON or XLSX; anything else is refused when you ask rather than after the wait, which is what happened to PDF before it was taken off the list.

A request moves through five states, shown as a badge on the list:

StatusMeaning
pendingQueued, not picked up yet
processingA worker is building the bundle (three attempts, with backoff)
completedReady; the download icon appears
failedGave up, or you cancelled it. The row keeps the reason
expiredOlder than seven days; the file has been removed

You can cancel a request while it's pending or processing; anything else gets "Can only cancel pending or processing exports". A cancel that lands while the worker is mid-build wins, and the half-made file is discarded.

The download is named export-compliance-2026-08-31.csv (or .json, .xlsx). The bundle is stored once as JSON and shaped into your chosen format when you fetch it, so the same request can't produce different data in different formats. Files are kept for seven days; a later attempt answers "Export has expired", and a nightly job marks such rows expired and removes the file. Request it again if you still need it.

One rule that's easy to miss: a company whose subscription is suspended is read-only, and creating or cancelling an export is deliberately still allowed. A customer in a billing dispute can always retrieve their own records.

FAQ

Why is the only export type "compliance"? Because it's the only subject with a live table behind it. The earlier types queried data the platform no longer holds and either failed or reported success over zero records, so they were removed rather than left to mislead. For stock, procurement and recipes, use the Export button on the relevant list screen.

I downloaded an export last week and the link doesn't work now. Exports live for seven days. After that the row reads expired and the file is gone; request a new one.

Why does a name in my spreadsheet start with an apostrophe? Because it began with a character a spreadsheet would run as a formula, and the apostrophe defuses it. Excel hides the apostrophe; some other tools show it. Nothing about the underlying record changed.

Why did the export only include some of the rows? The list-screen export takes exactly what the screen is showing. Check the filters; a search box or an outlet picker narrows the file as much as the table. The server-built reports are capped at 50,000 rows and tell you if you've hit it.

We're suspended. Can we still get our records out? Yes. Creating and cancelling an export are the two writes a suspended account is still permitted, and the download is a read.