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

Add possibility to interact with metadata #752

Closed
wants to merge 8 commits into from

Conversation

olivroy
Copy link
Collaborator

@olivroy olivroy commented Aug 22, 2023

Fix #744, #745

The implementation is quite basic. There is now potential duplication of code, with wb_add_creators(), wb_workbook(), but it is not too bad. Feel free to tweak the implementation.

This seems to fail without worksheets, but I wouldn't know why you wouldn't want to have a worksheet in a workbook
Lmk what you think.
This now works #741 (comment)

devtools::load_all("~/rrr-forks/openxlsx2")
#> ℹ Loading openxlsx2
wb1 <- wb_workbook(title = "thingy", subject = "A COOL SUBJECT")
wb1$add_worksheet()
wb1$open()
#> Warning in xl_open.default(x$clone()$save(temp_xlsx(macros = has_macros))$path,
#> : will not open file when not interactive
wb1$subject
#> [1] "A COOL SUBJECT"
wb1$set_properties(subject=  "A new subject")
wb1$subject
#> [1] "A new subject"
tmp_file <- temp_xlsx()
wb1$save(tmp_file)
wb2 <- wb_load(tmp_file)
wb2$subject
#> [1] "A new subject"
wb2$title
#> [1] "thingy"

edit: used the logic of wb$add_creator() mainly

@JanMarvin
Copy link
Owner

Cool! Thanks, even with a wrapper function! I'll have a closer look. Just for reference: I was thinking along the lines of this (this is quite general and should keep everything in wb$core that is not covered by genBaseCore():

library(openxlsx2)
# get some example file
wb <- wb_load(file = system.file("extdata", "openxlsx2_example.xlsx", package = "openxlsx2"))

#  get the core properties
get_core_propteries <- function(wb) {
  nams <- wb$core %>% xml_node_name("cp:coreProperties")
  vapply(nams, function(x)
    xml_value(wb$core, "cp:coreProperties", x), FUN.VALUE = NA_character_)
}

# set the core properties to replace genBaseCore()
set_core_properties <- function(wb, creator = NULL, title = NULL, subject = NULL, category = NULL) {
  
  # get an xml output or create one
  if (!is.null(wb$core)) {
    nams <- wb$core %>% xml_node_name("cp:coreProperties")
    xml_properties <- vapply(nams, function(x) {
      xml_value(wb$core, "cp:coreProperties", x)
    }, FUN.VALUE = NA_character_)
  } else {
    xml_properties <- c(
      "dc:creator" = "", 
      "cp:lastModifiedBy" = "",
      "dcterms:created" = "",
      "dcterms:modified" = "",
      "dc:title" = "",
      "dc:subject" = ""
    )
  }
  
  # update values where needed
  if (!is.null(creator)) {
    xml_properties["dc:creator"] <- as.character(creator)
  }
  if (!is.null(title)) {
    xml_properties["dc:title"] <- as.character(title)
  }
  if (!is.null(subject)) {
    xml_properties["dc:subject"] <- as.character(subject)
  }
  
  # create xml children
  xml_create_value <- mapply(function(x, y) {
    xml_node_create(x, xml_children = y)
  }, names(xml_properties), xml_properties)
  
  # return xml core output  
  xml_node_create(
    "cp:coreProperties",
    xml_attributes = c(
      "xmlns:cp"="http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
      "xmlns:dc"="http://purl.org/dc/elements/1.1/",
      "xmlns:dcterms"="http://purl.org/dc/terms/",
      "xmlns:dcmitype"="http://purl.org/dc/dcmitype/",
      "xmlns:xsi"="http://www.w3.org/2001/XMLSchema-instance"
    ),
    xml_children = paste0(xml_create_value, collapse = "")
  )
  
}

get_core_propteries(wb)
#>             dc:creator      cp:lastModifiedBy        dcterms:created 
#> "Jan Marvin Garbuszus" "Jan Marvin Garbuszus" "2023-05-29T07:43:12Z" 
#>       dcterms:modified 
#> "2023-05-29T10:47:37Z"
set_core_properties(wb, creator = "olivroy") %>% as_xml()
#> <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#>  <dc:creator>olivroy</dc:creator>
#>  <cp:lastModifiedBy>Jan Marvin Garbuszus</cp:lastModifiedBy>
#>  <dcterms:created>2023-05-29T07:43:12Z</dcterms:created>
#>  <dcterms:modified>2023-05-29T10:47:37Z</dcterms:modified>
#> </cp:coreProperties>

@JanMarvin
Copy link
Owner

I don't have time to work on this this week ergo it will not make if for 1.0.

@olivroy
Copy link
Collaborator Author

olivroy commented Aug 23, 2023

That is fine.. Just wanted to get the ball rolling, but you're the pro with xml !

@JanMarvin
Copy link
Owner

I close this as superseded by #782 .

@JanMarvin JanMarvin closed this Sep 19, 2023
@olivroy olivroy deleted the properties branch September 19, 2023 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

interact with wb metadata simply
2 participants