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

如何为Shiny应用添加截图(PNG/JPG)或PDF导出功能?

Shiny应用可视化区域导出方案

一、单个可视化区域导出(最优,对应绿色标记区域)

Shiny原生支持针对plotOutput生成的图表直接添加下载功能,只需在UI中加入下载按钮,配合server端的downloadHandler即可实现。以下是修改后的完整代码:

修改后代码

library(shiny)
library(shinydashboard)
library(data.table)
library(DT)
library(bslib)

server = shinyServer(function(input,output){
  
  output$histogram = renderPlot(
    hist(faithful$eruptions, breaks=input$days_plot)
  )
  
  output$histogram2 = renderPlot(
    hist(faithful$eruptions, breaks=input$days_plot)
  )
  
  output$active_cases = DT::renderDataTable(
    mtcars, selection = 'single', options=list(scrollX=TRUE))
  
  # 第一个图表的下载处理器
  output$download_hist1 <- downloadHandler(
    filename = function() {
      paste0("histogram_", Sys.Date(), ".png")
    },
    content = function(file) {
      png(file, width = 800, height = 600)
      hist(faithful$eruptions, breaks=input$days_plot)
      dev.off()
    }
  )
  
  # 第二个图表的下载处理器
  output$download_hist2 <- downloadHandler(
    filename = function() {
      paste0("histogram2_", Sys.Date(), ".png")
    },
    content = function(file) {
      png(file, width = 800, height = 600)
      hist(faithful$eruptions, breaks=input$days_plot)
      dev.off()
    }
  )
})

ui = shinyUI(
  dashboardPage(
    dashboardHeader(
      title="just a test"
    ),
    dashboardSidebar(
      sidebarMenu(id="tabs",
                  menuItem("Tab1", tabName="active_cases", icon = icon("magnifying-glass-location")),
                  menuItem("Tab2", tabName="archive", icon = icon("box-archive")),
                  menuItem("Configuration", sliderInput("days_plot", "Days into past", 1, 60, 30))
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(tabName="active_cases", shiny::h2("Active Cases"),
                fluidRow(
                  box(title="Table", status="primary", solidHeader=TRUE, div(DT::dataTableOutput("active_cases")))
                ),
                fluidRow(
                  box(title="Visual1", status="primary", solidHeader=TRUE, 
                      plotOutput("histogram"),
                      # 添加下载按钮
                      downloadButton("download_hist1", "下载该图表")),
                  box(title="Visual2", status="primary", solidHeader=TRUE, 
                      plotOutput("histogram2"),
                      downloadButton("download_hist2", "下载该图表"))
                )
        ),
        tabItem(tabName="archive", shiny::h2("Archive"))
      )
    )
  )
)

shinyApp(ui, server)

关键说明:

  • 每个plotOutput对应一组downloadButton和downloadHandler,点击按钮即可导出当前图表为PNG格式;若需JPG,将代码中的png()替换为jpeg()即可。
  • 可通过调整png()的width和height参数控制导出图片的尺寸。

二、多区域/整页导出(对应黄色标记区域或整页)

如果需要导出多个可视化区域(比如两个图表所在的行)或整页,可使用webshot2包,它能通过CSS选择器定位页面元素并导出为图片或PDF。

步骤1:安装依赖

install.packages("webshot2")
webshot2::install_chromium() # 需安装Chromium环境支持

步骤2:修改代码实现多区域/整页导出

library(shiny)
library(shinydashboard)
library(data.table)
library(DT)
library(bslib)
library(webshot2)

server = shinyServer(function(input,output){
  
  output$histogram = renderPlot(
    hist(faithful$eruptions, breaks=input$days_plot)
  )
  
  output$histogram2 = renderPlot(
    hist(faithful$eruptions, breaks=input$days_plot)
  )
  
  output$active_cases = DT::renderDataTable(
    mtcars, selection = 'single', options=list(scrollX=TRUE))
  
  # 导出两个图表所在的行
  output$download_plots_row <- downloadHandler(
    filename = function() {
      paste0("plots_row_", Sys.Date(), ".png")
    },
    content = function(file) {
      # 通过ID定位目标行(比nth-child更可靠)
      webshot2::webshot(
        url = session$clientData$url_local,
        file = file,
        selector = "#plots_row",
        vwidth = 1200,
        vheight = 600
      )
    }
  )
  
  # 导出整页为PDF
  output$download_full_page <- downloadHandler(
    filename = function() {
      paste0("full_page_", Sys.Date(), ".pdf")
    },
    content = function(file) {
      webshot2::webshot(
        url = session$clientData$url_local,
        file = file,
        vwidth = 1200,
        vheight = 800,
        expand = c(10, 10, 10, 10)
      )
    }
  )
})

ui = shinyUI(
  dashboardPage(
    dashboardHeader(
      title="just a test"
    ),
    dashboardSidebar(
      sidebarMenu(id="tabs",
                  menuItem("Tab1", tabName="active_cases", icon = icon("magnifying-glass-location")),
                  menuItem("Tab2", tabName="archive", icon = icon("box-archive")),
                  menuItem("Configuration", sliderInput("days_plot", "Days into past", 1, 60, 30))
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(tabName="active_cases", shiny::h2("Active Cases"),
                fluidRow(
                  box(title="Table", status="primary", solidHeader=TRUE, div(DT::dataTableOutput("active_cases")))
                ),
                # 给目标行添加ID,方便精准定位
                fluidRow(id="plots_row",
                  box(title="Visual1", status="primary", solidHeader=TRUE, plotOutput("histogram")),
                  box(title="Visual2", status="primary", solidHeader=TRUE, plotOutput("histogram2"))
                ),
                # 添加多区域和整页下载按钮
                fluidRow(
                  box(width=6, downloadButton("download_plots_row", "下载两个图表区域")),
                  box(width=6, downloadButton("download_full_page", "下载整页为PDF"))
                )
        ),
        tabItem(tabName="archive", shiny::h2("Archive"))
      )
    )
  )
)

shinyApp(ui, server)

关键说明:

  • 给目标元素添加id(如id="plots_row"),可通过selector="#plots_row"精准定位导出区域。
  • 导出格式支持PNG、JPG、PDF,只需修改filename的后缀即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:55:21