Documentation
Tutorials
Workflows
Kebab actions
Daily Work
Dashboard & Reports
Quality Control
ISO 17025
Logs
Contacts
Billing
Analysis Setup
Settings
Initial Setup
Help & Reference
Architecture decisions
Kebab actions
0:000:00

Export the samples grid to CSV

This recipe describes how to export a filtered subset of samples to a CSV file, so you can process it in a spreadsheet for batch analysis, customer reports, or accreditation submissions.


Goal

Produce a CSV file that contains exactly the samples currently shown in the grid after filters have been applied — ready for downstream processing outside the LIMS.


Prerequisites

  • You are signed in with read access to samples (any role that can open the /samples page).
  • You have an application that opens .csv files (Excel, LibreOffice Calc, Google Sheets, etc.).

Steps

  1. Navigate to the Samples page (/samples) from the side navigation.
  2. Open the filter panel via the filter icon in the title bar and apply the criteria you want:
  • Date range for received or due dates (receivedDate, dueDate).
  • Sample status (e.g. RECEIVED, IN_PROGRESS, REPORT_READY, SUBCONTRACTED).
  • Customer (contact picker with type-ahead search).
  • Lab method, instrument, assigned analyst, crop, municipality / city / toponym.
  1. Optionally, use the search box or sort by a column to further narrow or reorder the result set. The sort order carries over verbatim into the CSV file.
  2. Click the CSV download icon in the title bar (next to the print icon).
  3. The browser automatically downloads a file named samples-YYYYMMDD-HHmmss.csv. Open it in your spreadsheet of choice.
The exported columns are exactly those you have marked as visible via the column configuration — hidden columns and the actions column are skipped. If you need extra fields in the export, surface those columns first via the column-configuration dialog.

What happens behind the scenes

The CSV button calls the fetchAndExportCsv helper (libs/utils/src/lib/csv-export.ts:82), which re-issues the findAllSamples GraphQL query with take = 0 and skip = 0 — that is, it asks for every row that matches the current filter and sort state, without paging. The wiring lives in apps/agrometrisis/src/app/samples/sample.ts:2946 (onExportCsv()), where the current gridState() (filter text, sort column, sort order) and the allColumns definition are passed in.

The result is serialised to CSV entirely in the browser: visible columns are selected, field values are escaped (" doubled), nested GraphQL relation objects (e.g. contact, labMethod) are resolved to human-readable strings, and ISO timestamps are truncated to YYYY-MM-DD. The file is prefixed with  (UTF-8 BOM) so Excel renders Greek characters correctly. No backend storage is involved — the file is built and downloaded purely through Blob + URL.createObjectURL.


Tips & notes

  • The query runs against every row that matches the filters — it is not restricted to the current page of the grid. Don't hesitate to pull hundreds or thousands of rows in a single click.
  • For very large result sets (e.g. >20,000 rows) prefer a narrower date filter for faster response.
  • If Greek characters look garbled when you open the CSV in Excel, make sure you open the file via File → Open (not double-click on older versions) so that the UTF-8 BOM is honoured.
  • Date columns are emitted in ISO format (YYYY-MM-DD). Excel will recognise them as real dates and let you sort or pivot directly.
  • The export captures the current gridState() at the moment you click the icon. If you change filters mid-export, simply re-click to regenerate the file.
  • Files are timestamped to the second, so consecutive exports never overwrite each other in your downloads folder.

The same CSV export pattern is wired into every grid page in the app — Contacts, Analyses, Invoices, Instruments, Control samples, Deviations, CAPA, Training records, and more. Each list page exposes the same CSV icon in its title bar, the same filter panel, and the same exportToCsv / fetchAndExportCsv plumbing.

See apps/agrometrisis/src/app/contacts/contact.ts:765 (onExportCsv()) as a parallel example for contacts — the only differences are the GraphQL query name (findAllContacts) and the extras block fed to the service. Once you learn the flow on one grid, you know them all.