compare_xlsx <- function(ft,
tmpfile,
sheet_name,
start_col = 1,
start_row = 1,
offset_caption_rows = 0L,
dims = NULL) {
# Retrieve offsets
if (!is.null(dims)) {
dims <- openxlsx2::dims_to_rowcol(dims, as_integer = TRUE)
offset_cols <- min(dims[[1]]) - 1L
offset_rows <- min(dims[[2]]) - 1L
} else {
offset_cols <- start_col - 1L
offset_rows <- start_row - 1L
}
# ignore offset if there is no caption
if(length(ft$caption$value) == 0) {
offset_caption_rows <- 0L
}
ft_style <- flexlsx:::ft_to_style_tibble(ft,
offset_rows = offset_rows,
offset_cols = offset_cols,
offset_caption_rows = offset_caption_rows)
wb <- openxlsx2::wb_load(tmpfile)
ft_range <- ft_style |>
summarize(across(all_of(c("col_id", "row_id")),
list(Min = min, Max = max)),
.groups = "drop") |>
mutate(r = paste0(openxlsx2::int2col(col_id_Min), row_id_Min, ":",
openxlsx2::int2col(col_id_Max), row_id_Max))
## Check content
diff_content <- compare_content(ft,
ft_style,
ft_range,
wb, sheet_name,
offset_rows + offset_caption_rows,
offset_cols)
nrow_diff_content <- nrow(diff_content)
expect_equal(nrow_diff_content, 0)
if(nrow_diff_content > 0) {
print(paste0("Differences in content ", sheet_name, ":"))
print(diff_content)
}
## TODO: More tests (cell style, text style, ...)
}
compare_content <- function(ft,
ft_style, ft_range, wb, sheet_name,
offset_rows,
offset_cols) {
if(flextable:::has_caption(ft))
offset_rows <- offset_rows + 1L
content_target <- select(ft_style,
all_of(c("row_id", "col_id", "content"))) |>
unnest_legacy() |>
group_by(across(all_of(c("row_id", "col_id")))) |>
summarize(content = paste0(txt, collapse = ""),
.groups = "drop")
content_is <- wb$to_df(sheet = sheet_name,
dims = ft_range$r,
col_names = FALSE) |>
mutate(across(everything(), ~ as.character(.x)),
row_id = dplyr::row_number() + offset_rows) |>
tidyr::pivot_longer(-all_of("row_id")) |>
group_by(across(all_of("row_id"))) |>
mutate(col_id = dplyr::row_number() + offset_cols)
content_is |>
dplyr::full_join(content_target, by = c("row_id", "col_id")) |>
dplyr::mutate(value = dplyr::coalesce(value, ""),
content = dplyr::coalesce(content, "")) |>
filter(value != content)
}
test_that("Generation from start to finish works", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
ft <- flextable::as_flextable(table(mtcars[,1:2]))
wb <- openxlsx2::wb_workbook()$add_worksheet("mtcars")
wb_add_flextable(wb, "mtcars", ft)$save(tmpfile)
compare_xlsx(ft, tmpfile, "mtcars")
})
test_that("Offsets work", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
ft <- flextable::as_flextable(table(mtcars[,1:2]))
wb <- openxlsx2::wb_workbook()$
add_worksheet("mtcars_offset_B3")$
add_worksheet("mtcars_offset_52")
wb <- wb_add_flextable(wb, "mtcars_offset_B3", ft, dims = "B3")
wb_add_flextable(wb, "mtcars_offset_52", ft, start_col = 5, start_row = 2)$save(tmpfile)
compare_xlsx(ft, tmpfile,
sheet_name = "mtcars_offset_B3",
dims = "B3")
compare_xlsx(ft, tmpfile,
sheet_name = "mtcars_offset_52",
start_col = 5,
start_row = 2)
})
test_that("Simple Caption works", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
ft <- flextable::as_flextable(table(mtcars[,1:2]))
ft <- flextable::set_caption(ft, "Simple Caption")
wb <- openxlsx2::wb_workbook()$add_worksheet("mtcars")
wb_add_flextable(wb, "mtcars", ft)$save(tmpfile)
compare_xlsx(ft, tmpfile,
sheet_name = "mtcars")
})
test_that("Complex Caption works", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
ft <- flextable::as_flextable(table(mtcars[,1:2]))
ft <- flextable::set_caption(ft,
caption = flextable::as_paragraph('a ', flextable::as_b('bold'),
" and
",
flextable::as_i('italic'),
' text
with
',
flextable::as_chunk("Variations!", props = flextable::fp_text_default(color = "orange",
font.family = "Courier",
underlined = T))
))
wb <- openxlsx2::wb_workbook()$add_worksheet("mtcars")
wb_add_flextable(wb, "mtcars", ft, offset_caption_rows = 1L)$save(tmpfile)
compare_xlsx(ft, tmpfile,
sheet_name = "mtcars",
offset_caption_rows = 1L)
})
test_that("Complex gtsummary works", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
data("Titanic")
tibble::as_tibble(Titanic) |>
tidyr::uncount(n) |>
gtsummary::tbl_strata(strata = "Class",
.tbl_fun = \(x) {
gtsummary::tbl_summary(x,
by="Sex") |>
gtsummary::add_difference(everything() ~ "prop.test")
}) |>
gtsummary::tbl_butcher() |>
gtsummary::bold_labels() |>
gtsummary::italicize_levels() |>
gtsummary::as_flex_table() -> ft
wb <- openxlsx2::wb_workbook()$add_worksheet("titanic")
wb_add_flextable(wb, "titanic", ft, offset_caption_rows = 1L)$save(tmpfile)
compare_xlsx(ft, tmpfile,
sheet_name = "titanic",
offset_caption_rows = 1L)
})
test_that("Illegal XML characters work", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
to_check <- c("1 (<0.1%)",
"1 > 100",
"& 1 == 1",
"'Hallo'")
data.frame(IllegalXML = to_check) |>
flextable::flextable() -> ft
wb <- openxlsx2::wb_workbook()$add_worksheet("titanic")
wb_add_flextable(wb, "titanic", ft, offset_caption_rows = 1L)$save(tmpfile)
wb <- openxlsx2::wb_load(tmpfile)
expect_equal(wb$to_df(sheet = "titanic",
dims = "A1:A5",
col_names = FALSE)$A,
c("IllegalXML",
"1 (<0.1%)",
"1 > 100",
"& 1 == 1",
"'Hallo'"))
})
test_that("Linebreaks work", {
skip_if_not_installed("flextable")
require("flextable", quietly = TRUE)
tmpfile <- tempfile(fileext = ".xlsx")
to_check <- c("Hello
Linebreak",
"Hello
Linebreak2",
"Ein
Zeilenbrecher",
"Zwei
Zeilen
echer")
to_check2 = c("Hello kein Linebreak",
"Hello ein
Linebreak",
"Drei
Zeilenbrecher",
"Ein
Zeilenbrecher")
data.frame(Linebreak1 = to_check,
Linebreak2 = to_check2) |>
flextable::flextable() |>
flextable::autofit(part = "body")-> ft
wb <- openxlsx2::wb_workbook()$add_worksheet("titanic")
wb_add_flextable(wb, "titanic", ft, offset_caption_rows = 1L)$save(tmpfile)
wb <- openxlsx2::wb_load(tmpfile)
expect_equal(wb$to_df(sheet = "titanic",
dims = "A1:A5",
col_names = FALSE)$A,
c("Linebreak1",
"Hello\nLinebreak",
"Hello\n\n\nLinebreak2",
"Ein\nZeilenbrecher",
"Zwei\nZeilen\necher"))
})