The development team at PumasAI is happy to announce the open-source release of two packages:
SummaryTables.jl for generating publication-ready tables in HTML, docx, LaTeX and Typst. We wrote SummaryTables from scratch because existing solutions for table generation like PrettyTables did not support all the table structures (for example merged cells) or output formats (docx, Typst) we needed. | |
WriteDocx.jl for generating Microsoft Word compatible docx files from scratch. We wrote WriteDocx to have a completely flexible and precisely adjustable backend for SummaryTables and report generation, without having to fall back to tools that do “lossy” conversions through intermediate markdown representations, like Pandoc. |
We hope that we can give back to the Julia community with the release of these packages and strengthen its utility ecosystem.
What follows is a short description both packages, for more please check out the documentation at
SummaryTables
SummaryTables.jl is a Julia package for creating publication-ready tables in HTML, docx, LaTeX and Typst formats. Tables are formatted in a minimalistic style without vertical lines.
SummaryTables offers the table_one
, summarytable
and listingtable
functions to generate pharmacological tables from Tables.jl-compatible data structures, as well as a low-level API to construct tables of any shape manually.
Examples
data = DataFrame(
sex = ["m", "m", "m", "m", "f", "f", "f", "f", "f", "f"],
age = [27, 45, 34, 85, 55, 44, 24, 29, 37, 76],
blood_type = ["A", "0", "B", "B", "B", "A", "0", "A", "A", "B"],
smoker = [true, false, false, false, true, true, true, false, false, false],
)
table_one(
data,
[:age => "Age (years)", :blood_type => "Blood type", :smoker => "Smoker"],
groupby = :sex => "Sex",
show_n = true
)
data = DataFrame(
concentration = [1.2, 4.5, 2.0, 1.5, 0.1, 1.8, 3.2, 1.8, 1.2, 0.2,
1.7, 4.2, 1.0, 0.9, 0.3, 1.7, 3.7, 1.2, 1.0, 0.2],
id = repeat([1, 2, 3, 4], inner = 5),
dose = repeat([100, 200], inner = 10),
time = repeat([0, 0.5, 1, 2, 3], 4)
)
listingtable(
data,
:concentration => "Concentration (ng/mL)",
rows = [:dose => "Dose (mg)", :id => "ID"],
cols = :time => "Time (hr)",
summarize_rows = :dose => [
length => "N",
mean => "Mean",
std => "SD",
]
)
categories = ["Deciduous", "Deciduous", "Evergreen", "Evergreen", "Evergreen"]
species = ["Beech", "Oak", "Fir", "Spruce", "Pine"]
data = rand(4, 5)
labels = ["", "", "Size", Annotated("Water consumption", "Liters per year"), "Age", "Value"]
body = [
Cell.(categories, bold = true, merge = true, border_bottom = true)';
Cell.(species)';
Cell.(data)
]
Table(hcat(
Cell.(labels, italic = true, halign = :right),
body
))
Comparison with PrettyTables
PrettyTables.jl is a well-known Julia package whose main function is formatting tabular data, for example as the backend to DataFrames.jl. PrettyTables supports plain-text output because it is often used for rendering tables to the REPL, however this also means that it does not support merging cells vertically or horizontally in its current state, which is difficult to realize with plain text.
In contrast, SummaryTables’s main purpose is to offer convenience functions for creating specific scientific tables which are out-of-scope for PrettyTables. For our desired aesthetics, we also needed low-level control over certain output formats, for example for controlling cell border behavior in docx, which were unlikely to be added to PrettyTables at the time of writing this package.
WriteDocx
WriteDocx is a utility package that lets you create .docx files compliant with ECMA-376, for use with Microsoft Office Word and other compatible software. Under the hood, these files are zip files containing a standardized folder structure with XML files and other assets.
WriteDocx contains many Julia types that mirror the types of XML nodes commonly found in docx files, without the user having to write any XML manually.
Here’s a simple document with two paragraphs, one of which has pink-colored text:
import WriteDocx as W
doc = W.Document(
W.Body([
W.Section([
W.Paragraph([
W.Run([W.Text("Hello world, from WriteDocx.jl")]),
]),
W.Paragraph([
W.Run(
[W.Text("Goodbye!")],
color = W.HexColor("FF00FF"),
),
]),
]),
]),
)
W.save("example.docx", doc)