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"}
]
endDocumentation 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"]putplug 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
enddefmodule 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
enddefmodule 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
enddefmodule 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