Nothing
# worksheets ------------------------------------------------------------
worksheets <- R6Class(
"worksheets",
inherit = openxml_document,
public = list(
initialize = function(path) {
super$initialize(character(0))
private$package_dir <- path
presentation_filename <- file.path(path, "xl", "workbook.xml")
self$feed(presentation_filename)
slide_df <- self$get_sheets_df()
private$sheet_id <- slide_df$sheet_id
private$sheet_rid <- slide_df$rid
private$sheet_name <- slide_df$name
},
view_on_sheet = function(sheet) {
sheet_id <- self$get_sheet_id(sheet)
wb_view <- xml_find_first(self$get(), "d1:bookViews/d1:workbookView")
xml_attr(wb_view, "activeTab") <- sheet_id - 1
self$save()
},
add_sheet = function(target, label) {
private$rels_doc$add(
id = paste0("rId", private$rels_doc$get_next_id()),
type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
target = target
)
rels <- private$rels_doc$get_data()
rid <- rels[rels$target %in% target, "id"]
ids <- private$sheet_id
new_id <- max(ids) + 1
private$sheet_id <- c(private$sheet_id, new_id)
private$sheet_rid <- c(private$sheet_rid, rid)
private$sheet_name <- c(private$sheet_name, label)
children_ <- xml_children(self$get())
sheets_id <- which(sapply(children_, function(x) xml_name(x) == "sheets"))
xml_list <- xml_children(children_[[sheets_id]])
xml_elt <- paste(
sprintf(
"<sheet name=\"%s\" sheetId=\"%.0f\" r:id=\"%s\"/>",
htmlEscapeCopy(private$sheet_name),
private$sheet_id,
private$sheet_rid
),
collapse = ""
)
xml_elt <- paste0(
"<sheets xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">",
xml_elt,
"</sheets>"
)
xml_elt <- as_xml_document(xml_elt)
if (!inherits(xml_list, "xml_missing")) {
xml_replace(children_[[sheets_id]], xml_elt)
} else {
stop("could not find sheets entity")
}
self
},
get_new_sheetname = function() {
sheet_dir <- file.path(private$package_dir, "xl/worksheets")
if (!file.exists(sheet_dir)) {
dir.create(
file.path(sheet_dir, "_rels"),
showWarnings = FALSE,
recursive = TRUE
)
}
sheet_files <- basename(list.files(sheet_dir, pattern = "\\.xml$"))
sheet_name <- "sheet1.xml"
if (length(sheet_files)) {
slide_index <- as.integer(gsub(
"^(sheet)([0-9]+)(\\.xml)$",
"\\2",
sheet_files
))
sheet_name <- gsub(
pattern = "[0-9]+",
replacement = max(slide_index) + 1,
sheet_name
)
}
sheet_name
},
sheet_names = function() {
private$sheet_name
},
get_sheet_id = function(name) {
sheets_df <- self$get_sheets_df()
bool_name_in_list <- sheets_df$name %in% name
n_matches <- sum(bool_name_in_list, na.rm = TRUE)
if (n_matches < 1) {
stop("could not find ", shQuote(name), " sheet", call. = FALSE)
}
sheets_df$sheet_id[bool_name_in_list]
},
get_sheets_df = function() {
children_ <- xml_children(self$get())
sheets_id <- which(sapply(children_, function(x) xml_name(x) == "sheets"))
sheet_nodes <- xml_children(children_[[sheets_id]])
data.frame(
stringsAsFactors = FALSE,
name = xml_attr(sheet_nodes, "name"),
sheet_id = as.integer(xml_attr(sheet_nodes, "sheetId")),
rid = xml_attr(sheet_nodes, "id")
)
}
),
private = list(
sheet_id = NULL,
sheet_rid = NULL,
sheet_name = NULL,
package_dir = NULL
)
)
# sheet ------------------------------------------------------------
sheet <- R6Class(
"sheet",
inherit = openxml_document,
public = list(
feed = function(file) {
private$filename <- file
private$doc <- read_xml(file)
private$rels_filename <- file.path(
dirname(file),
"_rels",
paste0(basename(file), ".rels")
)
if (file.exists(private$rels_filename)) {
private$rels_doc <- relationship$new()$feed_from_xml(
private$rels_filename
)
} else {
new_rel <- relationship$new()
new_rel$write(private$rels_filename)
private$rels_doc <- new_rel
}
self
}
)
)
# dir_sheets ----
dir_sheet <- R6Class(
"dir_sheet",
public = list(
initialize = function(x) {
private$package_dir <- x$package_dir
private$sheets_path <- "xl/worksheets"
self$update()
},
update = function() {
dir_ <- file.path(private$package_dir, private$sheets_path)
filenames <- list.files(
path = dir_,
pattern = "\\.xml$",
full.names = TRUE
)
private$collection <- lapply(
filenames,
function(x, path) {
sheet$new(path)$feed(x)
},
private$sheets_path
)
names(private$collection) <- sapply(private$collection, function(x) {
x$name()
})
self
},
get_sheet_list = function() {
dir_ <- file.path(private$package_dir, private$sheets_path)
filenames <- list.files(
path = dir_,
pattern = "\\.xml$",
full.names = TRUE
)
sheet_index <- seq_along(filenames)
if (length(filenames)) {
filenames <- basename(filenames)
sheet_index <- as.integer(gsub(
"^(sheet)([0-9]+)(\\.xml)$",
"\\2",
filenames
))
filenames <- filenames[order(sheet_index)]
}
filenames
},
get_sheet = function(id) {
l_ <- self$length()
if (is.null(id) || !between(id, 1, l_)) {
stop("unvalid id ", id, " (", l_, " sheet(s))", call. = FALSE)
}
sheet_files <- self$get_sheet_list()
index <- which(names(private$collection) == sheet_files[id])
private$collection[[index]]
},
length = function() {
length(private$collection)
}
),
private = list(
collection = NULL,
package_dir = NULL,
sheets_path = NULL
)
)
# read_xlsx ----
#' @export
#' @title Create an 'Excel' document object
#' @description Read and import an xlsx file as an R object
#' representing the document. This function is experimental.
#' @param path path to the xlsx file to use as base document.
#' @param x an rxlsx object
#' @examples
#' read_xlsx()
read_xlsx <- function(path = NULL) {
if (!is.null(path) && !file.exists(path)) {
stop("could not find file ", shQuote(path), call. = FALSE)
}
if (is.null(path)) {
path <- system.file(package = "officer", "template/template.xlsx")
}
if (!grepl("\\.xlsx$", path, ignore.case = TRUE)) {
stop("read_xlsx only support xlsx files", call. = FALSE)
}
package_dir <- tempfile()
unpack_folder(file = path, folder = package_dir)
obj <- structure(
list(package_dir = package_dir),
.Names = c("package_dir"),
class = "rxlsx"
)
obj$content_type <- content_type$new(package_dir)
obj$worksheets <- worksheets$new(package_dir)
obj$sheets <- dir_sheet$new(obj)
obj$core_properties <- read_core_properties(obj$package_dir)
obj
}
#' @export
#' @title Add a sheet
#' @description Add a sheet into an xlsx worksheet.
#' @param x rxlsx object
#' @param label sheet label
#' @examples
#' my_ws <- read_xlsx()
#' my_pres <- add_sheet(my_ws, label = "new sheet")
add_sheet <- function(x, label) {
if (label %in% x$worksheets$sheet_names()) {
stop("sheet ", shQuote(label), " already exist")
}
new_slidename <- x$worksheets$get_new_sheetname()
xml_file <- file.path(x$package_dir, "xl/worksheets", new_slidename)
template_file <- system.file(package = "officer", "template/sheet.xml")
file.copy(template_file, xml_file, copy.mode = FALSE)
rel_filename <- file.path(
dirname(xml_file),
"_rels",
paste0(basename(xml_file), ".rels")
)
dir.create(dirname(rel_filename), showWarnings = FALSE)
template_rel_file <- system.file(
package = "officer",
"template/sheet.xml.rels"
)
file.copy(template_rel_file, rel_filename, copy.mode = FALSE)
# update presentation elements
x$worksheets$add_sheet(
target = file.path("worksheets", new_slidename),
label = label
)
partname <- file.path("/xl/worksheets", new_slidename)
override <- setNames(
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
partname
)
x$content_type$add_override(value = override)
x$sheets$update()
sheet_select(x, sheet = label)
}
#' @export
#' @rdname read_xlsx
length.rxlsx <- function(x) {
x$sheets$length()
}
#' @export
#' @title Select sheet
#' @description Set a particular sheet selected when workbook will be
#' edited.
#' @param x rxlsx object
#' @param sheet sheet name
#' @examples
#' my_ws <- read_xlsx()
#' my_pres <- add_sheet(my_ws, label = "new sheet")
#' my_pres <- sheet_select(my_ws, sheet = "new sheet")
#' print(my_ws, target = tempfile(fileext = ".xlsx") )
sheet_select <- function(x, sheet) {
x$worksheets$view_on_sheet(sheet)
x
}
#' @export
#' @param target path to the xlsx file to write
#' @param ... unused
#' @rdname read_xlsx
#' @examples
#' x <- read_xlsx()
#' print(x, target = tempfile(fileext = ".xlsx"))
print.rxlsx <- function(x, target = NULL, ...) {
if (is.null(target)) {
cat("xlsx document with", length(x), "sheet(s):\n")
print(x$worksheets$sheet_names())
return(invisible())
}
if (!grepl(x = target, pattern = "\\.(xlsx)$", ignore.case = TRUE)) {
stop(target, " should have '.xlsx' extension.")
}
x$worksheets$save()
x$content_type$save()
x$core_properties['modified', 'value'] <- format(
Sys.time(),
"%Y-%m-%dT%H:%M:%SZ"
)
x$core_properties['lastModifiedBy', 'value'] <- Sys.getenv("USER")
write_core_properties(x$core_properties, x$package_dir)
invisible(pack_folder(folder = x$package_dir, target = target))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.