I am working on a shiny app where the user will upload an excel file, the data will be manipulated, and then a new excel file with this data is exported for the user to examine. I am having issues with the downloadHandler function. I used to create an entirely new excel file every time based on the uploaded data like this:
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
write.xlsx(exportdata(), file)
})
})
This works fine.
Now I would like to edit an excel file that I will include when I publish the app and allow the user to download this edited version like this:
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("6rep-charts.xlsx")
writeData(wb, sheet = "Species Match Results", correlInput())
writeData(wb, sheet = "BS1 Data", bs1Input())
writeData(wb, sheet = "BS2 Data", bs2Input())
saveWorkbook(wb, file)
})
However, this results in the error Warning: Error in write_file: Expecting a single string value: [type=character; extent=0]. [No stack trace available]
. I am not sure what is going wrong as when I run the content section outside of the shiny app, it works just fine. The problem seems to be in the saveWorkbook
command.
The reason I would like to edit an existing excel file rather than create a new one is that the template file I'm including in the app has charts already made that should change when the new data is written into the file. The users would like to be able to edit these charts themselves, rather than just see a picture of a graph. If anyone has a simpler way to accomplish this, that would be great! Thank you in advance for your help!
Reproducible example using this excel file:
library(shiny); library(readxl); library(xlsx)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
fluidRow(
column(3,
downloadButton(outputId = "export",
label = "Export Results to Excel")
),
column(6,
dataTableOutput("data")
))))
server <- function(input, output) {
adata <- faithful[1:20,]
bdata <- faithful[21:50,]
cdata <- faithful[51:200,]
read_excel_allsheets <- function(filename, tibble = FALSE) {
sheets <- readxl::excel_sheets(filename)
x <- lapply(sheets, function(Y) {readxl::read_excel(filename, sheet = Y)})
if(!tibble) x <- lapply(x, as.data.frame)
names(x) <- sheets
x
}
output$data <- renderDataTable({
adata })
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("./Data/template.xlsx")
writeData(wb, sheet = "Alpha", adata)
writeData(wb, sheet = "Beta", bdata)
writeData(wb, sheet = "Gamma", cdata)
saveWorkbook(wb, file="./Data/temp.xlsx", overwrite = T)
print("done")
Fin_WB<- read_excel_allsheets("./Data/temp.xlsx")
write.xlsx(Fin_WB, file)
} ) }
shinyApp(ui = ui, server = server)