Search code examples
rshinyofficer

Generating word report in shiny using officeR


I want to use shiny to take a set of dates and days as inputs, calculate the number of days between those days, and then generate the output of these operations in a word document. The code works when I just use R, but when I try to run this in shiny, it fails - because the document is not being generated.

My current code is below.

####Setup####
  library(shiny)  
  library(needs)
  library(tidyverse)
  library(lubridate)
  library(officer)
  library(ical)


####Generate page####
ui <- fluidPage(
  titlePanel("Shiny Example"),

  sidebarLayout(
    sidebarPanel(
      #Input for Date Range
      dateInput("date_begin", label = h3("Start Date"), 
                language= "de",  
                format = "dd-mm-yyyy"),
      dateInput("date_end", label = h3("End Date"), 
                language= "de",
                format = "dd-mm-yyyy"),

      #Week Days 
      checkboxGroupInput("weekdays", label = h3("Weekdays"), 
      choices = list("Monday" = 2, 
                     "Tuesday" = 3, 
                     "Wednesday" = 4, 
                     "Thursday" = 5, 
                     "Friday" = 6, 
                     "Saturday" = 7, 
                     "Sunday" = 1), hr())
      ),

    mainPanel(
      textOutput("begin"),
      verbatimTextOutput("Days"),
      downloadButton('downloadData', 'download')

    )
  )
)

server <- function(input, output) {

  ####Calculations####
  #Find all days between the dates

  output$begin <- renderText({ 
    paste("Days between", 
          input$date_begin,  "and", 
          input$date_end, "statt")
  })

   output$downloadData <- downloadHandler(
     filename = function(){"download.docx"},

     content = function(file) {

      ###Generate Date Vector###
       #Get Dates
       myDates <-seq(from = input$date_begin, to = output$date_end, by = "days")
       #Identify Date of Weekday
       select.vec<-which(wday(myDates) %in% c(output$weekdays))
       #Subset Data by Weekday
       date.vec<-myDates[select.vec]

       #Generate Number Vector
       number.vec<-seq(1,length=length(date.vec))

       #Generate Vector of Heading Names (German Format)
       name.vec1<-paste("Day",number.vec,sep=" ")

      ###Generate File###
          doc.full<-read_docx("")     

    #Write date in for loop
    for (i in 1:length(date.vec)){
      #Generate German output for date
      temp.date<-paste(day(date.vec[i]),
                       month(date.vec[i]),
                       year(date.vec[i]), 
                       sep=".")
      doc.full<-doc.full %>% 
      body_add_par(value = name.vec1[i], style =  "Sitzung") %>% 
      body_add_par(value = temp.date, style =  "Datum") 
    }

    #Write Output
          doc.full%>% 
            print(target = file)
    }
   )

}

# Run the application 
shinyApp(ui = ui, server = server)



Solution

  • There are several errors.

      #Get Dates
      myDates <-seq(from = input$date_begin, to = output$date_end, by = "days")
      #Identify Date of Weekday
      select.vec<-which(wday(myDates) %in% c(output$weekdays))
    

    to replace with

      #Get Dates
      myDates <-seq(from = input$date_begin, to = input$date_end, by = "days")
      #Identify Date of Weekday
      select.vec<-which(wday(myDates) %in% c(input$weekdays))
    

    Next, read_docx("") does not work, because there is no file "". To use the default template, do read_docx().

    But if you use the default template, then

        doc.full <- doc.full %>% 
          body_add_par(value = name.vec1[i], style =  "Sitzung") %>% 
          body_add_par(value = temp.date, style =  "Datum") 
    

    does not work, because there are no styles Sitzung and Datum in the default template.