Skip to content

Commit

Permalink
[merge_cells] allow splitting into dimensions (#1212)
Browse files Browse the repository at this point in the history
* [merge_cells] allow splitting into dimensions

* [misc] cleanup
  • Loading branch information
JanMarvin authored Dec 15, 2024
1 parent 49c89dc commit e5c5ccf
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 23 deletions.
5 changes: 3 additions & 2 deletions R/class-workbook-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ wb_copy_cells <- function(
#' @param sheet A name or index of a worksheet
#' @param dims worksheet cells
#' @param solve logical if intersecting merges should be solved
#' @param direction direction in which to split the cell merging. Allows "row" or "col"
#' @param ... additional arguments
#'
#' @examples
Expand Down Expand Up @@ -934,9 +935,9 @@ wb_copy_cells <- function(
#' @family workbook wrappers
#' @family worksheet content functions
#' @export
wb_merge_cells <- function(wb, sheet = current_sheet(), dims = NULL, solve = FALSE, ...) {
wb_merge_cells <- function(wb, sheet = current_sheet(), dims = NULL, solve = FALSE, direction = NULL, ...) {
assert_workbook(wb)
wb$clone(deep = TRUE)$merge_cells(sheet = sheet, dims = dims, solve = solve, ... = ...)
wb$clone(deep = TRUE)$merge_cells(sheet = sheet, dims = dims, solve = solve, direction = direction, ... = ...)
}

#' @export
Expand Down
14 changes: 3 additions & 11 deletions R/class-workbook.R
Original file line number Diff line number Diff line change
Expand Up @@ -5256,8 +5256,9 @@ wbWorkbook <- R6::R6Class(
#' @description
#' Set cell merging for a sheet
#' @param solve logical if intersecting cells should be solved
#' @param direction direction in which to split the cell merging. Allows "row" or "col".
#' @return The `wbWorkbook` object, invisibly
merge_cells = function(sheet = current_sheet(), dims = NULL, solve = FALSE, ...) {
merge_cells = function(sheet = current_sheet(), dims = NULL, solve = FALSE, direction = NULL, ...) {

cols <- list(...)[["cols"]]
rows <- list(...)[["rows"]]
Expand All @@ -5273,17 +5274,8 @@ wbWorkbook <- R6::R6Class(
dims <- rowcol_to_dims(rows, cols)
}

ddims <- dims_to_rowcol(dims)

rows <- ddims[[2]]
cols <- ddims[[1]]

sheet <- private$get_sheet_index(sheet)
self$worksheets[[sheet]]$merge_cells(
rows = rows,
cols = cols,
solve = solve
)
self$worksheets[[sheet]]$merge_cells(dims = dims, solve = solve, direction = direction)
invisible(self)
},

Expand Down
14 changes: 13 additions & 1 deletion R/class-worksheet.R
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,14 @@ wbWorksheet <- R6::R6Class(
#' Set cell merging for a sheet
#' @param rows,cols Row and column specifications.
#' @param solve logical if intersects should be solved
#' @param direction direction in which to split
#' @return The `wbWorkbook` object, invisibly
merge_cells = function(rows = NULL, cols = NULL, solve = FALSE) {
merge_cells = function(dims = NULL, solve = FALSE, direction = NULL) {

ddims <- dims_to_rowcol(dims)

rows <- ddims[[2]]
cols <- ddims[[1]]

rows <- range(as.integer(rows))
cols <- range(col2int(cols))
Expand Down Expand Up @@ -556,6 +562,12 @@ wbWorksheet <- R6::R6Class(
}
}

if (!is.null(direction)) {
if (direction == "row") direction <- 1
if (direction == "col") direction <- 2
sqref <- split_dims(sqref, direction = direction)
}

self$append("mergeCells", sprintf('<mergeCell ref="%s"/>', sqref))

invisible(self)
Expand Down
17 changes: 9 additions & 8 deletions R/helper-functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -383,13 +383,8 @@ hashPassword <- function(password) {
}

# Helper to split a cell range into rows or columns
split_dims <- function(dims, direction = NULL, preserve_single = FALSE) {
split_dims <- function(dims, direction = "row") {
df <- dims_to_dataframe(dims, fill = TRUE, empty_rm = TRUE)

if (preserve_single && is.null(direction) && any(dim(df) == 1)) {
return(dims)
}
if (is.null(direction)) direction <- "row"
if (is.numeric(direction)) {
if (direction == 1) direction <- "row"
if (direction == 2) direction <- "col"
Expand All @@ -410,6 +405,10 @@ split_dim <- function(dims) {
unlist(df)
}

is_single_cell <- function(dims) {
all(lengths(dims_to_rowcol(dims)) == 1)
}

#' Create sparklines object
#'
#' Create a sparkline to be added a workbook with [wb_add_sparklines()]
Expand Down Expand Up @@ -540,8 +539,10 @@ create_sparklines <- function(
if (!is.null(markers) && as_xml_attr(markers) == "" && !is.null(type) && type %in% c("stacked", "column"))
stop("markers only affect lines `type = NULL`, not stacked or column")

dims <- split_dims(dims, direction = direction, preserve_single = TRUE)
sqref <- split_dim(sqref)
if (!is.null(direction) || !is_single_cell(sqref)) {
dims <- split_dims(dims, direction = direction)
sqref <- split_dim(sqref)
}

if (length(dims) != 1 && length(dims) != length(sqref)) {
stop("dims and sqref must be equal length.")
Expand Down
3 changes: 3 additions & 0 deletions man/wbWorkbook.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion man/wb_merge_cells.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tests/testthat/test-fill_merged_cells.R
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,15 @@ test_that("solving merge conflicts works", {
expect_equal(exp, got)

})

test_that("merging with direction works", {
wb <- wb_workbook()$add_worksheet()$
merge_cells(dims = "A1:C3", direction = "row")$
merge_cells(dims = "A4:C6", direction = "col")

exp <- c("<mergeCell ref=\"A1:C1\"/>", "<mergeCell ref=\"A2:C2\"/>",
"<mergeCell ref=\"A3:C3\"/>", "<mergeCell ref=\"A4:A6\"/>",
"<mergeCell ref=\"B4:B6\"/>", "<mergeCell ref=\"C4:C6\"/>")
got <- wb$worksheets[[1]]$mergeCells
expect_equal(exp, got)
})

0 comments on commit e5c5ccf

Please sign in to comment.