ElixlsxView

This library is used to render data as xlsx documents in phoenix views.

Instalation

Add the library into your deps/0:

defp deps do
[
{:elixlsx_view, "~> 0.1"}
]
end

Documentation can be found on HexDocs

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:

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.

defmodule MyApp.Report do
@moduledoc false
def generate do
[
%{name: "John", number: 1},
%{name: "Phil", number: 2},
%{name: "Zak", number: 3}
]
end
end
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
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
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