Packages

Rapport aims to provide a robust set of modules to generate HTML reports that both looks good in the browser and when being printed.

Current section

Files

Jump to
rapport lib rapport.ex
Raw

lib/rapport.ex

defmodule Rapport do
@moduledoc """
Documentation for Rapport.
"""
@normalize_css File.read!(Path.join(__DIR__, "normalize.css"))
@paper_css File.read!(Path.join(__DIR__, "paper.css"))
@base_template File.read!(Path.join(__DIR__, "base_template.html.eex"))
defstruct template: nil, paper_size: nil, rotation: nil, fields: nil, title: nil
def new(template, paper_size \\ :A4, rotation \\ :portrait)
when is_binary(template) and is_atom(paper_size) and is_atom(rotation) do
template_content = template_content(template)
validate_paper_size(paper_size)
validate_rotation(rotation)
%Rapport{
template: template_content,
paper_size: paper_size,
rotation: rotation,
fields: %{},
title: "Report"}
end
def set_field(%Rapport{} = report, field_name, field_value) when is_binary(field_name) do
set_field(report, String.to_atom(field_name), field_value)
end
def set_field(%Rapport{} = report, field_name, field_value) when is_atom(field_name) do
fields = report.fields |> Map.put(field_name, field_value)
Map.put(report, :fields, fields)
end
def set_title(%Rapport{} = report, title) when is_binary(title) do
Map.put(report, :title, title)
end
def generate_html(%Rapport{} = report) do
content = EEx.eval_string report.template, assigns: report.fields
paper_settings = paper_settings_css(report)
assigns = [
content: content,
title: report.title,
paper_settings: paper_settings,
normalize_css: @normalize_css,
paper_css: @paper_css]
EEx.eval_string @base_template, assigns: assigns
end
defp paper_settings_css(%Rapport{} = report) do
paper_size = Atom.to_string(report.paper_size)
rotation = Atom.to_string(report.rotation)
if rotation == "portrait", do: paper_size, else: "#{paper_size} #{rotation}"
end
defp validate_paper_size(paper_size) do
allowed_paper_sizes = [:A4, :A3, :A5, :half_letter, :letter, :legal, :junior_legal, :ledger]
msg = "Invalid paper size"
if paper_size not in allowed_paper_sizes, do: raise ArgumentError, message: msg
end
defp validate_rotation(rotation) do
allowed_rotations = [:portrait, :landscape]
msg = "Invalid rotation"
if rotation not in allowed_rotations, do: raise ArgumentError, message: msg
end
defp template_content(template) do
if (File.exists?(template)), do: File.read!(template), else: template
end
end