# Export

> Package `@umriss-ui/table`, version 0.40.0. Demo page: <https://romanhaendler.github.io/umriss-ui/table/export/>. Every page in one line: [llms.txt](https://romanhaendler.github.io/umriss-ui/table/llms.txt); every page in full: [llms-full.txt](https://romanhaendler.github.io/umriss-ui/table/llms-full.txt).

A button that writes the rows the user sees into a CSV file for a spreadsheet (also called download or export to Excel). Hand the application the text instead where it wants the clipboard or a file of its own.

```ts
import { Export } from "@umriss-ui/table";
```

Demo page: https://romanhaendler.github.io/umriss-ui/table/export/

It writes the filtered set across all pages, in the visible columns, in the order and sorting on screen – and the values, not their presentation: numbers with the decimal mark of the formats, yes and no from the wording, a point in time as a timestamp, an absent value as an empty field. The separator follows the mark – a comma, or a semicolon where the mark is a comma – and a byte order mark tells the spreadsheet it is UTF-8. English gets commas and a point; the German wording and formats from `@umriss-ui/core/wording/de` get the file the table always wrote, and German wording with English formats gets German words with comma and point – take both halves ([ADR-0061](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0061-the-csv-follows-the-language-in-use.md)).

A verdict column exports its value, not the verdict. In [server mode](https://romanhaendler.github.io/umriss-ui/table/server-mode/) the table holds one page of the server's, so it exports that page, and the button says so. The same text is `t.asCsv()`, without a button.

Ctrl or Cmd with C copies the selected rows – the visible columns under a header line, tab-separated, with the same values and the formats' decimal mark – and in a grid with no selection the Active cell. What was copied flashes once in an accent tint (shown without the fade under reduced motion), and a screen reader is told how many rows were copied, or that the copy failed. Marked text and a focused field keep the browser's own copy; in an open cell editor with nothing marked the key copies the value that stands in the field. `t.selectionAsText()` is the same text for a button of your own, as in the last example.

## Examples

### Download a file

Put an `Export` into the toolbar: the file holds what the user sees – the filtered, sorted rows of every page, in the visible columns.

```tsx
import { Export, Search, Toolbar, useTable } from "@umriss-ui/table";

interface Shipment {
  id: string;
  customer: string;
  parcels: number;
  weight: number;
}

const SHIPMENTS: Shipment[] = [
  { id: "FP-1004210", customer: "Holloway Garden Supplies", parcels: 3, weight: 23.5 },
  { id: "FP-1004223", customer: "Northgate Florists", parcels: 6, weight: 41.25 },
  { id: "FP-1004236", customer: "Pellham Hardware", parcels: 1, weight: 4 },
  { id: "FP-1004249", customer: "Northbay Books", parcels: 2, weight: 18.4 },
];

export default function DownloadAFile() {
  const { Table, Column } = useTable(SHIPMENTS, { rowKey: (s) => s.id });

  return (
    <Table ariaLabel="Shipments">
      <Toolbar>
        <Search placeholder="Search customer" />
        <Export filename="shipments.csv" />
      </Toolbar>
      <Column value="id" label="Shipment" rowHeader />
      <Column value="customer" label="Customer" />
      <Column value="parcels" label="Parcels" />
      <Column value="weight" label="Weight (kg)" format={{ decimals: 2 }} />
    </Table>
  );
}
```

### Take the text

Pass `onExport` to receive the CSV text instead of a download – for the clipboard or a service; values, not their presentation.

```tsx
import { useState } from "react";
import { Stack, Text } from "@umriss-ui/core";
import { Export, Toolbar, useTable } from "@umriss-ui/table";

interface Shipment {
  id: string;
  weight: number;
  delivered: Date | null;
  signed: boolean;
}

const SHIPMENTS: Shipment[] = [
  { id: "FP-1004210", weight: 23.5, delivered: new Date(Date.UTC(2026, 2, 17, 8, 12)), signed: true },
  { id: "FP-1004223", weight: 14, delivered: null, signed: false },
];

export default function TakeTheText() {
  const [text, setText] = useState("Not exported yet.");
  const { Table, Column } = useTable(SHIPMENTS, { rowKey: (s) => s.id });

  return (
    <Stack gap={3}>
      <Table ariaLabel="Shipments to export">
        <Toolbar>
          <Export onExport={setText} />
        </Toolbar>
        <Column value="id" label="Shipment" rowHeader />
        <Column value="weight" label="Weight (kg)" />
        <Column value="delivered" label="Delivered" format="dateTime" />
        <Column value="signed" label="Signed" />
      </Table>
      <Text as="pre" size="xs" mono>
        {text}
      </Text>
    </Stack>
  );
}
```

### Copy the selection

Ctrl or Cmd with C copies the selected rows, tab-separated under a header line, and they flash once; `selectionAsText()` hands the same text to a button of your own.

```tsx
import { Button, Stack, Text } from "@umriss-ui/core";
import { useTable } from "@umriss-ui/table";

interface Shipment {
  id: string;
  customer: string;
  weight: number;
}

const SHIPMENTS: Shipment[] = [
  { id: "FP-1004210", customer: "Holloway Garden Supplies", weight: 23.5 },
  { id: "FP-1004223", customer: "Northgate Florists", weight: 41.25 },
  { id: "FP-1004236", customer: "Pellham Hardware", weight: 4 },
];

export default function CopyTheSelection() {
  const t = useTable(SHIPMENTS, { rowKey: (s) => s.id });
  const { Table, Column } = t;

  return (
    <Stack gap={3}>
      <Stack direction="row" gap={2} align="center">
        <Button size="sm" variant="secondary" onClick={() => void navigator.clipboard.writeText(t.selectionAsText())} disabled={t.selection.count === 0}>
          Copy as table
        </Button>
        <Text size="xs" tone="muted">
          {t.selection.count} selected
        </Text>
      </Stack>
      <Table selectable ariaLabel="Shipments to copy">
        <Column value="id" label="Shipment" rowHeader />
        <Column value="customer" label="Customer" />
        <Column value="weight" label="Weight (kg)" />
      </Table>
    </Stack>
  );
}
```

## Keyboard

The keys of [First table](https://romanhaendler.github.io/umriss-ui/table/first-table/#keyboard-first-table), [Input](https://romanhaendler.github.io/umriss-ui/core/input/#keyboard-input) and [Button](https://romanhaendler.github.io/umriss-ui/core/button/#keyboard-button) apply here.

## API

### `ExportProps`

| Prop | Type | Default | Description |
|---|---|---|---|
| `filename` | `string` | the wording's "table.csv" | File name of the download.<br>Shown in: [Download a file](https://romanhaendler.github.io/umriss-ui/table/export/#download-a-file), [Set wording and formats once (Provider)](https://romanhaendler.github.io/umriss-ui/table/provider/#provider), [Search takes the line (Search)](https://romanhaendler.github.io/umriss-ui/table/search/#search-takes-the-line) and 6 more |
| `size` | [`ToolbarSize`](https://romanhaendler.github.io/umriss-ui/table/export/#type-ToolbarSize)<br>`"sm" \| "md"` | the size of the toolbar it stands in, `"sm"` outside one | The size of the part: `sm` or `md`.<br>Shown in: [Parts outside a toolbar (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#parts-outside-a-toolbar) |
| `of` | [`TableRef`](https://romanhaendler.github.io/umriss-ui/table/export/#type-TableRef) | — | The table, when the part does not stand inside it: the return value of `useTable`.<br>Shown in: [Place it outside the table (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#place-it-outside), [Parts outside a toolbar (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#parts-outside-a-toolbar), [Review cost centres against budget (Scenarios)](https://romanhaendler.github.io/umriss-ui/table/#review-cost-centres) |

#### Events

| Prop | Type | Default | Description |
|---|---|---|---|
| `onExport` | `(text: string) => void` | — | Gets the text instead of triggering a file.<br>Shown in: [Take the text](https://romanhaendler.github.io/umriss-ui/table/export/#take-the-text), [Sort and export a value that is an object (Sorting)](https://romanhaendler.github.io/umriss-ui/table/sorting/#own-ordering) |

### Types on this page

#### `ToolbarSize`

The size of a toolbar's controls.

```ts
type ToolbarSize = "sm" | "md";
```

#### `TableRef`

What a part without a row type needs from a table – for `of`.

```ts
type TableRef = Omit<TableSnapshot<unknown>, "setFilter" | "conditionOf"> & {
  readonly Table: unknown;
  /** Without a row kind: any id, any condition. */
  setFilter(column: string, condition: unknown): void;
};
```

## Known limits

- One format, CSV: no workbook, PDF or print layout.

What umriss deliberately does not build, and why: [ADR-0032](https://romanhaendler.github.io/umriss-ui/what-umriss-ui-is-not/).
