Prathamesh
Prathamesh

Reputation: 97

Applying style to all sheets of a workbook using openxlsx package in R

While using openxlsx package in R, I want to apply a particular style to all sheets of a workbook. I am using addStyle() after defining a style. Here, I need to specify the sheet name or number on which style needs to be added

addStyle(wb, sheet=1, style, rows, cols, gridExpand = FALSE, stack = FALSE)

Is there a simple way to do this without using any loop or adding the style individually per sheet? Reason being no.of sheets may change for every run

Upvotes: 2

Views: 3477

Answers (2)

Martin G.
Martin G.

Reputation: 159

Just to extend on Danny's conjecture

I don't think there is a way to use addStyle for all sheets without some kind of for loop/apply function.

and for the sake of completeness - there is another possibility: the purrr package from tidyverse! It is a way of functional programming that allows you to avoid loops.

A minimal reproducible example on how to add styles to multiple sheets via openxlsx and data.frames with different lenghts:

library(purrr)
library(openxlsx)

# random data.frames
a <- data.frame(name = c("A", "B", "C"),
                value = c(0.01, 0.02, 0.03))

b <- data.frame(name = c("D", "E", "F", "G"),
                value = c(0.01, 0.02, 0.03, 0.04))

# functional programing is mainly based on lists
l <- list(a, b)

# Excel Sheets
sheet_names <- c("SheetA", "SheetB")

# Create the workbook
wb <- createWorkbook()

# Walk replaces the for-loop to create empty sheets given our variable
# sheet_names = .x
walk(sheet_names, ~addWorksheet(wb, .x))

# Walk2 takes a second parameter, in our case the list of data.frames
# sheet_names = .x
# l = .y
walk2(sheet_names, l, ~writeData(wb, .x, .y))

# To apply a certain style, i.e. percentage format, we need to know the number of rows 
# for each data.frame. Thus, walk2 helps us to circumvent a nested for-loop
# sheet_names = .x
# l = .y
walk2(sheet_names, l, ~addStyle(wb, .x, 
                                style = createStyle(numFmt='PERCENTAGE'), 
                                rows = 2:(nrow(.y)+1), cols = 2, gridExpand = TRUE))

# Save the workbook
saveWorkbook(wb, "myfile.xlsx", overwrite = T)

Of course, in such a small example a for-loop would be easy to implement, but when requirements get tougher and you want to increase the speed of your script, go for purrr and functional programming.

Upvotes: 4

Danny
Danny

Reputation: 488

You don't have to use a fixed number for the loop. If you loop through names(wb) i.e.

for(curr_sheet in names(wb))

and pass that value into the sheet parameter it will work regardless of when you change the number of sheets.

I don't think there is a way to use addStyle for all sheets without some kind of for loop/apply function.

Upvotes: 1

Related Questions