Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clone_worksheet] copy worksheet across workbooks #622

Merged
merged 11 commits into from
Oct 4, 2023
Merged

Conversation

JanMarvin
Copy link
Owner

@JanMarvin JanMarvin commented May 21, 2023

Early attempt at #380

There are a couple of things to do and this is just a first step

  • copy elements

    • actual copy for wb$worksheet[[n]]
    • required bits from wb$workbook, wb$workbook.xml.rels, wb$worksheet_rels
    • required charts, comments, drawings, embeddings, shared strings, tables, pivot tables, slicers, vmls
  • update copy elements

    • copy styles from one workbook onto the next
    • update wb$worksheet_rels (most likely everything will require a new file name)

Hopefully we can build on wb_clone_worksheet(), but even then there is still a lot to do.

a first draft of what could be possible

# we will clone this styled chart into another workbook
fl <- system.file("extdata", "oxlsx2_sheet.xlsx", package = "openxlsx2")
wb_in <- wb_load(fl)

# create a second workbook
wb <- wb_workbook()$
  add_worksheet("NOT_SUM")$
  add_data(x = head(iris))$
  add_fill(dims = "A1:B2", color = wb_color("yellow"))$
  add_border(dims = "B2:C3")

# hack copy the workbook
wb$add_worksheet("SUM")
wb$worksheets[[2]] <- wb_in$clone(deep = TRUE)$worksheets[[1]]
wb$sharedStrings <- wb_in$sharedStrings
wb$append("Content_Types", "<Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/>")
wb$append("workbook.xml.rels", "<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings\" Target=\"sharedStrings.xml\"/>")

# update sheet styles
style <- get_cellstyle(wb_in)
new_sty <- set_cellstyles(wb, style = style)
new_s <- unname(new_sty[match(wb$worksheets[[2]]$sheet_data$cc$c_s, names(new_sty))])
wb$worksheets[[2]]$sheet_data$cc$c_s <- new_s

@JanMarvin JanMarvin added enhancement 😀 New feature or request help wanted 🙏 Extra attention is needed workbook 📖 wbWorkbook objects labels May 21, 2023
@JanMarvin JanMarvin added this to the future milestone May 21, 2023
@JanMarvin JanMarvin changed the title [WIP] add get_cellstyle/set_cellstyle function [WIP] copy worksheet across workbooks May 21, 2023
@olivroy
Copy link
Collaborator

olivroy commented Sep 27, 2023

I think this could be very useful! Whenever you come back to this, let me know, (and if I can help)

Maybe a syntax like this could be cool:?

wb1 <- wb_load("file1.xlsx")
wb2 <- wb_load("file2.xlsx")
#  assuming wb2 has "Sheet 1"
wb1$add_worksheet(sheet = "Sheet 1", from_wb = wb2)

@JanMarvin
Copy link
Owner Author

JanMarvin commented Sep 27, 2023

It's a long standing feature request, but unfortunately also quite a nuisance and nothing I really require. (I once handcrafted a solution for myself, but obviously that's nothing to show to the user.)
Basically it gets tricky once there's more than just data on a sheet. Drawings, charts, pivot tables and slicers, tables and embeddings. All of this should be handled but most of this isn't simple to do. Therefore it's a task for bad weather and nothing I'm currently actively developing.

@JanMarvin

This comment was marked as outdated.

@JanMarvin

This comment was marked as outdated.

@JanMarvin

This comment was marked as outdated.

@JanMarvin
Copy link
Owner Author

Guess you could have a look at what works and what doesn't @olivroy . I might have fixed a few bugs in the original clone_worksheet() code.

Unless there are major malfunctions, we might have something working, at least for data and maybe native charts. Obviously there are still lots of things to check and we might have to add a still experimental note to the man page.

@olivroy
Copy link
Collaborator

olivroy commented Oct 2, 2023

That is fantastic, I will try it out.

@JanMarvin JanMarvin force-pushed the clone_to_wb branch 2 times, most recently from 0457553 to 5a721ba Compare October 2, 2023 18:26
@JanMarvin

