--- title: "Customizing How Your Tables Look" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Customizing How Your Tables Look} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(tsg) library(dplyr) ``` `tsg` uses a **style** object (called a *facade*) to control how your tables look when exported — fonts, colours, borders, cell sizes, and more. You can: - Use a **built-in style** out of the box, - **Tweak a few settings** with `add_facade()`, or - **Design your own style** by editing a YAML template. The same style applies consistently to all output formats (Excel, HTML, PDF, Word). --- ## Using a built-in style The package ships with two named styles for Excel output. Pass one to `write_xlsx()` via the `facade` argument. | Style name | Description | |------------|-------------| | `"default"` | Clean, neutral — used automatically when no style is specified | | `"yolo"` | Bolder colours and heavier formatting | ```{r, eval=FALSE} # Bold "yolo" style person_record |> generate_frequency(sex) |> write_xlsx(path = "yolo.xlsx", facade = get_tsg_facade("yolo")) # Explicitly use the default style (same as omitting the facade argument) person_record |> generate_frequency(sex) |> write_xlsx(path = "default.xlsx", facade = get_tsg_facade("default")) ``` --- ## Tweaking a few settings with `add_facade()` `add_facade()` lets you override individual style settings without replacing the whole style. Call it in your pipeline before `write_*()`. Style settings use a two-part name: **which part of the table** `.` **what to change**. For example: - `header.bgFill` — background colour of the column header - `body.fontSize` — font size of the data cells - `table.offsetRow` — blank rows above the table (Excel only) ```{r} person_record |> generate_frequency(sex) |> add_facade( table.offsetRow = 2, table.offsetCol = 1 ) ``` ### Common tweaks ```{r, eval=FALSE} person_record |> generate_crosstab(marital_status, sex) |> add_facade( # Move the table down 2 rows and right 1 column (Excel only) table.offsetRow = 2, table.offsetCol = 1, # Round numbers to 1 decimal place table.decimalPrecision = 1, # Make the last row (usually Total) bold table.lastRowBold = TRUE, # Header background colour and white text header.bgFill = "#003366", header.fontColour = "#FFFFFF", header.textDecoration = "bold", # Data cell font size body.fontSize = 11 ) |> write_xlsx(path = "styled-table.xlsx") ``` > **Good to know:** A few settings only apply to Excel output (such as `table.offsetRow`, `table.gridLines`, and `table.tabColour`). They are harmlessly ignored when exporting to HTML, Word, or PDF — so you can attach them once and export to any format without changing anything. ### Applying the same tweaks across formats Once you attach style overrides with `add_facade()`, those overrides are carried with the table object and applied to whichever format you export to. You only need to style the table once. ```{r, eval=FALSE} styled_tbl <- person_record |> generate_frequency(sex) |> add_table_title("Distribution by Sex") |> add_source_note("Source: Survey 2024") |> add_facade( header.bgFill = "#003366", header.fontColour = "#FFFFFF", header.textDecoration = "bold", body.fontSize = 11, table.lastRowBold = TRUE ) write_xlsx(styled_tbl, path = "table.xlsx") write_html(styled_tbl, path = "table.html") write_pdf(styled_tbl, path = "table.pdf") write_docx(styled_tbl, path = "table.docx") ``` --- ## Making your own style file For full control, generate a starter YAML file, edit it to your taste, and load it back in. ### Step 1 — generate the template ```{r, eval=FALSE} generate_template("my-style.yaml", template = "facade") ``` ### Step 2 — edit the file Open `my-style.yaml` in any text editor. It looks like this: ```yaml table.fontName: 'Arial' table.fontSize: 12 table.offsetRow: 0 table.offsetCol: 0 table.decimalPrecision: 2 table.lastRowBold: false table.width: 14 header.bgFill: ~ # ~ means "use the default" header.fontColour: ~ header.textDecoration: ~ header.height: 28 body.fontSize: ~ body.bgFill: ~ body.numFmt: "###0" body.height: 20 title.fontSize: 13 title.textDecoration: "bold" title.height: 24 source_note.fontSize: 10 source_note.textDecoration: "italic" ``` Change any value you like. Use `~` to keep the built-in default for a setting. > **Tip:** `get_tsg_facade()` also accepts `.json` file paths if you prefer JSON over YAML. ### Step 3 — use your style ```{r, eval=FALSE} my_style <- get_tsg_facade("my-style.yaml") person_record |> generate_frequency(sex) |> write_xlsx(path = "custom-styled.xlsx", facade = my_style) ``` --- ## Programmatic style overrides If you need to build style settings dynamically (for example, in a loop or from a config), use `add_facade_alt()`. It accepts a named list instead of individual named arguments. ```{r} overrides <- list( table.offsetRow = 3, header.bgFill = "#2E4057", header.fontColour = "#FFFFFF", body.fontSize = 11 ) do.call( add_facade_alt, c(list(data = person_record |> generate_frequency(sex)), overrides) ) ``` --- ## Style property reference The table below lists every setting supported by each section of the table. ```{r, echo=FALSE} props <- c( "fontName", "fontSize", "fontColour", "bgFill", "fgFill", "halign", "valign", "textDecoration", "wrapText", "indent", "border", "borderColour", "borderStyle", "numFmt", "height", "width" ) sections <- c( "table", "title", "subtitle", "header", "spanner", "body", "col_first", "col_last", "row_group", "sub_group", "source_note", "footnotes" ) has_prop <- function(section, prop) { if (prop == "width") return(section %in% c("table", "col_first", "col_last", "row_group")) if (prop == "numFmt") return(section %in% c("body", "col_first", "col_last")) if (prop == "height") return(section != "table") TRUE } ref <- do.call(rbind, lapply(sections, function(s) { data.frame( Section = s, Properties = paste( Filter(function(p) has_prop(s, p), props), collapse = ", " ), stringsAsFactors = FALSE ) })) knitr::kable(ref, row.names = FALSE) ``` ### Table-level settings (full list) | Setting | What it does | Excel | HTML | Word | |---------|-------------|:-----:|:----:|:----:| | `table.fontName` | Default font family | ✓ | ✓ | ✓ | | `table.fontSize` | Default font size | ✓ | ✓ | ✓ | | `table.fontColour` | Default font colour | ✓ | ✓ | ✓ | | `table.bgFill` | Table background colour | ✓ | ✓ | ✓ | | `table.decimalPrecision` | Decimal places for numbers | ✓ | ✓ | ✓ | | `table.decimalCols` | Which columns get decimal formatting | ✓ | ✓ | ✓ | | `table.lastRowBold` | Make the last row bold | ✓ | ✓ | ✓ | | `table.offsetRow` | Blank rows above the table | ✓ | | | | `table.offsetCol` | Blank columns to the left | ✓ | | | | `table.gridLines` | Show worksheet grid lines | ✓ | | | | `table.tabColour` | Excel worksheet tab colour | ✓ | | | | `table.locked` | Lock the worksheet | ✓ | | | | `table.hidden` | Hide the worksheet | ✓ | | | | `table.width` | Column width | ✓ | | | | `table.widthOffset` | Extra width added to auto-sized columns | ✓ | | | ### Colour values All `fontColour`, `bgFill`, and `fgFill` settings accept: - Hex colour codes: `"#003366"` - Named R colours: `"navy"` - `~` (in YAML) or `NULL` (in R) to use the inherited default ### Section names | Section | What it styles | |---------|----------------| | `table` | Global table settings | | `title` | Title row above the table | | `subtitle` | Subtitle row | | `header` | Column header row(s) | | `spanner` | Grouped header rows in cross-tabulations | | `body` | Data rows | | `col_first` | First (category) column | | `col_last` | Last column | | `row_group` | Group header rows | | `sub_group` | Sub-group rows | | `source_note` | Source note row below the table | | `footnotes` | Footnote rows | | `border_header` | Border under the header | | `border_outer` | Outer border around the table | | `border_bottom` | Bottom border row height |