You need to enable JavaScript to run this app. Shiny应用上传xlsx后read_xlsx无法访问临时路径报错求解
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用上传xlsx后read_xlsx无法访问临时路径报错求解

问题诊断与修复方案

核心错误原因

  • 错误使用list.files读取文件路径:input$upload$datapath返回的是上传文件的直接完整路径,不是目录,调用list.files读取文件路径自然返回空字符向量character(0)
  • read_xlsx的col_names参数逻辑错误:代码中letters[1:cell_range]的写法不成立,cell_range是如B15:Z16的字符串,无法作为数值索引使用,直接生成NA导致NA/NaN报错
  • Shiny变量作用域错误:在observeEvent中定义的data为局部变量,downloadHandler无法访问该变量,下载功能会直接失效
  • 依赖包缺失:代码中使用的str_replace_na、str_c属于stringr包,write_xlsx属于writexl包,未显式加载会触发函数不存在报错
  • 多文件上传逻辑缺失:当前calc函数仅支持单个文件处理,未适配多文件上传的遍历需求
  • 语法疏漏:print(files2末尾缺少闭合括号,会触发语法报错

修复后完整代码

library(shiny)
library(readxl)
library(dplyr)
library(stringr)
library(writexl)

calc <- function(tmp_file, num_of_cols) {
  print(tmp_file)
  print(num_of_cols)
  
  cell_range <- paste0("B15:", toupper(letters[num_of_cols+1]), "16")
  print(cell_range)
  
  cols <- read_xlsx(tmp_file, range = cell_range, col_names = letters[1:num_of_cols]) %>%
    mutate_all(str_replace_na, replacement = "") %>%
    transmute_all(str_c, collapse = "") %>%
    slice(-1) %>%
    as.character()
  
  return(cols)
}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("upload", "上传文件", multiple = TRUE),
      numericInput(inputId = "num_of_cols",
                   label = "指定读取列数",
                   value = 0),
      actionButton(inputId = "gobutton", "开始处理"),
      downloadButton("downloadbutton", "下载结果")
    ),
    mainPanel(
      tableOutput("upload_overview")
    )
  )
)

server <- function(input, output) {
  # 响应式变量存储处理后的数据
  processed_data <- reactiveVal(NULL)
  
  output$upload_overview <- renderTable(input$upload$datapath)
  
  observeEvent(input$gobutton, {
    # 非空校验,避免无输入时触发报错
    req(input$upload, input$num_of_cols > 0)
    # 遍历处理所有上传的文件
    res_list <- lapply(input$upload$datapath, function(f) {
      calc(f, input$num_of_cols)
    })
    # 合并所有文件的处理结果
    res_df <- bind_rows(res_list)
    processed_data(res_df)
  })
  
  output$downloadbutton <- downloadHandler(
    filename = "汇总结果.xlsx",
    content = function(file) {
      req(processed_data())
      write_xlsx(processed_data(), path = file)
    }
  )
}

shinyApp(ui = ui, server = server)

关键修改说明

  • 移除错误的list.files调用,直接使用上传生成的临时文件路径读取xlsx
  • 修正col_names参数为letters[1:num_of_cols],匹配实际读取的列数
  • 新增reactiveVal存储处理后的汇总数据,解决跨模块变量访问的作用域问题
  • 新增多文件遍历逻辑,循环处理所有上传的xlsx文件后合并结果
  • 补全缺失的依赖包加载
  • 增加非空校验逻辑,避免未上传文件、未指定列数就点击按钮触发的报错
  • 修复语法疏漏,补全缺失的括号

内容的提问来源于stack exchange,提问作者CoCoL0r3s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 05:06:04