简体   繁体   中英

How to write multiple docx files in purrr::map() style with officer from within downloadHandler() in Shiny to temp directory?

I am trying to write multiple docx files from within downloadHandler(). When purrr::map() arrives at the part of the mapped function where the resume is written with a unique name to the specified temp directory, that is then zipped and returned to the file argument of downloadHandler(). There is an error stating that the specified directory does not exist. An example directory for a single resume is /var/folders/vv/57k257g531b889lqwcgj2z3m0000gp/T//RtmpqhDbg1/resumes/someones_name_resume.docx

I have tried many ways of writing the files to different locations or altering the end directory. I am working from within an R project. I keep getting the error: "Warning: Error in : directory of /var/folders/vv/57k257g531b889lqwcgj2z3m0000gp/T//RtmpqhDbg1/resumes/someones_name_resume.docx does not exist."

resume_temp <- file.path(tempdir(), "resumes")
make_my_resume <- function(my_id) {


  # the empty Word doc that has an applied resume style
  template <- read_docx(here::here("r_scripts", "modern_basic_resume_empty.docx"))


  name_for_file <- str_to_lower(paste(my$first_name, my$last_name, sep = "_"))


  #-----------------------build resume in Word------------------------------------

  word_resume <- template %>%
    cursor_begin() %>% 
    body_remove() %>%
    body_add_par(paste(my$first_name, my$last_name), style = "Title") %>%

    body_end_section_continuous() %>%
    body_add_par(my$address, style = "Contact Info") %>%
    body_add_par(my$phone, style = "Contact Info") %>%
    body_add_par(my$email, style = "Contact Info") %>%

    body_end_section_continuous() %>%
    body_add_par(" ", style = "Title") %>%
    body_add_par(" ", style = "Normal") %>%

    body_end_section_continuous() %>%
    body_add_par("Experience", style = "heading 1") %>%
    body_add_table(my_experience, style = "Plain Table 5") %>%

    body_end_section_continuous() %>%
    body_add_par("Deployments", style = "heading 1") %>%
    body_add_table(my_deployments, style = "Plain Table 5") %>%

    body_end_section_continuous() %>%
    body_add_par("Education", style = "heading 1") %>%
    body_add_table(my_education, style = "Plain Table 5") %>%

    body_end_section_continuous() %>%
    body_add_par("Certifications", style = "heading 1") %>%
    body_end_section_continuous()

  # iterate over each certification
  for (cert in my_certificates$certs) {
    eval(parse(text = (paste0("word_resume <- body_add_par(word_resume, ",
                              "'", cert, "'",
                              ", ",
                              "style = 'List Bullet')",
                              collapse = ""))))
  }

  word_resume <- word_resume %>%  
    body_end_section_columns() %>%
    body_add_par("SKILLS", style = "heading 1") %>%
    body_end_section_continuous()

  # iterate over each skill
  for (skill in my_skills$skills) {
    eval(parse(text = (paste0("word_resume <- body_add_par(word_resume, ",
                              "'", skill, "'",
                              ", ",
                              "style = 'List Bullet')",
                              collapse = ""))))
  }

  message("------starting to write resumes to file------")
  # finish and write to disk

  # browser()

  # resume_empty_dir <- paste0(resume_temp, "/", name_for_file, "_resume.docx")
  # 
  # write_file()

  word_resume <- word_resume %>%  
    body_end_section_columns() %>% 
    print(target = file.path(resume_temp, paste0(name_for_file, "_resume.docx")))


}
output$resume <- downloadHandler(

    filename = "resumes.zip",
    content = function(file, resume_temp) {

      # resume_temp <- here::here(tempdir(), "resumes")

      # file <- NULL

      message("----starting map2()----")

      # browser()

      require(purrr)
      purrr::map(
        .x = selectedId(),  # reactive list for my_id argument in         # make_my_resume
        .f = make_my_resume
      )

      message("----map2() finished----")

      zip::zipr(zipfile = file, files = resume_temp)
      message("----files zipped----")

    },
    contentType = "application/zip"
  )

I want to have the resumes written to a temp directory that is zipped and returned to the file argument of downloadHandler(). Thank you so much!

I found the solution. Instead of creating my tempdir (outside of the app) to write to as

temp_path <- file.path(tempdir(), "sub_directory")

I created it as just

temp_path <- file.path(tempdir())

Once the docx files were written to temp_path, I used a combination of list.files() and regex to zip up and return only the files I wanted, as there are some other unwanted directories created along with the docx files. I used the following inside the downloadHandler() content function after purr:map() wrote the docx files to my temp directory:

to_keep <- list.files(temp_path, pattern = ".docx$", full.names = TRUE)

all_temp_files <- list.files(temp_path, full.names = TRUE)

to_remove <- setdiff(all_temp_files, to_keep)

unlink(to_remove, recursive = TRUE, force = TRUE)

zip::zipr(zipfile = file, files = temp_path)

I am still not sure why

temp_path <- file.path(tempdir(), "sub_directory")

does not work though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM