如何在Shiny应用中通过fileInput函数实现CSV上传文件有效性校验
CSV上传校验功能实现方案
- 校验逻辑内嵌到
try()块中,符合你要求的通用异常捕获规则 - 新增两个校验条件:上传的CSV至少包含2列、前两列的表头(即对应Excel的A1、B1单元格)严格等于
Scenario 1 - 修正原代码中反馈提示绑定的组件ID错误,确保无效提示正常展示在文件上传控件旁
核心代码修改点
1. 读取上传文件逻辑新增校验
修改uploadMat3Data响应式变量的实现:
uploadMat3Data <- reactive({ req(input$uploadMat3) validate(need(identical(tools::file_ext(input$uploadMat3$datapath),"csv"),"Invalid")) try({ df <- read.csv(input$uploadMat3$datapath, header = TRUE) # 校验A1、B1单元格内容均为Scenario 1 if(ncol(df) < 2 || !identical(colnames(df)[1:2], c("Scenario 1", "Scenario 1"))) { stop("Invalid header") } df }) })
2. 修正反馈提示绑定ID
修改文件读取后的反馈逻辑,将原错误的file组件ID改为实际文件上传控件的IDuploadMat3:
observeEvent(uploadMat3Data(), { if(is.data.frame(uploadMat3Data())){ updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data())) hideFeedback("uploadMat3") } else {showFeedbackWarning("uploadMat3", "Invalid")} })
完整可运行代码
library(dplyr) library(shiny) library(shinyFeedback) library(shinyMatrix) sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))} ui <- fluidPage( useShinyFeedback(), sidebarLayout( sidebarPanel( actionButton("matrix3show","Click for matrix input"), ), mainPanel(plotOutput("plot")) ) ) server <- function(input, output, session) { uploadMat3Data <- reactive({ req(input$uploadMat3) validate(need(identical(tools::file_ext(input$uploadMat3$datapath),"csv"),"Invalid")) try({ df <- read.csv(input$uploadMat3$datapath, header = TRUE) # 校验A1、B1单元格内容均为Scenario 1 if(ncol(df) < 2 || !identical(colnames(df)[1:2], c("Scenario 1", "Scenario 1"))) { stop("Invalid header") } df }) }) observeEvent(uploadMat3Data(), { if(is.data.frame(uploadMat3Data())){ updateMatrixInput(session,"matrix3",as.matrix(uploadMat3Data())) hideFeedback("uploadMat3") } else {showFeedbackWarning("uploadMat3", "Invalid")} }) observeEvent(input$matrix3show,{ showModal( modalDialog( fileInput(inputId = "uploadMat3",label = NULL,accept = ".csv"), matrixInput( inputId = "matrix3", value = if(is.null(input$matrix3)){matrix(c(1,5),ncol=2,dimnames=list(NULL,rep("Scenario 1",2)))} else {input$matrix3}, rows = list(extend = TRUE, delete = TRUE), cols = list(extend = TRUE, delta = 2, delete = TRUE, multiheader = TRUE), class = "numeric"), output$verbMat3 <- renderPrint(class(uploadMat3Data())), footer = tagList( downloadButton("saveMat3","Save",style = "width:80px;"), modalButton("Exit box") ) # close tag list )) }) observeEvent(input$matrix3, { tmpMat3 <- input$matrix3 colnames(tmpMat3) <- paste("Scenario",rep(1:ncol(tmpMat3),each=2,length.out=ncol(tmpMat3))) rownames(tmpMat3) <- paste("Row", seq_len(nrow(input$matrix3))) updateMatrixInput(session,inputId="matrix3",value=tmpMat3) }) data <- function(){tibble(X = seq_len(10),Y = sumMat(input$matrix3))} output$plot<-renderPlot({plot(data(),type="l")}) output$saveMat3 <- downloadHandler( filename = function(){paste("Inputs","csv",sep=".")}, content = function(file){write.csv(input$matrix3, file,row.names=FALSE)} ) } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

