Masu.Export (Masu v0.1.0)

Copy Markdown View Source

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.

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.

Summary

Functions

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

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.

Types

format()

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

t()

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

Functions

stream(export, format \\ :csv)

@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(export, format, path, opts \\ [])

@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.