Search code examples
rshinyxlsx

"read_excel" in a Shiny app


I have a Shiny app that uses the read.xlsx function from package xlsx. All works fine, but I want to change to read_excel from readxl, hoping it would be faster and able to cope with large files.

ui part:

fileInput("inputFile","Upload file...")

server part:

  data <- reactive({
    inFile <- input$inputFile
    if (is.null(inFile)) { return(NULL) }    
    dataFile <- read_excel(inFile$datapath,sheet=1)
    return(dataFile)
  })

I get the "Unknown format" error.

inFile$datapath is "/tmp/.../60974676c7287e913d1c0dc5/0"
inFile$type is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

Question 1: is there a way to tell read_excel that it's a xlsx type file?
Question 2: is it possible to control the location where the uploaded file will be stored?


Solution

  • This was an open issue with the readxl package. The current workaround provided there is to copy the file data path and append .xlsx. Here is a working example on my machine limited to .xlsx files edited to use file.rename instead of file.copy.

    library(shiny)
    library(readxl)
    
    runApp(
        list(
            ui = fluidPage(
                titlePanel("Use readxl"),
                sidebarLayout(
                    sidebarPanel(
                        fileInput('file1', 'Choose xlsx file',
                                  accept = c(".xlsx")
                                  )
                        ),
                    mainPanel(
                        tableOutput('contents'))
                    )
                ),
            server = function(input, output){
                output$contents <- renderTable({
                    inFile <- input$file1
    
                    if(is.null(inFile))
                        return(NULL)
                    file.rename(inFile$datapath,
                              paste(inFile$datapath, ".xlsx", sep=""))
                    read_excel(paste(inFile$datapath, ".xlsx", sep=""), 1)
                })
            }
            )
        )
    

    EDIT Note that with the 1.1.0 version of readxl it no longer needs to have the file renamed. The following works without a problem for me now.

    library(shiny)
    library(readxl)
    
    runApp(
      list(
        ui = fluidPage(
          titlePanel("Use readxl"),
          sidebarLayout(
            sidebarPanel(
              fileInput('file1', 'Choose xlsx file',
                        accept = c(".xlsx")
              )
            ),
            mainPanel(
              tableOutput('contents'))
          )
        ),
        server = function(input, output){
          output$contents <- renderTable({
    
            req(input$file1)
    
            inFile <- input$file1
    
            read_excel(inFile$datapath, 1)
          })
        }
      )
    )