# ElixlsxView


This library is used to render data as xlsx documents in phoenix
views.
## Instalation
Add the library into your `deps/0`:
```elixir
defp deps do
[
{:elixlsx_view, "~> 0.1"}
]
end
```
Documentation can be found on [HexDocs](https://hexdocs.pm/elixlsx_view)
## Usage
First you need to register mime type for xlsx and configure phoenix
to use this library to manage rendering. Add this to your
`confix.exs`:
```elixir
config :mime, :types, %{
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" =>
["xlsx"]
}
config :phoenix, :format_encoders,
xlsx: ElixlsxView.Encoder
```
After configuration is done, you can use it like you do with any
other mime type (i.e. json or html), but the view function needs to
return `%Elixlsx.Workbook{}` struct instead of a simple map like in
json view.
> **Note:** You probably don't need to do content negotiation and
> instead of `plug accept, ["xlsx"]` put `plug put_format, "xlsx"`
> in your pipeline.
## Example
Here goes an example of application with xlsx endpint.
```elixir
defmodule MyApp.Report do
@moduledoc false
def generate do
[
%{name: "John", number: 1},
%{name: "Phil", number: 2},
%{name: "Zak", number: 3}
]
end
end
```
```elixir
defmodule MyAppWeb.Router do
@moduledoc false
use MyAppWeb, :router
pipeline :xlsx do
plug :put_format, "xlsx"
end
scope "/", MyAppWeb do
pipe_through [:xlsx]
get "/report", ReportController, :generate
end
end
```
```elixir
defmodule MyAppWeb.ReportController do
@moduledoc false
use MyAppWeb, :controller
alias MyApp.Report
def generate(conn, _params) do
report = Report.generate()
render(conn, :report, report: report)
end
end
```
```elixir
defmodule MyAppWeb.ReportView do
@moduledoc false
use MyAppWeb, :view
alias Elixlsx.{Sheet, Workbook}
alias ElixlsxView.Style
@styles [
title: [size: 14, bold: true],
name: [italic: true],
number: [bg_color: "#aaa"]
]
def render("report.xlsx", %{report: report}) do
%Workbook{sheets: [render_sheet(report)]}
end
defp render_sheet(report) do
%Sheet{}
|> Sheet.set_at(0, 0, "Name", classes: [:title])
|> Sheet.set_at(0, 1, "Number", classes: [:title])
|> put_rows(report)
|> Style.apply(@styles)
end
defp put_rows(sheet, report) do
{sheet, _} =
Enum.reduce(report, {sheet, 1}, fn
%{name: name, number: number}, {sheet, row} ->
sheet =
sheet
|> Sheet.set_at(row, 0, name, classes: [:name])
|> Sheet.set_at(row, 1, number, classes: [:number])
{sheet, row + 1}
end)
sheet
end
end
```