# `Masu.Export`
[🔗](https://github.com/hattoriai/masu/blob/v0.1.0/lib/masu/export.ex#L1)

A grid's rows as a file: CSV or XLSX, of every row of the person's
query (their order, filters and search), with the columns that show,
in their order, and their labels as the first row.

A grid with `export` has an Export menu. The file is not written in the
LiveView, nor sent over its socket: the menu gives the browser a link,
good once and for five minutes, to the route `Masu.Router.masu_exports/1`
mounts, and the browser downloads it from there as the rows are read, a
block at a time, with its own progress. See the [Export
guide](export.md).

An app exports a grid itself with `Masu.Live.export/1`, in the
LiveView: it gives the export as data, which `write/4` writes anywhere,
in a task or a background job, and `stream/2` streams, to a
controller's response, say:

    def handle_event("email_report", _params, socket) do
      export = Masu.Live.export("orders")
      Task.start(fn ->
        path = Path.join(System.tmp_dir!(), "orders.xlsx")
        :ok = Masu.Export.write(export, :xlsx, path)
        MyApp.Mailer.deliver_report(path)
      end)
      {:noreply, socket}
    end

The rows are read from the source a block at a time; an export of an
Ecto source never holds more than a block. Grouped rows and a tree's
rows are exported as rows, every one of them.

## Values

CSV: values as the browser gets them (numbers, decimals with their
digits, dates and times in ISO 8601, `true` and `false`), in UTF-8.
Text that starts with `=`, `+`, `-`, `@` or a tab starts with `'`, so
that a spreadsheet does not run it as a formula.

XLSX: numbers and decimals as numbers, dates, times and datetimes as
dates (in UTC), booleans as booleans, text as text. A column with
content of its own exports its value, not its HTML. A sheet has
1,048,576 rows at most (Excel's limit): an XLSX export stops there; a
CSV one does not.

# `format`

```elixir
@type format() :: :csv | :xlsx
```

# `t`

```elixir
@type t() :: %Masu.Export{
  all_columns: [Masu.Column.t()],
  columns: [Masu.Column.t()],
  input: term(),
  name: String.t(),
  opts: keyword(),
  query: Masu.Query.t()
}
```

# `stream`

```elixir
@spec stream(t(), format()) :: Enumerable.t()
```

The file of an export, a block of rows at a time (iodata): CSV, the
labels first, or XLSX.

# `write`

```elixir
@spec write(t(), format(), Path.t(), keyword()) :: :ok
```

Writes an export to `path`. Options: `:progress`, a function of the
rows written and the rows there are (nil while the source does not
know), called after each block.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
