通过点击按钮将整个 shinydashboard 页面截图为 pdf

screenshot the whole shinydashboard page as pdf by hitting a button

有没有办法通过点击 actionButton()downloadButton() 将整个 shinydashboard 页面打印为 pdf 格式。根据用户所在的标签打印并下载相应的页面。

# app.R ##
library(shiny)
library(shinydashboard)
library(DT)

dbHeader <- dashboardHeader(
  title = "fr"
)

ui <- dashboardPage(
  dbHeader,
  dashboardSidebar(),
  dashboardBody(

    tags$hr(),
    actionButton("generate", "Generate PDF"),
    
    tabsetPanel(
      id ="tabA",
      type = "tabs",
      tabPanel("Front",icon = icon("accusoft"),
               plotOutput("ir")
               ),
      tabPanel("Data", icon = icon("table"),
               dataTableOutput("iris")
      )
    )
  )
)

server <- function(input, output) {
  output$ir<-renderPlot(
    plot(iris)
  )
  output$iris<-renderDataTable(
    iris
  )
}

shinyApp(ui = ui, server = server)

多田

如果我们可以在浏览器中完成所有事情,为什么我们需要 Shiny 服务器?纯 javascript,添加了 0 行服务器代码。

# app.R ##
library(shiny)
library(shinydashboard)
library(DT)

dbHeader <- dashboardHeader(
    title = "fr"
)

ui <- dashboardPage(
    dbHeader,
    dashboardSidebar(),
    dashboardBody(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"),
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"),
        tags$script(HTML(
            '
            window.jsPDF = window.jspdf.jsPDF;
            function capture(){
                domtoimage.toPng(document.querySelector("body"))
                .then(function(dataurl) {
                    var orientation = window.innerHeight >= window.innerWidth ? "portrait" : "landscape";
                    const doc = new jspdf.jsPDF({unit: "px", orientation: orientation, format: [window.innerHeight, window.innerWidth]});
                    doc.addImage(dataurl, "PNG", 0, 0, window.innerWidth, window.innerHeight);
                    doc.save("page.pdf");
                });
            }
            '
        )),
        tags$hr(),
        actionButton("generate", "Generate PDF", onclick="capture()"),
        tabsetPanel(
            id ="tabA",
            type = "tabs",
            tabPanel("Front",icon = icon("accusoft"),
                     plotOutput("ir")
            ),
            tabPanel("Data", icon = icon("table"),
                     dataTableOutput("iris")
            )
        )
    )
)

server <- function(input, output) {
    output$ir<-renderPlot(
        plot(iris)
    )
    output$iris<-renderDataTable(
        iris
    )
}

shinyApp(ui = ui, server = server)