Изменить автора документа


Есть ли способ редактировать автора .xlsx файл из RStudio с использованием пакета xlsx?

Я создаю простую рабочую книгу xlsx

data_1=data.frame(1,1,2)
require(xlsx)
wb <- createWorkbook() 
sheet <- createSheet(wb,"TEST") 
addDataFrame(as.data.frame(data_1),
             sheet=sheet,
             startRow=1,
             startColumn=1,
             row.names=FALSE
             )
saveWorkbook(wb,file = "TEST.xlsx") 

В авторе этого xlsx в Excel я вижу "Apache POI", как я могу редактировать это поле?

Не могу найти что-то подобное в документации для xlsx.

Спасибо!

1 2

1 ответ:

library(XML)

# source workbook ---------------------------------------------------------

xl <- "~/Documents/wb.xlsx"

# make a copy using .zip extension ----------------------------------------

tmp <- tempfile(fileext=".zip")
xl <- path.expand(xl)
ok <- file.copy(xl, tmp)

# unzip it and get file list ----------------------------------------------

tmpdir <- tempfile()
fils <- unzip(tmp, exdir=tmpdir)

# get the doc properties file (one of them anyway) ------------------------

props_file <- grep("docProps/core.xml", fils, value=TRUE)

# open it -----------------------------------------------------------------

props <- xmlTreeParse(props_file, useInternalNodes=TRUE)

# view some info ----------------------------------------------------------

for (tag in c("dc:title", "dc:subject", "dc:creator", "cp:keywords",
              "dc:description", "cp:lastModifiedBy", "cp:category")) {
  print(xmlValue(props[[sprintf("//%s", tag)]]))
}

# modify some info --------------------------------------------------------

# you can do this for any of those properties
creator <- getNodeSet(props, "//dc:creator")[[1]]
xmlValue(creator) <- "Mickey Mouse"

# save out the modified file ----------------------------------------------

saveXML(props, props_file)

# re-zip the archive ------------------------------------------------------

unlink(tmp)
cur <- getwd()
setwd(tmpdir)
zip(tmp, basename(tmpdir))
setwd(cur)

# move new xlsx to source xlsir -------------------------------------------

file.copy(tmp,
          paste0(file.path(dirname(path.expand(xl)), basename(tmpdir)), ".xlsx"),
          overwrite=FALSE) # FALSE for testing only

Проверьте это, сделав фиктивный блокнот с некоторыми свойствами документа.

Вот две функции из этого кода, одна для просмотра свойств, а другая для их задания через именованный вектор:

#' Set Excel (xlsx) document properties
#'
#' pass in a named vector. Names should be in this set:
#'
#'   "dc:title", "dc:subject", "dc:creator", "cp:keywords",
#'   "dc:description", "cp:category"
#'
#' @param xl path to excel xlsx file
#' @param file_props document properties to set (named vector)
#' @return new filename created (this doesn't overwrite the existing since
#'         there's not enough error checking)
#' @examples
#' set_properties("path/tp/some.xlsx",
#'                c(`dc:title`="Cool Title",
#'                  `dc:subject`="Cool Subject",
#'                  `dc:creator`="Cool Creator"))
set_properties <- function(xl, file_props) {

  require(XML)

  # make a copy using .zip extension ----------------------------------------

  tmp <- tempfile(fileext=".zip")
  xl <- path.expand(xl)
  ok <- file.copy(xl, tmp)

  # unzip it and get file list ----------------------------------------------

  tmpdir <- tempfile()
  fils <- unzip(tmp, exdir=tmpdir)

  # get the doc properties file (one of them anyway) ------------------------

  props_file <- grep("docProps/core.xml", fils, value=TRUE)

  # open it -----------------------------------------------------------------

  props <- xmlTreeParse(props_file, useInternalNodes=TRUE)

  # you can do this for any of those properties
  for (tag in names(file_props)) {
    # message(sprintf("//%s", tag))
    # message(file_props[tag])
    tval <- getNodeSet(props, sprintf("//%s", tag))[[1]]
    xmlValue(tval) <- file_props[tag]
  }

  # save out the modified file ----------------------------------------------

  saveXML(props, props_file)

  # re-zip the archive ------------------------------------------------------

  unlink(tmp)
  cur <- getwd()
  setwd(tmpdir)
  zip(tmp, "./")
  setwd(cur)

  # move new xlsx to source xlsir -------------------------------------------
  new_fil <- paste0(file.path(dirname(path.expand(xl)), basename(tmpdir)), ".xlsx")
  file.copy(tmp, new_fil, overwrite=TRUE)

  new_fil
}

#' Display Excel (xlsx) document properties
#'
#' @param xl path to excel xlsx file
#' @examples
#' print_properties("path/to/some.xlsx")
print_properties <- function(xl, props) {
  require(XML)

  # make a copy using .zip extension ----------------------------------------

  tmp <- tempfile(fileext=".zip")
  xl <- path.expand(xl)
  ok <- file.copy(xl, tmp)

  # unzip it and get file list ----------------------------------------------

  tmpdir <- tempfile()
  fils <- unzip(tmp, exdir=tmpdir)

  # get the doc properties file (one of them anyway) ------------------------

  props_file <- grep("docProps/core.xml", fils, value=TRUE)

  # open it -----------------------------------------------------------------

  props <- xmlTreeParse(props_file, useInternalNodes=TRUE)
  for (tag in c("dc:title", "dc:subject", "dc:creator", "cp:keywords",
                "dc:description", "cp:category")) {
    cat(sprintf("%16s", tag), ": ", xmlValue(props[[sprintf("//%s", tag)]]), sep="", "\n")
  }

  unlink(tmp)
  unlink(tmpdir)

}