Current section
Files
Jump to
Current section
Files
lib/elixlsx.ex
defmodule Elixlsx do
@moduledoc ~S"""
Elixlsx is a writer for the MS Excel OpenXML format (`.xlsx`).
# Quick Overview
The `write_to/2` function takes a `Elixlsx.Workbook` object
and a filename. A Workbook is a collection of `Elixlsx.Sheet`s with
(currently only) a *creation date*.
See the example.exs file for usage instructions.
# Hacking / Technical overview
XLSX stores potentially repeating values in databases, most
notably `sharedStrings.xml` and `styles.xml`. In these databases,
each element is assigned a unique ID which is then referenced
later. IDs are consecutive and correspond to the (0-indexed)
position in the database (except for number/date formattings,
where the ID is explicitly given in the attribute and needs to
be at least 164).
The sharedStrings database is built up using the
`Elixlsx.Compiler.StringDB` module. Pre-compilation, all cells
are *folded* over, producing the StringDB struct which assigns
each string a unique ID. The StringDB is part of the
`Elixlsx.Compiler.WorkbookCompInfo` struct, which is passed to
the XML generating function, which then `get_id`'s the ID
associated with the string found in the cell.
For `styles.xml`, the procedure is in general the same, but slightly
more complicated since elements can reference other elements in
the same file. The `Elixlsx.Style.CellStyle` element is the
combination of sub-styles (`Elixlsx.Style.Font`, `Elixlsx.Style.NumFmt`,
...). A call to register_all creates the (unique) entries in the
sub-style databases (`Elixlsx.Compiler.FontDB`, `Elixlsx.Compiler.NumFmtDB`).
Afterwards, each unique combination of substyles is assigned an ID
in `Elixlsx.Compiler.CellStyleDB`. During XML generation, the <xf>
elements reference the individual sub-style IDs, and the actual cell
element references the <xf> id.
"""
@doc ~S"""
Write a Workbook object to the given filename.
"""
@spec write_to(Elixlsx.Workbook.t(), String.t()) :: {:ok, String.t()} | {:error, any()}
def write_to(workbook, filename) do
wci = Elixlsx.Compiler.make_workbook_comp_info(workbook)
:zip.create(to_charlist(filename), Elixlsx.Writer.create_files(workbook, wci))
end
@doc ~S"""
Write a Workbook object to the binary.
Returns a tuple containing a filename and the binary
"""
@spec write_to_memory(Elixlsx.Workbook.t(), String.t()) ::
{:ok, {charlist, binary}} | {:error, any()}
def write_to_memory(workbook, filename) do
wci = Elixlsx.Compiler.make_workbook_comp_info(workbook)
:zip.create(to_charlist(filename), Elixlsx.Writer.create_files(workbook, wci), [:memory])
end
end