This comment was marked as outdated.

@JanMarvin

This comment was marked as outdated.

@JanMarvin
Copy link
Owner Author

library(openxlsx2)

# we will clone this styled chart into another workbook
fl <- system.file("extdata", "oxlsx2_sheet.xlsx", package = "openxlsx2")
wb_in <- wb_load(fl)

# create a second workbook
wb <- wb_workbook()$
  add_worksheet("NOT_SUM")$
  add_data(x = head(iris))$
  add_fill(dims = "A1:B2", color = wb_color("yellow"))$
  add_border(dims = "B2:C3")

# clone styles and shared strings
wb$clone_worksheet(old = "SUM", new = "SUM", from = wb_in)

wb$clone_worksheet(old = "SUM", new = "SUM_clone")

wb$clone_worksheet(old = "SUM", new = "SUM2", from = wb_in)


wb_in <- wb_workbook()$add_worksheet("tab")$add_data_table(x = mtcars)

# clone table
wb$clone_worksheet(old = "tab", new = "tab", from = wb_in)

# clone it twice
wb$clone_worksheet(old = "tab", new = "tab", from = wb_in)
#> Warning: Attempted to add a worksheet that is invalid or already exists.
#> Fixing: a sheet with name "tab" already exists. Creating a unique sheetname"


library(mschart)
## Add mschart to worksheet (adds data and chart)
scatter <- ms_scatterchart(data = iris, x = "Sepal.Length", y = "Sepal.Width", group = "Species")
scatter <- chart_settings(scatter, scatterstyle = "marker")

wb_ms <- wb_workbook() %>%
  wb_add_worksheet("chart") %>%
  wb_add_mschart(dims = "F4:L20", graph = scatter)


wb$clone_worksheet(old = "chart", new = "chart_1", from = wb_ms)
wb$clone_worksheet(old = "chart", new = "chart_2", from = wb_ms)

img <- system.file("extdata", "einstein.jpg", package = "openxlsx2")

wb_img <- wb_workbook()$
  add_worksheet()$
  add_image("Sheet 1", dims = "C5", file = img, width = 6, height = 5)$
  add_worksheet()$
  add_image(dims = "B2", file = img)$
  add_worksheet()$
  add_image(dims = "G3", file = img, width = 15, height = 12, units = "cm")

wb$clone_worksheet(old = "Sheet 1", new = "img", from = wb_img)

wb_ex <- wb_load(system.file("extdata", "loadExample.xlsx", package = "openxlsx"))

# this one is still broken, not sure why. maybe the hyperlink reference?
wb$clone_worksheet(old = "testing", new = "test", from = wb_ex)
# hack to silnce this. need to get dxfsId from conditional formatting
wb$styles_mgr$styles$dxfs <- wb_ex$styles_mgr$styles$dxfs

if (interactive()) wb$open()

R/helper-functions.R Outdated Show resolved Hide resolved
R/class-workbook.R Outdated Show resolved Hide resolved
* improve cloning images
* improve cloning numfmts
* document that this is experimental
* trying to wrap my head around dxf style selection
@JanMarvin JanMarvin changed the title [WIP] copy worksheet across workbooks [clone_worksheet] copy worksheet across workbooks Oct 4, 2023
@JanMarvin JanMarvin merged commit f0da559 into main Oct 4, 2023
9 checks passed
@JanMarvin JanMarvin deleted the clone_to_wb branch October 4, 2023 20:45
@JanMarvin
Copy link
Owner Author

It's as good as it gets for the first take. There are many things not yet working, but they are either nothing I required atm (like conditional formatting), tricky to implement (pivot tables and slicers) or a little special (is anyone actually using custom table styles).

Fixing these can always happen later, once someone stumbles over these.

@olivroy
Copy link
Collaborator

olivroy commented Oct 4, 2023

Wow! Thanks for the great work. I think these caveats are fine for now. I will try it when I have the chance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 😀 New feature or request help wanted 🙏 Extra attention is needed workbook 📖 wbWorkbook objects
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants