You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R Shiny的同一个下载按钮中支持CSV与PDF文件下载?

解决同一按钮下载CSV或PDF的问题

要实现同一个下载按钮根据用户选择动态输出CSV或PDF文件,只需修改downloadHandler的逻辑,根据选择的数据集类型调整文件名和输出内容,以下是修改后的完整代码:

library(tidyverse)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)


full_data <- tibble(
  State = c("IL", "IL", "IL", "IL", "IL", "IL", "IN", "IN", "IN", "IN", "IN", "IN"),
  City = c("Chicago", "Rockford", "Naperville", "Chicago", "Rockford", "Naperville","Fort Wayne", 
           "Indianapolis", "Bloomington", "Fort Wayne", "Indianapolis", "Bloomington"),
  Year = c("2008", "2008", "2008", "2009", "2009", "2009", "2008", "2008", "2008", "2009", "2009", "2009"),
  GDP = c(200, 300, 350, 400, 450, 250, 600, 400, 300, 800, 520, 375)
)


ui <- fluidPage(
  useShinyjs(),
  selectInput(
    inputId = "year",
    label = "Year",
    multiple = TRUE,
    choices = unique(full_data$Year),
    selected = unique(full_data$Year)
  ),
  selectInput(
    inputId = "state",
    label = "State",
    choices = unique(full_data$State)
  ),
  selectInput(
    inputId = "dataset",
    label = "Select Data to Download",
    choices = c("Full Data",
                "Illinois Trends")
  ),
  downloadButton(outputId = "downloadData",
                 label = "Download"),
  plotlyOutput("gdp_level", height = 400),
  shinyjs::hidden(actionButton("clear", "Return to State"))
)

server <- function(input, output, session) {
  

  datasetInput <- reactive({
    switch(input$dataset,
           "Full Data" = full_data,
           "Illinois Trends" = "Data/illinois_graph.pdf")
  })
  

  output$downloadData <- downloadHandler(
    filename = function() {
      # 根据选择的数据集类型设置文件名后缀
      if(input$dataset == "Full Data"){
        paste(input$dataset, ".csv", sep = "")
      } else {
        paste(input$dataset, ".pdf", sep = "")
      }
    },
    content = function(file) {
      # 根据选择执行不同的下载逻辑
      if(input$dataset == "Full Data"){
        write.csv(datasetInput(), file, row.names = FALSE)
      } else {
        # 复制指定路径的PDF文件到下载输出路径
        file.copy(datasetInput(), file)
      }
    }
  )
  

  drills <- reactiveValues(category = NULL,
                           sub_category = NULL)
  

  gdp_reactive <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(State %in% input$state)
  })
  

  gdp_reactive_2 <- reactive({
    full_data %>%
      filter(Year %in% input$year) %>%
      filter(State %in% input$state) %>%
      filter(City %in% drills$category)
  })
  

  gdp_data <- reactive({
    if (is.null(drills$category)) {
      return(gdp_reactive())
    }
    else {
      return(gdp_reactive_2())
    }
  })
  

  output$gdp_level <- renderPlotly({
    if (is.null(drills$category)) {
      plot_title <- paste0("GDP Level of ",  input$state)
    } else {
      plot_title <- paste0("GDP Level of ",  drills$category)
    }
    

    gdp_data() %>%
      plot_ly(
        x = ~ Year,
        y = ~ GDP,
        color = ~ City,
        key = ~ City,
        source = "gdp_level",
        type = "bar"
      ) %>%
      layout(
        barmode = "stack",
        showlegend = T,
        xaxis = list(title = "Year"),
        yaxis = list(title = "GDP"),
        title = plot_title
      )
  })
  

  observeEvent(event_data("plotly_click", source = "gdp_level"), {
    x <- event_data("plotly_click", source = "gdp_level")$key
    if (is.null(x))
      return(NULL)
    if (is.null(drills$category)) {
      drills$category <- unlist(x)
    }  else {
      drills$sub_category <- NULL
    }
  })
  

  observe({
    if (!is.null(drills$category)) {
      shinyjs::show("clear")
    }
  })
  

  observeEvent(c(input$clear, input$state), {
    drills$category <- NULL
    shinyjs::hide("clear")
  })
}


shinyApp(ui, server)

关键修改说明

  1. 文件名动态生成:在filename函数中通过if-else判断用户选择的数据集,分别返回.csv或.pdf后缀的文件名。
  2. 下载内容分支处理:在content函数中,针对不同的选择执行不同操作:
    • 选择Full Data时,依然使用write.csv输出CSV文件;
    • 选择Illinois Trends时,使用file.copy将指定路径的PDF文件复制到下载输出路径,实现PDF下载。
  3. 路径注意事项:确保"Data/illinois_graph.pdf"路径正确,若PDF文件在项目根目录下,可直接写文件名,或使用绝对路径避免路径错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:15:50