Reputation: 437
All I am trying to do is read, render and download excel. Not sure how we can display specific UI details such as uploading excel button in dashboard sidebar and rendering and download button in dashboard body
Only error when I tried to get rid this error in mod_exampleUI module function. Error in mod_example("example_mod") : argument "output" is missing, with no default
Please find the code below
library(shiny)
library(magrittr) # Load magrittr for the piping operator %>%
library(DT)
library(readxl)
library(tidyselect)
library(writexl)
library(dplyr)
library(tidyr)
library(readxl)
library(stringr)
# Increase band width for shiny to handle bigger file
options(shiny.maxRequestSize=300*1024^2)
# Module UI to display sidebar content
mod_exampleUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
fileInput(ns("file1"), "Choose XLSX File (Convert xls to xlsx)",accept=c(".xlsx")),
tags$hr(),
downloadButton(ns("downloadData"), "Download")
)
}
# Module UI to display Body content
mod_example_displayUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
DT::dataTableOutput(ns("contents"))
)
}
# Function to read all excel sheet necessary
mod_example_display <- function(input, output, session) {
output$contents <- DT::renderDataTable({
DT::datatable(readxl::read_excel(input$file1$datapath)
,options = list(pageLength = 7,scrollX = TRUE))
})
output$downloadData <- downloadHandler(
filename = function() {
paste("updated file dated-", Sys.Date(), ".xlsx")
},
content = function(file) {
write_xlsx(DT::datatable(readxl::read_excel(input$file1$datapath),file))
}
)
}
ui <- fluidPage(
shinydashboard::dashboardPage(
skin = "yellow",
# HEADER -----
shinydashboard::dashboardHeader(
title = "Modularizing App"
),
# SIDEBAR -----
shinydashboard::dashboardSidebar(
shinydashboard::sidebarMenu(
shinydashboard::menuItem('Example', tabName = 'example', icon = shiny::icon('file')),
shinydashboard::tabItems(
shinydashboard::tabItem("example", mod_exampleUI("example_sidemod"))
)
)
),
# BODY -----
shinydashboard::dashboardBody(
shiny::tags$head(shiny::tags$link(rel = "stylesheet", type = "text/css", href = "custom.css")),
shinydashboard::tabItems(
shinydashboard::tabItem("example", mod_example_displayUI("example_bodymod"))
)
)
)
)
server <- function(input, output) {
shiny::callModule(mod_example_display, "mod_example")
}
shinyApp(ui,server)
Upvotes: 1
Views: 1360
Reputation: 437
Pleased to share answer so that it might helkp other shiny developers. Although it is no elegant but mich appreciated if UI could be improved by experts.
library(shiny)
library(magrittr) # Load magrittr for the piping operator %>%
library(DT)
library(readxl)
library(tidyselect)
library(writexl)
library(dplyr)
library(tidyr)
library(readxl)
library(stringr)
# Increase band width for shiny to handle bigger file
options(shiny.maxRequestSize=30*1024^2)
# Function to read all excel sheet necessary
read_excel_allsheets <- function(filename, tibble = FALSE) {
sheets <- readxl::excel_sheets(filename)
x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X, col_names = T, skip = 5
,col_types = "text"
))
if(!tibble) x <- lapply(x, as.data.frame)
names(x) <- sheets
x
}
# Module UI to read content
mod_readUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
fileInput(ns("file1"), h6("Choose xlsx file")
,accept=c(".xlsx"))
)
}
# Module UI to display content
mod_displayUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
DT::dataTableOutput(ns("contents"))
)
}
# Module UI to download content
mod_downloadUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
downloadButton(ns("downloadData"), "Download")
)
}
# Server functions
mod_display <- function(input, output, session, file) {
# In case want to alter the data to download
# myfile = reactive({as.data.frame(file()[,1])})
output$contents <- DT::renderDataTable({
DT::datatable(file()
,options = list(pageLength = 7,scrollX = TRUE))
})
reactive({
file()
# myfile()
})
}
mod_read <- function(input, output, session){
getData <- reactive({
req(input$file1)
inFile <- input$file1
mysheets <- read_excel_allsheets(inFile$datapath)
ppm <- mysheets$Download
ppm
})
### In ordert to send data as reactive
reactive({
getData()
})
}
mod_download <- function(input, output, session, displayData){
output$downloadData <- downloadHandler(
# browser(),
filename = function() {
paste("Updated file dated-", Sys.Date(), ".xlsx")
},
content = function(file) {
write_xlsx(displayData(),file)
}
)
}
ui <- fluidPage(
shinydashboard::dashboardPage(
skin = "yellow",
# HEADER -----
shinydashboard::dashboardHeader(
title = "Modularizing App"
),
# SIDEBAR -----
shinydashboard::dashboardSidebar(
shinydashboard::sidebarMenu(id = "menu",
shinydashboard::menuItem('Example', tabName = 'example', icon = shiny::icon('file')),
conditionalPanel("input.menu == 'example'",
shinydashboard::menuSubItem(mod_readUI("sidemod")),
shinydashboard::menuSubItem(mod_downloadUI("downmod"))
)
)
),
# BODY -----
shinydashboard::dashboardBody(
shinydashboard::tabItems(
shinydashboard::tabItem("example", mod_displayUI("bodymod"))
)
)
)
)
server <- function(input, output) {
readFile <- shiny::callModule(mod_read, "sidemod")
displayFile <- shiny::callModule(mod_display, "bodymod", file = readFile)
shiny::callModule(mod_download, "downmod", displayFile)
}
shinyApp(ui,server)
Upvotes: 1