Shiny上传.xlsx文件加载所有工作表为列表报错求助
问题修复:Shiny读取Excel多工作表报错“object of type 'closure' is not subsettable”
错误根源
input_file是Shiny的响应式对象,本质是一个闭包函数。你直接用input_file[[1]]尝试对函数做子集操作,这就触发了报错。必须通过input_file()调用才能拿到里面的列表数据。另外原代码无文件时返回空字符串,后续处理也容易出问题,应该返回NULL配合req()处理空值。
修复后的完整代码
library(shiny) library(readxl) library(flextable) library(tidyverse) ui <- shinyUI(fluidPage( titlePanel("Use readxl"), sidebarLayout( sidebarPanel( fileInput('file1', 'Choose xlsx file', accept = c(".xlsx") ) ), mainPanel( htmlOutput("ftable2") ) ) )) server <- function(input, output){ input_file <- reactive({ if (is.null(input$file1)) { return(NULL) # 替换空字符串为NULL,避免后续类型错误 } sapply(readxl::excel_sheets(input$file1$datapath), simplify = F, USE.NAMES = T, function(X) readxl::read_excel(input$file1$datapath, sheet = X)) }) output$ftable2 <- renderUI({ req(input_file()) # 确保有数据才执行后续代码 input_file()[[1]] %>% # 关键:调用input_file()获取列表,再取第一个元素 head(10) %>% flextable() %>% htmltools_value() }) } shinyApp(ui, server)
关键修改说明
- 响应式对象
input_file无文件时返回NULL,而非空字符串,保证数据类型统一为列表/NULL - 在
renderUI中,必须通过input_file()调用响应式对象获取实际数据,再用[[1]]取第一个工作表的数据框
内容的提问来源于stack exchange,提问作者Basil
相关产品推荐
相关产品推荐

