diff --git a/R/sysdata.rda b/R/sysdata.rda index 18237c9..232fefe 100644 Binary files a/R/sysdata.rda and b/R/sysdata.rda differ diff --git a/R/writeODS.R b/R/writeODS.R index 61b5019..ce2fdc3 100644 --- a/R/writeODS.R +++ b/R/writeODS.R @@ -1,4 +1,4 @@ -.zip_tmp_to_path <- function(tmp, path, overwrite, verbose) { +.zip_tmp_to_path <- function(temp_ods_dir, path, overwrite, verbose) { if (verbose) { zip_flags <- "-r9X" } else { @@ -6,27 +6,27 @@ } wd <- getwd() on.exit(setwd(wd), add = TRUE) - setwd(tmp) + setwd(temp_ods_dir) utils::zip(basename(path), dir(), flags = zip_flags) setwd(wd) - file.copy(file.path(tmp, basename(path)), path, overwrite = overwrite) + file.copy(file.path(temp_ods_dir, basename(path)), path, overwrite = overwrite) } -.find_named_sheet <- function(ss, name) { - sheet <- NULL - for (i in seq(2, length(xml2::xml_children(ss)))) { - if (!is.na(xml2::xml_attr(xml2::xml_children(ss)[[i]], "name") == name) && - xml2::xml_attr(xml2::xml_children(ss)[[i]], "name") == name) { - sheet <- xml2::xml_children(ss)[[i]] +.find_sheet_node_by_sheet <- function(spreadsheet_node, sheet) { + sheet_node <- NULL + for (i in seq(2, length(xml2::xml_children(spreadsheet_node)))) { + if (!is.na(xml2::xml_attr(xml2::xml_children(spreadsheet_node)[[i]], "name") == sheet) && + xml2::xml_attr(xml2::xml_children(spreadsheet_node)[[i]], "name") == sheet) { + sheet_node <- xml2::xml_children(spreadsheet_node)[[i]] } } - return(sheet) + return(sheet_node) } .silent_read_xml <- function(x) { suppressWarnings({ return(xml2::read_xml(x)) - }) + }) } .silent_add_sheet_node <- function(sheet) { @@ -43,9 +43,9 @@ } ## CREATION OF sysdata -## .content <- readLines("benchmark/header.xml") -## .footer <- readLines("benchmark/footer.xml") -## usethis::use_data(.content, .footer, internal = TRUE, overwrite = TRUE) +## .CONTENT <- readLines("benchmark/header.xml") +## .FOOTER <- readLines("benchmark/footer.xml") +## usethis::use_data(.CONTENT, .FOOTER, internal = TRUE, overwrite = TRUE) .gen_sheet_tag <- function(sheet = "Sheet1") { sprintf('', sheet) @@ -91,21 +91,21 @@ } ## https://github.com/ropensci/readODS/issues/88 -.vfwrite_ods <- function(x, tmp, sheet = "Sheet1", row_names = FALSE, col_names = FALSE) { +.vfwrite_ods <- function(x, temp_ods_dir, sheet = "Sheet1", row_names = FALSE, col_names = FALSE) { templatedir <- system.file("template", package = "readODS") - file.copy(dir(templatedir, full.names = TRUE), tmp, recursive = TRUE) - con <- file(file.path(tmp, "content.xml"), open="w") - cat(.content[1], file = con) - cat(.content[2], file = con) + file.copy(dir(templatedir, full.names = TRUE), temp_ods_dir, recursive = TRUE) + con <- file(file.path(temp_ods_dir, "content.xml"), open="w") + cat(.CONTENT[1], file = con) + cat(.CONTENT[2], file = con) .write_sheet_con(x = x, con = con, sheet = sheet, row_names = row_names, col_names = col_names) - cat(.footer, file = con) + cat(.FOOTER, file = con) close(con) } #' Write Data to ODS File -#' @description +#' @description #' Function to write a single data.frame to an ods file. -#' +#' #' @param x a data.frame #' @param path Path to the ods file to write #' @param sheet Name of the sheet @@ -134,45 +134,45 @@ write_ods <- function(x, path, sheet = "Sheet1", append = FALSE, update = FALSE, if (!is.data.frame(x)) { stop("x must be a data.frame.", call. = FALSE) } - ##setup temp directory + ## setup temp directory ## one can't just use tempdir() because it is the same in the same session - tmp <- file.path(tempdir(), sample(seq_len(1000000), 1)) - dir.create(tmp) + temp_ods_dir <- file.path(tempdir(), sample(seq_len(1000000), 1)) + dir.create(temp_ods_dir) tryCatch({ if (!file.exists(path) | (!append & !update)) { - .vfwrite_ods(x = x, tmp = tmp, sheet = sheet, row_names = row_names, col_names = col_names) + .vfwrite_ods(x = x, temp_ods_dir = temp_ods_dir, sheet = sheet, row_names = row_names, col_names = col_names) } else { ## The file must be there. - utils::unzip(path, exdir = tmp) - contentfile <- file.path(tmp, "content.xml") + utils::unzip(path, exdir = temp_ods_dir) + contentfile <- file.path(temp_ods_dir, "content.xml") content <- xml2::read_xml(contentfile) - spreadsheet <- xml2::xml_children(xml2::xml_children(content)[[which(!is.na(xml2::xml_find_first(xml2::xml_children(content),"office:spreadsheet")))]])[[1]] - sn <- .find_named_sheet(spreadsheet, sheet) - if ((!is.null(sn) & append & !update) | (!is.null(sn) & !update)) { + spreadsheet_node <- xml2::xml_children(xml2::xml_children(content)[[which(!is.na(xml2::xml_find_first(xml2::xml_children(content),"office:spreadsheet")))]])[[1]] + sheet_node <- .find_sheet_node_by_sheet(spreadsheet_node, sheet) + if ((!is.null(sheet_node) & append & !update) | (!is.null(sheet_node) & !update)) { ## Sheet exists so we cannot append stop(paste0("Sheet ", sheet, " exists. Set update to TRUE is you want to update this sheet."), call. = FALSE) } - if (is.null(sn) & update) { + if (is.null(sheet_node) & update) { stop(paste0("Sheet ", sheet, " does not exist. Cannot update."), call. = FALSE) } - if (!is.null(sn) & update) { + if (!is.null(sheet_node) & update) { ## clean up the sheet - xml2::xml_remove(xml2::xml_children(sn)[2:length(xml2::xml_children(sn))]) + xml2::xml_remove(xml2::xml_children(sheet_node)[2:length(xml2::xml_children(sheet_node))]) } - if (is.null(sn) & append) { + if (is.null(sheet_node) & append) { ## Add a new sheet - sn <- xml2::xml_add_child(spreadsheet, .silent_add_sheet_node(sheet)) + sheet_node <- xml2::xml_add_child(spreadsheet_node, .silent_add_sheet_node(sheet)) } throwaway_xml_file <- .convert_df_to_sheet(x = x, sheet = sheet, row_names = row_names, col_names = col_names) - xml2::xml_replace(sn, .silent_read_xml(throwaway_xml_file)) + xml2::xml_replace(sheet_node, .silent_read_xml(throwaway_xml_file)) ## write xml to contentfile xml2::write_xml(content, contentfile) } ## zip up ODS archive - .zip_tmp_to_path(tmp, path, overwrite, verbose) + .zip_tmp_to_path(temp_ods_dir, path, overwrite, verbose) }, finally = { - unlink(tmp) + unlink(temp_ods_dir) }) invisible(path) }